<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Quasar on Techformist</title>
    <link>https://techformist.com/tags/quasar/</link>
    <description>Recent content in Quasar on Techformist</description>
    <image>
      <url>https://techformist.com/logo.svg</url>
      <link>https://techformist.com/logo.svg</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 17 Jun 2020 06:30:00 +0000</lastBuildDate><atom:link href="https://techformist.com/tags/quasar/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Using Caddy with Quasar</title>
      <link>https://techformist.com/quasar-vue-caddy/</link>
      <pubDate>Wed, 17 Jun 2020 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/quasar-vue-caddy/</guid>
      <description>&lt;p&gt;I switched to Caddy recently on one of our servers to host multiple applications and am super happy about its simplicity and ease of use. Here&amp;rsquo;s how I use Caddy with Quasar.&lt;/p&gt;
&lt;h2 id=&#34;what-is-caddy&#34;&gt;What is Caddy?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://caddyserver.com/v2&#34;&gt;Caddy&lt;/a&gt; is a web server much like Nginx. It calls itself &amp;ldquo;a new kind of extensible platform for server apps&amp;rdquo;. Features include -&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Easy configuration (super readable config. files - we will get to this in a bit)&lt;/li&gt;
&lt;li&gt;Configuration is exposed as APIs (JSON files can be used to create/change configuration)&lt;/li&gt;
&lt;li&gt;An extensible plugin system&lt;/li&gt;
&lt;li&gt;Automatic https using Let&amp;rsquo;s Encrypt&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Caddy does all this with a single executable, and a single configuration file.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I switched to Caddy recently on one of our servers to host multiple applications and am super happy about its simplicity and ease of use. Here&rsquo;s how I use Caddy with Quasar.</p>
<h2 id="what-is-caddy">What is Caddy?</h2>
<p><a href="https://caddyserver.com/v2">Caddy</a> is a web server much like Nginx. It calls itself &ldquo;a new kind of extensible platform for server apps&rdquo;. Features include -</p>
<ol>
<li>Easy configuration (super readable config. files - we will get to this in a bit)</li>
<li>Configuration is exposed as APIs (JSON files can be used to create/change configuration)</li>
<li>An extensible plugin system</li>
<li>Automatic https using Let&rsquo;s Encrypt</li>
</ol>
<p>Caddy does all this with a single executable, and a single configuration file.</p>
<p><img loading="lazy" src="/2020/caddy.jpg" type="" alt="caddy"  /></p>
<p>Caddy version 2 caused some ground-breaking changes from v1. Since I did not quite use v1, can&rsquo;t really compare how they fare. Caddy is free to use and is licensed under Apache 2.0 open source license.</p>
<h2 id="why-use-caddy">Why use Caddy?</h2>
<p>The most important factor for me - Caddy enables quick setup of a server with multiple apps without spending hours on configuration.</p>
<p>As a non sysadmin developer, I approach server configuration with some skepticism. I cannot quite get away from it due to cheaper costs, but I would rather spend time creating something else rather than fiddling with server configuration.</p>
<p>Nginx has been a great companion. The configuration files are just ok and I don&rsquo;t mind them as long as they are setup only once. However, introducing multiple apps, APIs and static file hosting on same server confuses me and requires quite a bit of trial &amp; error configuration.</p>
<p>Over years I have tried solving the problem with a few options -</p>
<ul>
<li>Use cookie cutter config files with Nginx</li>
<li>Nginx configuration file generator</li>
<li>Alternate server options (there are many options but one needs to be careful about a solution that is too niche or has a thin community behind it)</li>
<li>Self-hosting solutions like Parse that let&rsquo;s me get away with backend configuration changes</li>
</ul>
<p>It is with that background that I find Caddy a refreshing change. With minimal configuration, easier changes and acceptable performance, Caddy works great for this use case.</p>
<h2 id="my-typical-use-case">My Typical Use Case</h2>
<p>My preferred architecture when using &ldquo;quick&rdquo; Vue apps -</p>
<ol>
<li>A node server that serves APIs and database on a 2-4 GB server</li>
<li>Front-end hosted on same server. VueJS is my framework of choice</li>
<li>Static content on Github, Netlify or similar</li>
</ol>
<p>Each server typically hosts 1-4 production apps or <code>x</code> test/MVP apps.</p>
<p>The Caddy server should -</p>
<ol>
<li>handle API requests and proxy them to Node server. The requests may be from the frontend application or from external systems</li>
<li>handle frontend requests when routing to different pages</li>
</ol>
<h2 id="caddy-configuration">Caddy Configuration</h2>
<p>While I found Caddy documentation to be great in general, the examples seem to be for a more &ldquo;in the know&rdquo; audience. The radical changes from v1 to v2 have made some of the previous content irrelevant.</p>
<p>I typically use <code>Caddyfile</code> to store Caddy configuration, which does not appear to be future-proof but is fully supported and quite easy to use. The structure looks somewhat like this -</p>
<pre tabindex="0"><code>example.com {
    root * /usr/www/example
    file_server
}
</code></pre><p>You can store this file wherever you please, but I use <code>/etc/caddy/Caddyfile</code>.</p>
<p>I can now start Caddy with -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo caddy start -config /etc/caddy/Caddyfile
</span></span></code></pre></div><p>I will switch to configuration using JSON at some point in time with a typical structure looking like this -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;apps&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tls&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;certificates&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;automate&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;example.com&#34;</span><span class="p">,</span> <span class="s2">&#34;another-example.net&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The JSON format is not quite difficult to understand, but more &ldquo;typing&rdquo;. I don&rsquo;t send API requests to configure web servers (thank heavens), and the specific port remains closed in the firewall.</p>
<h2 id="caddy-and-quasar">Caddy and Quasar</h2>
<p>While I knew Caddy&rsquo;s configuration was quite simple, I could not get it to play nicely with client-side routing of Vue apps at the beginning.</p>
<p>After some hit &amp; miss, and lot of searching on Google, I have this configuration that simply works.</p>
<pre tabindex="0"><code># Caddyfile
example.com {
    root * /usr/www/example

    route {
        reverse_proxy /api/* localhost:3000
        try_files {path} {path}/ /index.html
        file_server
    }
}

another-example.net {
    root * /usr/www/anotherexample
    file_server
}
</code></pre><p>This file accomplishes the following -</p>
<ol>
<li>Host site <code>example.com</code>
<ul>
<li>redirect all requests with <code>/api/*</code> to <code>localhost:3000</code>. The node server listens on port 3000, and that port is not open to the Internet</li>
<li>redirect any request to <code>/</code> and allow Vue to handle routing. I do this using <code>try_files {path} {path}/ /index.html</code>, which tries locating for a file with the name passed from URL and redirects to it. If no file is found, it directs to <code>index.html</code></li>
<li>the <code>route</code> statement ensures that Caddy follows the given order while handling URLs. APIs with <code>/api/</code> are served by Node server and other URLs are served by client-side routing</li>
</ul>
</li>
<li>Host site <code>another-example.net</code>
<ul>
<li>serve files in <code>/usr/www/anotherexample</code></li>
</ul>
</li>
</ol>
<p>All I now need to is point the domain name to the IP address of this server and both <code>example.com</code> and <code>another-example.net</code> just work!</p>
<h2 id="when-not-to-use-caddy">When not to use Caddy?</h2>
<p>Caddy works great for all my use cases. I don&rsquo;t quite build Twitter or Facebook level apps - so I should be ok I guess.</p>
<p>At the same time, I will not quite migrate everything to Caddy at this time. If you have configured Nginx a couple of times, you know that all it takes is some &ldquo;lazy copy/paste&rdquo; to get the whole thing working. Simpler needs = simple tasks = no need to take drastic action to change status quo.</p>
<p>You may also not want to use Caddy if you -</p>
<ul>
<li>manage quite an intensive server that handles high traffic volumes. Nginx can manage twice the processing</li>
<li>want to consume as less memory as possible. Caddy is light-weight but not as much as Nginx, and can consume more than double the memory</li>
</ul>
<p>See -</p>
<ul>
<li><a href="https://community.centminmod.com/threads/caddy-v2-versus-centmin-mod-nginx-http-2-http-3-https-benchmarks.19700/">benchmarks for Caddy2 vs Nginx on Centminmod forums</a>.</li>
</ul>
<h2 id="finis">Finis</h2>
<p>I personally believe in a great future for Caddy. It has a great community, good documentation and is a delight to use.</p>
<p>Start using Caddy for your dev/test environments and see the difference. Migrating production environments may be a long drawn out decision based on your intended use.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Using Vue Plugins in Quasar</title>
      <link>https://techformist.com/using-vue-plugins-quasar/</link>
      <pubDate>Fri, 22 May 2020 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/using-vue-plugins-quasar/</guid>
      <description>&lt;p&gt;Here&amp;rsquo;s a quick way to use Vue plugins in Quasar.&lt;/p&gt;
&lt;h2 id=&#34;use-case-frappe-charts-in-vue&#34;&gt;Use Case: Frappe Charts in Vue&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s consider a simple use case for using Vue plugins - we want to use Frappe charts.&lt;/p&gt;
&lt;p&gt;We can simply use &lt;a href=&#34;https://github.com/JustSteveKing/vue2-frappe&#34;&gt;vue2-frappe&lt;/a&gt; to easily do that. Just install the package in your project -&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm i --save vue2-frappe
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, register it as a Vue plugin -&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Vue&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;vue&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Chart&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;vue2-frappe&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;Vue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;use&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;frappe-in-quasar&#34;&gt;Frappe in Quasar&lt;/h2&gt;
&lt;p&gt;In Quasar you can&amp;rsquo;t do a &lt;code&gt;Vue.use&lt;/code&gt; like the above. There is no &lt;code&gt;main.js&lt;/code&gt; to orchestrate that.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Here&rsquo;s a quick way to use Vue plugins in Quasar.</p>
<h2 id="use-case-frappe-charts-in-vue">Use Case: Frappe Charts in Vue</h2>
<p>Let&rsquo;s consider a simple use case for using Vue plugins - we want to use Frappe charts.</p>
<p>We can simply use <a href="https://github.com/JustSteveKing/vue2-frappe">vue2-frappe</a> to easily do that. Just install the package in your project -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npm i --save vue2-frappe
</span></span></code></pre></div><p>Next, register it as a Vue plugin -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Vue</span> <span class="nx">from</span> <span class="s2">&#34;vue&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Chart</span> <span class="nx">from</span> <span class="s2">&#34;vue2-frappe&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">Vue</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">Chart</span><span class="p">);</span>
</span></span></code></pre></div><h2 id="frappe-in-quasar">Frappe in Quasar</h2>
<p>In Quasar you can&rsquo;t do a <code>Vue.use</code> like the above. There is no <code>main.js</code> to orchestrate that.</p>
<p>The documentation of <code>vue2-frappe</code> does say that we can use <code>vue2-frappe</code> directly in components..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">VueFrappe</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;vue2-frappe&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">VueFrappe</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>.. but, I was never successful in getting that to work.</p>
<p>Time is always of essence - so I did the next best thing. I used a <a href="/create-boot-plugin-quasar">boot plugin</a> to register Vue plugins.</p>
<p>Create <code>./src/boot/vplugins.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Vue</span> <span class="nx">from</span> <span class="s2">&#34;vue&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Chart</span> <span class="nx">from</span> <span class="s2">&#34;vue2-frappe&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Similar to Vue.use()
</span></span></span><span class="line"><span class="cl"><span class="nx">Chart</span><span class="p">.</span><span class="nx">install</span><span class="p">(</span><span class="nx">Vue</span><span class="p">);</span>
</span></span></code></pre></div><p>Register this new plugin in <code>quasar.conf</code>..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="cm">/* ctx */</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// app boot file (/src/boot)
</span></span></span><span class="line"><span class="cl">    <span class="c1">// --&gt; boot files are part of &#34;main.js&#34;
</span></span></span><span class="line"><span class="cl">    <span class="c1">// https://quasar.dev/quasar-cli/cli-documentation/boot-files
</span></span></span><span class="line"><span class="cl">    <span class="nx">boot</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;vplugins&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>You can now happily use frappe charts from any component -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">vue-frappe</span>
</span></span><span class="line"><span class="cl">      <span class="na">v-if</span><span class="o">=</span><span class="s">&#34;trend[&#39;labels&#39;]&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">id</span><span class="o">=</span><span class="s">&#34;prodTrend&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">:labels</span><span class="o">=</span><span class="s">&#34;trend[&#39;labels&#39;]&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">:dataSets</span><span class="o">=</span><span class="s">&#34;trend[&#39;datasets&#39;]&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">type</span><span class="o">=</span><span class="s">&#34;bar&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">:height</span><span class="o">=</span><span class="s">&#34;300&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">:colors</span><span class="o">=</span><span class="s">&#34;[&#39;blue&#39;]&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&gt;&lt;/</span><span class="nt">vue-frappe</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">data</span><span class="p">()</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">    <span class="nx">props</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">trend</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// provide options for Frappe chart
</span></span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">&gt;
</span></span></code></pre></div><p>Have additional plugins to register? Instead of creating distinct files for more than one Vue plugin, we just combine everything in one file - just change <code>vplugins.js</code> and you are all set.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Vue</span> <span class="nx">from</span> <span class="s2">&#34;vue&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Chart</span> <span class="nx">from</span> <span class="s2">&#34;vue2-frappe&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">GobblyGook</span> <span class="nx">from</span> <span class="s2">&#34;gobbly&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">Chart</span><span class="p">.</span><span class="nx">install</span><span class="p">(</span><span class="nx">Vue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="nx">GobblyGook</span><span class="p">.</span><span class="nx">install</span><span class="p">(</span><span class="nx">Vue</span><span class="p">);</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>Create Boot Plugin in Quasar</title>
      <link>https://techformist.com/create-boot-plugin-quasar/</link>
      <pubDate>Wed, 20 May 2020 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/create-boot-plugin-quasar/</guid>
      <description>&lt;p&gt;Quasar CLI structures project differently as compared to a standard Vue CLI app. As a result, you cannot just follow examples on the Internets blindly and use &lt;code&gt;Vue.use()&lt;/code&gt;, or start changing code in &lt;code&gt;main.js&lt;/code&gt;. There are, however, great ways of addressing the same problems with slightly different solutions.&lt;/p&gt;
&lt;p&gt;Enter &lt;a href=&#34;https://quasar.dev/quasar-cli/cli-documentation/boot-files&#34;&gt;boot files&lt;/a&gt;. These were simply called app plugins which led to them being mixed up with Quasar&amp;rsquo;s own plugins. Now they are simply referred to as &amp;ldquo;boot files&amp;rdquo;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Quasar CLI structures project differently as compared to a standard Vue CLI app. As a result, you cannot just follow examples on the Internets blindly and use <code>Vue.use()</code>, or start changing code in <code>main.js</code>. There are, however, great ways of addressing the same problems with slightly different solutions.</p>
<p>Enter <a href="https://quasar.dev/quasar-cli/cli-documentation/boot-files">boot files</a>. These were simply called app plugins which led to them being mixed up with Quasar&rsquo;s own plugins. Now they are simply referred to as &ldquo;boot files&rdquo;.</p>
<h2 id="why-boot-files">Why Boot Files?</h2>
<p>Use cases for boot files include -</p>
<ol>
<li>Use common start-up code for your app</li>
<li>Enable functions that are accessible from anywhere</li>
<li>Initiliase your own dependencies</li>
</ol>
<p>A great example is provided out of the box in axios. If you select <code>axios</code> library to be enabled while creating project using Quasar CLI, you will find a boot file in <code>./src/boot/axios.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Vue</span> <span class="nx">from</span> <span class="s2">&#34;vue&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">axios</span> <span class="nx">from</span> <span class="s2">&#34;axios&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">Vue</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">$axios</span> <span class="o">=</span> <span class="nx">axios</span><span class="p">;</span>
</span></span></code></pre></div><p>Next, this plugin is registered in <code>quasar.conf.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="cm">/* ctx */</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">boot</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;axios&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>In any component, you can now do -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">data</span> <span class="p">}</span> <span class="o">=</span> <span class="kr">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">$axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>
</span></span></code></pre></div><p>.. without the need to import axios.</p>
<h2 id="create-a-simple-boot-plugin">Create a simple boot plugin</h2>
<p>The axios plugin works just fine as-is. But, you have no way to provide options in one common place. Take an example of providing just the bearer token -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">res</span> <span class="p">}</span> <span class="o">=</span> <span class="kr">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">$axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="sb">`store.state.baseURL/</span><span class="si">${</span><span class="nx">reqURL</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">reqData</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">Authorization</span><span class="o">:</span> <span class="nx">store</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">bearerToken</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span></code></pre></div><p>Clutter affects code readability and maintenance - more importantly, we lose &ldquo;cool&rdquo; factor.</p>
<p>Let&rsquo;s create our own version of Axios so that bearer token is included automatically for authentication.</p>
<p>If you are curious - we could always extend the current plugin, but I found it the hard way that it led to confusion for people on the beginner side of spectrum (&ldquo;axios automatically authenticates in that project, but there is something wrong here&rdquo;).</p>
<p>Create a new file <code>./src/boot/req.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">axios</span> <span class="nx">from</span> <span class="s2">&#34;axios&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">req</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">async</span> <span class="nx">post</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="kr">await</span> <span class="nx">axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="sb">`https://baseURL.com/</span><span class="si">${</span><span class="nx">url</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">Authorization</span><span class="o">:</span> <span class="s2">&#34;token&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">async</span> <span class="p">({</span> <span class="nx">Vue</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// something to do
</span></span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="nx">req</span><span class="p">)</span> <span class="nx">req</span><span class="p">.</span><span class="nx">Vue</span> <span class="o">=</span> <span class="nx">Vue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">Vue</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">$req</span> <span class="o">=</span> <span class="nx">req</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>We are doing simple things here -</p>
<ol>
<li>Create an object with a function</li>
<li>Create a function within the object that makes axios call with arguments passed to the function</li>
<li>Register object to be globally available through a Vue prototype</li>
</ol>
<p>Register the plugin in <code>quasar.conf.js</code>..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="cm">/* ctx */</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">boot</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;req&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>You can test this code from any component..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- Stuff goes here --&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kr">async</span> <span class="nx">updateRecord</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kd">let</span> <span class="nx">reqData</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">a</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">b</span><span class="o">:</span> <span class="mi">2</span> <span class="p">};</span>
</span></span><span class="line"><span class="cl">        <span class="kr">const</span> <span class="p">{</span> <span class="nx">data</span> <span class="p">}</span> <span class="o">=</span> <span class="kr">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">$req</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s2">&#34;get-sum&#34;</span><span class="p">,</span> <span class="nx">reqData</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;data&#34;</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><h2 id="accessing-the-store">Accessing the Store</h2>
<p>Wait, there&rsquo;s more.</p>
<p>There is no need to hard-code values when you can bring them from one central place - from the Vuex store.</p>
<p>Let&rsquo;s do that.</p>
<p>Modify <code>./src/boot/req.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">axios</span> <span class="nx">from</span> <span class="s2">&#34;axios&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">async</span> <span class="p">({</span> <span class="nx">Vue</span><span class="p">,</span> <span class="nx">store</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// something to do
</span></span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">req</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">async</span> <span class="nx">post</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kr">await</span> <span class="nx">axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">baseURL</span><span class="si">}</span><span class="sb">/</span><span class="si">${</span><span class="nx">url</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">Authorization</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">bearerToken</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">});</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// throw if you want to pass errors back
</span></span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">req</span><span class="p">.</span><span class="nx">Vue</span> <span class="o">=</span> <span class="nx">Vue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">Vue</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">$req</span> <span class="o">=</span> <span class="nx">req</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>We have included <code>store</code> argument and moved <code>req</code> within the exported function (which was not strictly required, but it avoids creating more variables and confusion with <code>this</code>).</p>
<p>You can now use <code>this.$req.post()</code> from anywhere within your app, and authentication is automatically taken care for you.</p>
<p>Similar to <code>Vue</code> and <code>store</code>, there are other arguments available to your boot function -</p>
<ul>
<li>router</li>
<li>ssrContext: useful in server rendered contexts</li>
<li>app: object that root component instantiates with</li>
</ul>
<p>Read more in <a href="https://quasar.dev/quasar-cli/cli-documentation/boot-files">docs</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Access Vuex Store in a Quasar App</title>
      <link>https://techformist.com/access-vuex-store-quasar/</link>
      <pubDate>Wed, 06 May 2020 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/access-vuex-store-quasar/</guid>
      <description>&lt;p&gt;Quasar is great. But, it is also a bit different when it comes to accessing the Vuex store from your code.&lt;/p&gt;
&lt;h2 id=&#34;why-is-quasar-any-different&#34;&gt;Why is Quasar any different?&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;Is it not just Vue?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Well, yes. But.. the project structure created by Quasar CLI differs from a &amp;ldquo;normal&amp;rdquo; that by Vue CLI. Quasar CLI builds on top of Vue as well but may not follow similar practices to other frameworks / libraries using Vue.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Quasar is great. But, it is also a bit different when it comes to accessing the Vuex store from your code.</p>
<h2 id="why-is-quasar-any-different">Why is Quasar any different?</h2>
<p>&ldquo;Is it not just Vue?&rdquo;</p>
<p>Well, yes. But.. the project structure created by Quasar CLI differs from a &ldquo;normal&rdquo; that by Vue CLI. Quasar CLI builds on top of Vue as well but may not follow similar practices to other frameworks / libraries using Vue.</p>
<p>If you can&rsquo;t really move away from the standard structure, just use Quasar as a plugin in a project created by Vue CLI. You may <a href="https://quasar.dev/start/pick-quasar-flavour">lose some features</a>, but you may find yourself at home and stay happy. In that case, you could leverage your existing knowledge on using <a href="/access-update-vuex-store">Vuex states and mutations in multiple ways</a>.</p>
<p>Or.. you could just experiment more and accept a different normal.</p>
<p>An app created by Quasar CLI does not have <code>main.js</code>. Vue compile/load sequence is taken care by quasar with options defined in a <code>/quasar.conf</code> file.</p>
<p>The <code>store/index.js</code> file in Vue CLI will have a function invocation -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="k">new</span> <span class="nx">Vuex</span><span class="p">.</span><span class="nx">Store</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>This store is then used in <code>main.js</code>..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">store</span> <span class="nx">from</span> <span class="s2">&#34;./store&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">router</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">store</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">render</span><span class="o">:</span> <span class="p">(</span><span class="nx">h</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">h</span><span class="p">(</span><span class="nx">App</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"><span class="p">}).</span><span class="nx">$mount</span><span class="p">(</span><span class="s2">&#34;#app&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>This and the corresponding setup within Vue CLI projects make it convenient to access states or mutations (in addition to helper functions).</p>
<ol>
<li>
<p>Use <code>this.$store</code> in components, store modules, or router</p>
</li>
<li>
<p>Directly import <code>store</code> and use it to access store functions</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">store</span> <span class="nx">from</span> <span class="s2">&#34;./store&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">store</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">auth</span><span class="p">.</span><span class="nx">isLoggedIn</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// how do you penalise a person without login
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></li>
</ol>
<p>In Quasar CLI, the <code>/store/index.js</code> file returns a <code>store</code> object..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">//...
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span><span class="p">({</span> <span class="nx">ssrContext</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">Store</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vuex</span><span class="p">.</span><span class="nx">Store</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">namespaced</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="c1">//...
</span></span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">Store</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>&hellip; but this is not used in the same way as Vue CLI.</p>
<p>Also, the modules are structured within folders in <code>/src/store</code> by default. And.. you can use <a href="https://quasar.dev/quasar-cli/cli-documentation/vuex-store">quasar CLI to create a new module</a>.</p>
<p>Directly accessing store will not work -</p>
<ol>
<li>
<p>Can&rsquo;t just import store</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">store</span> <span class="nx">from</span> <span class="s2">&#34;./store&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">store</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s2">&#34;blah&#34;</span><span class="p">,</span> <span class="nx">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="c1">// store is a function and does not support `set`
</span></span></span></code></pre></div></li>
<li>
<p><code>this.$store</code> is <code>undefined</code> and not available in stores / modules</p>
</li>
</ol>
<h2 id="how-can-you-use-a-vuex-store-in-quasar">How can you use a Vuex store in Quasar?</h2>
<p>You have more than one way to get to the store..!</p>
<h5 id="use-helper-functions">Use helper functions</h5>
<p>Continue to use <code>mapState</code>, <code>mapMutations</code>, and friends to manage your state.</p>
<h5 id="use-pathify">Use Pathify</h5>
<p>Works great everywhere. Use <code>sync</code> in store modules or in components. See working with <a href="/avoid-vuex-boilerplate-pathify/">Pathify</a>.</p>
<h5 id="use-normal-commit">Use &ldquo;normal&rdquo; <code>commit</code></h5>
<p>Fall back on the trusty commit in store modules!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;contact&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">namespaced</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">state</span><span class="o">:</span> <span class="nx">state</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">actions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">async</span> <span class="nx">updateContact</span><span class="p">({</span> <span class="nx">commit</span> <span class="p">},</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="c1">//...
</span></span></span><span class="line"><span class="cl">      <span class="nx">commit</span><span class="p">(</span><span class="s2">&#34;first_name&#34;</span><span class="p">,</span> <span class="s2">&#34;Ram&#34;</span><span class="p">);</span> <span class="c1">// within this module
</span></span></span><span class="line"><span class="cl">      <span class="nx">commit</span><span class="p">(</span><span class="s2">&#34;action/updateCall&#34;</span><span class="p">,</span> <span class="nx">actionData</span><span class="p">,</span> <span class="p">{</span> <span class="nx">root</span><span class="o">:</span> <span class="kc">true</span> <span class="p">});</span> <span class="c1">// mutation from `action`
</span></span></span><span class="line"><span class="cl">      <span class="c1">//...
</span></span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><h5 id="change-the-default-store-structure">Change the default store structure</h5>
<p>Just change the Vuex store structure to access it from anywhere.</p>
<p>Modify <code>./src/store/index.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Vue</span> <span class="nx">from</span> <span class="s2">&#34;vue&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Vuex</span> <span class="nx">from</span> <span class="s2">&#34;vuex&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Use a new variable and export values to change default behaviour.
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">store</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">Vue</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">Vuex</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// .. other code
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">Store</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vuex</span><span class="p">.</span><span class="nx">Store</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">namespaced</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;global&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">state</span><span class="o">:</span> <span class="p">{</span> <span class="nx">answer</span><span class="o">:</span> <span class="mi">42</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// mutations / getters / plugins/ other code
</span></span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// add this so that we export store
</span></span></span><span class="line"><span class="cl">  <span class="nx">store</span> <span class="o">=</span> <span class="nx">Store</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Quasar default
</span></span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">Store</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// add this line to access store wherever you need
</span></span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="p">{</span> <span class="nx">store</span> <span class="p">};</span>
</span></span></code></pre></div><p>This is useful to access state as well as commits.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// ./src/router.js
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">store</span> <span class="nx">from</span> <span class="s2">&#34;./store/index&#34;</span><span class="p">;</span>
</span></span></code></pre></div><h5 id="use-boot-time-plugins-app-plugins-in-quasar">Use <code>boot</code> time plugins (&ldquo;app plugins&rdquo;) in Quasar</h5>
<p>Create a new plugin (say <code>superfunc</code>) by creating a new file in <code>/src/boot/superfunc.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">superfunc</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">  <span class="nx">store</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">async</span> <span class="p">({</span> <span class="nx">store</span><span class="p">,</span> <span class="nx">Vue</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// something to do
</span></span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="nx">superfunc</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">superfunc</span><span class="p">.</span><span class="nx">store</span> <span class="o">=</span> <span class="nx">store</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">Vue</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">$superfunc</span> <span class="o">=</span> <span class="nx">superfunc</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>Then happily use <code>superfunc</code> in places -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;story store&#34;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_vm</span><span class="p">.</span><span class="nx">$superfunc</span><span class="p">.</span><span class="nx">store</span><span class="p">);</span>
</span></span></code></pre></div><h2 id="parting-words">Parting Words</h2>
<p>Not quite what you call &ldquo;super fun&rdquo;, but stores simply work in Quasar, and that&rsquo;s all there is to it.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Quasar Dev Stuck Without Errors</title>
      <link>https://techformist.com/quasar-dev-hang/</link>
      <pubDate>Wed, 11 Mar 2020 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/quasar-dev-hang/</guid>
      <description>&lt;p&gt;Do you see &lt;code&gt;quasar dev&lt;/code&gt; stuck but no errors reported anywhere? The fix was quite easy - only the way to get to the fix was frustrating.&lt;/p&gt;
&lt;p&gt;I faced this issue in a medium-sized project that I was playing around with. I was stupid enough to change a few lines in multiple components, and lo and behold - I don&amp;rsquo;t see the changes being compiled. Restarting &lt;code&gt;quasar dev&lt;/code&gt; doesn&amp;rsquo;t help either.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Do you see <code>quasar dev</code> stuck but no errors reported anywhere? The fix was quite easy - only the way to get to the fix was frustrating.</p>
<p>I faced this issue in a medium-sized project that I was playing around with. I was stupid enough to change a few lines in multiple components, and lo and behold - I don&rsquo;t see the changes being compiled. Restarting <code>quasar dev</code> doesn&rsquo;t help either.</p>
<p>The command simply does not move ahead beyond a point..</p>
<p><img loading="lazy" src="/2020/quasar-dev-stuck.jpg" type="" alt="quasar-dev-stuck"  /></p>
<p>The first and foremost thing you do is to revert things to where they were. With no real commits, I could only fidget around till I get to a working state, or go back to the original.</p>
<p>After trying about 10 minutes, I gave up and was exploring <code>package.json</code> and <code>quasar</code> CLI params to see whether I could anything else. And.. saw this.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="s2">&#34;scripts&#34;</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;lint&#34;</span><span class="o">:</span> <span class="s2">&#34;eslint --ext .js,.vue --ignore-path .gitignore ./&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;test&#34;</span><span class="o">:</span> <span class="s2">&#34;echo \&#34;No test specified\&#34; &amp;&amp; exit 0&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">},</span>
</span></span></code></pre></div><p>I see commands, I run them. So, lint it was.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npm run lint
</span></span></code></pre></div><p><img loading="lazy" src="/2020/quasar-hang-lint-error.jpg" type="" alt="quasar-hang-lint-error"  /></p>
<p>Looks like <code>quasar dev</code> breaks without errors if there are errors in templates - who knew..? I do remember seeing errors in Vue CLI for similar issues - should go back, compare them, and report the issue back to the teams (soon 🐌).</p>
<p>Also, linting helps. Again, who knew.. :)?</p>
<p>The fix by itself was easy enough. All it needed was a change in two lines of code in distinct components. And, I was all set to continue breaking the application further.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
