{"id":1265,"date":"2021-01-02T13:11:21","date_gmt":"2021-01-02T12:11:21","guid":{"rendered":"http:\/\/www.thelins.se\/johan\/blog\/?p=1265"},"modified":"2021-01-02T13:14:28","modified_gmt":"2021-01-02T12:14:28","slug":"some-vue-django-tips","status":"publish","type":"post","link":"https:\/\/www.thelins.se\/johan\/blog\/2021\/01\/some-vue-django-tips\/","title":{"rendered":"Some Vue + Django tips"},"content":{"rendered":"\n<p>As I wrote <a href=\"https:\/\/www.thelins.se\/johan\/blog\/2020\/12\/looking-at-vue\/\" data-type=\"post\" data-id=\"1259\">last time<\/a>, I currently develop a web app based on Django and Vue using the <a href=\"https:\/\/github.com\/eadwinCode\/django-compressor-parceljs\">django-compressor-parceljs<\/a>. I&#8217;d like to mention some small things that I&#8217;ve learned since last.<\/p>\n\n\n\n<p><strong>Vue in development mode<\/strong><\/p>\n\n\n\n<p>I found it interesting that <a href=\"https:\/\/parceljs.org\/\">parceljs<\/a> described how to get Vue into development mode for several bundlers, but failed to mention parcel. After some digging around, I figured out that parcel respects the NODE_ENV environment variable, so starting the django server with <code>NODE_ENV=development .\/manage.py runserver<\/code> does the trick. Now I get proper error messages from Vue.<\/p>\n\n\n\n<p><strong>Constantly rebundling<\/strong><\/p>\n\n\n\n<p>Another annoyance with the default configuration of the compressor, was that it compiles (bundles \/ compresses) the Vue files once every time the server is started. This really lengthened the change-build-test cycle time, so something needed to be done. It turns out that the solution is to set the <a href=\"https:\/\/django-compressor.readthedocs.io\/en\/latest\/settings\/#django.conf.settings.COMPRESS_REBUILD_TIMEOUT\">COMPRESS_REBUILD_TIME<\/a> to a really low value in the django settings, and the contents is compressed every time. I set it to one second on my development machine.<\/p>\n\n\n\n<p>Disabling compression would break the Vue files, as the browser cannot run the Vue files natively, i.e. they need a compression to be possible to run.<\/p>\n\n\n\n<p>The consequence of this configuration is that loading a view based on Vue takes a bit longer, but it takes way shorter time than restarting the django server, recreating the backend state and so on.<\/p>\n\n\n\n<p><strong>Exposing Django context to Javascript<\/strong><\/p>\n\n\n\n<p>Django exposes a set of context variables when loading a view. This avoids an unnecessary round-trip over the server to asynchronously request the info that I already know the view will need. I&#8217;ve developed a small convention for this.<\/p>\n\n\n\n<p>In the Django template, I add something along these lines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script&gt;\nvar context_title = '{{ title }}';\nvar context_actors = &#91;\n{% for actor in actors %}'{{ actor }}',\n{% endfor %} ];\n...\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>This copies the django context into Javascript space with the variable name prefix of <code>context_<\/code>. I then consume these in the Vue app&#8217;s <code>mounted<\/code> method, e.g.:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    ...\n    mounted() {\n        this.title = context_title;\n        this.actors = context_actors;\n        ...\n    },\n    ...<\/code><\/pre>\n\n\n\n<p>This copies the state into the state of the app, which means that it is now a part of what the Vue interface is reactive to.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As I wrote last time, I currently develop a web app based on Django and Vue using the django-compressor-parceljs. I&#8217;d like to mention some small things that I&#8217;ve learned since last. Vue in development mode I found it interesting that parceljs described how to get Vue into development mode for several bundlers, but failed to &hellip; <a href=\"https:\/\/www.thelins.se\/johan\/blog\/2021\/01\/some-vue-django-tips\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Some Vue + Django tips<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,17],"tags":[],"class_list":["post-1265","post","type-post","status-publish","format-standard","hentry","category-django","category-vue"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/posts\/1265","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/comments?post=1265"}],"version-history":[{"count":2,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/posts\/1265\/revisions"}],"predecessor-version":[{"id":1267,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/posts\/1265\/revisions\/1267"}],"wp:attachment":[{"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/media?parent=1265"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/categories?post=1265"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/tags?post=1265"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}