<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Adrià Fontcuberta</title>
    <description>The latest articles on DEV Community by Adrià Fontcuberta (@afontcu).</description>
    <link>https://dev.to/afontcu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F87913%2Fcec1df65-7b3c-4274-bcbe-e1aaf3050a8c.jpg</url>
      <title>DEV Community: Adrià Fontcuberta</title>
      <link>https://dev.to/afontcu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/afontcu"/>
    <language>en</language>
    <item>
      <title>Vue state management from the ground up</title>
      <dc:creator>Adrià Fontcuberta</dc:creator>
      <pubDate>Tue, 04 Sep 2018 15:32:17 +0000</pubDate>
      <link>https://dev.to/afontcu/vue-state-management-from-the-ground-up-1kp</link>
      <guid>https://dev.to/afontcu/vue-state-management-from-the-ground-up-1kp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things. — &lt;em&gt;Phil Karlton&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, I guess Phil Karlton never had to deal with managing state on the front end..!&lt;/p&gt;

&lt;p&gt;State management is one of “&lt;em&gt;those things&lt;/em&gt;”. Backends roll their eyes, frontends hide under the desk. After all, managing state is the hardest part of being a frontend developer: you need to think in terms of the UI as something that changes over time. And we are not particularly good at it.&lt;/p&gt;

&lt;p&gt;In this post, we will discover how to &lt;strong&gt;handle state in a Vue application&lt;/strong&gt; from the ground up. We will end up creating our own state manager generator!&lt;/p&gt;

&lt;p&gt;Let’s dive in:&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Our first app. Election Day!
&lt;/h1&gt;

&lt;p&gt;First of all, we need an application. We cannot manage an application state without an application, right?&lt;/p&gt;

&lt;p&gt;Let’s create a voting app, to let you folks vote for the next President(?):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;TODO (REMOVE BEFORE PUBLISHING): avoid making jokes about politics. Not a good time, not a good time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The code above renders something as pretty as this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vFllakhz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AiwyBQkT2vuOIg3XaeBuh9Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vFllakhz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AiwyBQkT2vuOIg3XaeBuh9Q.png" alt="It looks like the browser failed to load the CSS"&gt;&lt;/a&gt;&lt;em&gt;It looks like the browser failed to load the CSS&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I can hear your brain screaming:&lt;/p&gt;

&lt;p&gt;“&lt;em&gt;Man, you are not managing state. You are just passing props down to each component. You promised state management. You better deliver&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;Well, isn’t passing props the simplest form of “state management”? Isn’t our main component holding both red and blue, our pieces of state?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(The answers are YES and YES)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But yeah, I hear you. Passing down props is not pretty nor comfortable nor scalable, so let’s try something else.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Isolating state
&lt;/h1&gt;

&lt;p&gt;Let’s create a “state holder” object and manage our whole state from there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;There it is! Our application state, properly held and encapsulated. It wasn’t that hard!&lt;/p&gt;

&lt;p&gt;Now, from our components, we could do something like the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TotalVotes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Total votes: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Red: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; - Blue: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ...and, inside our main component,...&lt;/span&gt;
&lt;span class="nl"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;voteForRed&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;voteForBlue&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Spoiler: &lt;strong&gt;this is not going to work&lt;/strong&gt;. Why?&lt;/p&gt;

&lt;p&gt;Because Vue uses data method to trigger its “magic reactivity”. Without passing our data to data (heh), Vue won’t be able to track down value changes and update our components in response.&lt;/p&gt;

&lt;p&gt;Easily said, &lt;em&gt;easily(?)&lt;/em&gt; fixed:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;A few things happened there:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Look ma’, no props! &lt;em&gt;(lines 8, 9)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Every component registers our state in their data method. Now Vue is able to track down state changes, so when we vote for 🔴 all our components &lt;em&gt;rerender&lt;/em&gt; with the proper value. &lt;em&gt;(lines 20, 27, 35)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We had to remove our pretty arrow function from the render functions because now we are using this.* (lines 21, 28)*&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now our state it “isolated” from components. &lt;em&gt;Free as in beer&lt;/em&gt;. &lt;em&gt;(line 14)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ok, so now we have our state separated from our “UI implementation”, but that came with some caveats: &lt;strong&gt;we need to register our state to each component&lt;/strong&gt; in data(), we cannot use the beautiful arrow functions in our render functions…&lt;/p&gt;

&lt;p&gt;But.&lt;/p&gt;

&lt;p&gt;Wait.&lt;/p&gt;

&lt;p&gt;Did I just say “&lt;em&gt;Vue needs to register data in data() to make it reactive?&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;Yes, I did.&lt;/p&gt;

&lt;p&gt;But in my solution I’m using every component instance to make the very same data reactive, right?&lt;/p&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;And could I create a shared Vue instance to hold that reactivity, so my components don’t have to?&lt;/p&gt;

&lt;p&gt;Well, yes. Let me write a big heading:&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Create a shared Vue instance to hold that reactivity
&lt;/h1&gt;

&lt;p&gt;So, information stored in data() becomes “reactive by default”. And what is the piece of information we want to make reactive?&lt;/p&gt;

&lt;p&gt;Our state!&lt;/p&gt;

&lt;p&gt;So what if we did this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Neat! Now our state is reactive. We’ll be sharing a Vue instance for all the data, but that’ll be waaaay cleaner than my previous solution, right?&lt;/p&gt;

&lt;p&gt;But, wait. Wait. Wait. We have a Vue instance, now. And do you know what a Vue instance can hold, besides reactive data?&lt;/p&gt;

&lt;p&gt;Exactly: &lt;strong&gt;methods&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now our voteforRed() and voteForBlue() methods can be &lt;strong&gt;collocated&lt;/strong&gt; with our state!&lt;/p&gt;

&lt;p&gt;Let’s check it out:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Vuetiful! Let me highlight the improvements we achieved:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;State and methods that mutate our state are now &lt;strong&gt;placed together&lt;/strong&gt;. No more leaking implementation details! Notice that our voteFor methods are quite simple, but that they could be as complicated as needed. &lt;em&gt;(lines 9, 10)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We still need to call these methods from our component. &lt;em&gt;(lines 25, 26)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Back to our render functions with arrows. &lt;em&gt;(lines 15, 19)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And we removed a lot of boilerplate code (all the data() declarations).&lt;/p&gt;

&lt;p&gt;Okay, so far so good! Our current solution is terse, simple, and idiomatic.&lt;/p&gt;

&lt;p&gt;But we need to import Vue, and then create a new instance. While this is not inherently “bad”, I feel we could do better, couldn’t we?&lt;/p&gt;

&lt;p&gt;For instance, our solution cannot be shared among projects right now. I need to teach people to create a Vue instance, populate its data method, then register some methods to modify the state… way too much.&lt;/p&gt;

&lt;p&gt;It’s time to…&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Encapsulate our state in a function
&lt;/h1&gt;

&lt;p&gt;Fortunately, Javascript provides us with a cool feature that allows us to hide all those details and keep things simple: functions. We are gonna create our &lt;a href="https://medium.com/javascript-scene/javascript-factory-functions-with-es6-4d224591a8b1"&gt;factory function&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s define our createStore function. What’s the API? I would expect:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A &lt;em&gt;data&lt;/em&gt; parameter to set our initial state. We could call the parameter “state”, for the sake of clarity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A list of mutations functions to change my state when needed. We could call the parameter “mutations”, for the sake of clarity.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally, I would expect our createStore to expose a generic method that would allow my components to “run” the mutations. We could call the parameter “commit”, for the sake of clarity (you usually &lt;em&gt;commit mutations&lt;/em&gt;, right?).&lt;/p&gt;

&lt;p&gt;You see where I’m going, don’t ya.&lt;/p&gt;

&lt;p&gt;We want to end up writing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;voteForRed&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;voteForBlue&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Quite nice, right? And pretty straightforward.&lt;/p&gt;

&lt;p&gt;Now, how would we implement this createStore helper? Remember that we should use a Vue instance to leverage its reactivity:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mutations&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;commit&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutationName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;mutationName&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Some things happened there:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;First of all, we return a new Vue instance. So far so good.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then, we register our state parameter to the data() method of the instance. Bam! Our state is now reactive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, we create our public commit() method. This method takes a name of a mutation as the parameter, and then runs the very same mutation (and passes our state). If we call commit('someMutation'), our method will call mutations.someMutation(this.state).&lt;br&gt;
Notice that in a real implementation we should handle non-existent mutations!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, how do our component look like, now?&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TotalVotes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Total votes: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Red: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; - Blue: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TotalVotes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Results&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;voteForRed&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;voteForRed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;voteForBlue&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;voteForBlue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we access store.state to get our state, and store.commit to modify it (notice that we pass the desired mutation name as parameter).&lt;/p&gt;

&lt;p&gt;All together now!:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Isn’t that cool?&lt;/p&gt;

&lt;p&gt;Now we can generate hundreds of thousands of stores by providing a simple createStore method. You’d want to place your createStore in a file and export it, so you can import it in your applications and create a whole new store. Bonus points if you call this file Vuex.js 😁.&lt;/p&gt;

&lt;h1&gt;
  
  
  ✅ That’s a wrap!
&lt;/h1&gt;

&lt;p&gt;state, mutations… does it sound familiar to you? Well, if you have ever used &lt;a href="https://vuex.vuejs.org/"&gt;Vuex&lt;/a&gt;, it definitely should. We effectively mapped the Vuex API in our example.&lt;/p&gt;

&lt;p&gt;We are missing getters and actions, but I hope you get the idea that Vuex is &lt;strong&gt;an abstraction of things we already knew&lt;/strong&gt;. It’s a great abstraction, well-polished, useful, scalable. But an abstraction, after all. We just keep adding layers to the heart of the framework: &lt;strong&gt;reactivity&lt;/strong&gt;. That’s the core feature that triggers everything.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Vuex is &lt;strong&gt;an abstraction of things we already knew&lt;/strong&gt;.
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;p&gt;A quick recap:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;State management on the front end is something &lt;strong&gt;scalable&lt;/strong&gt;. My personal recommendation: start as small as possible, and think about it twice before adding new things. Vuex is amazing (it truly is!), but do you really need it yet?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reactivity&lt;/strong&gt; is the king of Vue. Everything, and I mean everything, depends on data being reactive. And this is great because we can leverage that reactivity and create nice, useful abstractions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we &lt;em&gt;kinda&lt;/em&gt; understand what Vuex is doing under the hood, which is cool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sometimes, &lt;strong&gt;verbosity trumps succinctness&lt;/strong&gt; if it provides context, intent, and repeatability to our code (for instance, step 4 required way more code that step 2).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Wanna dig in? &lt;a href="https://github.com/afontcu/vue-state-management/commits/master"&gt;I created a Github repo&lt;/a&gt; with 4 commits: one commit per step of the post. Feel free to play with it and inspect every change.&lt;/p&gt;

&lt;p&gt;Do you want to practice a bit with our solution? Here’s a challenge: How would you implement getters? And actions? and… &lt;a href="https://vuex.vuejs.org/guide/modules.html"&gt;modules&lt;/a&gt;? 😏&lt;/p&gt;

&lt;p&gt;Hope it helps!&lt;/p&gt;

&lt;p&gt;(This post was first published in &lt;a href="https://hackernoon.com/vue-state-management-from-the-ground-up-a31eb87c668d"&gt;Hacker Noon&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vuex</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>A Vue pattern for idiomatic, performant component registration you might not know about</title>
      <dc:creator>Adrià Fontcuberta</dc:creator>
      <pubDate>Wed, 22 Aug 2018 18:00:08 +0000</pubDate>
      <link>https://dev.to/afontcu/a-vue-pattern-for-idiomatic-performant-component-registration-you-might-not-know-about-58of</link>
      <guid>https://dev.to/afontcu/a-vue-pattern-for-idiomatic-performant-component-registration-you-might-not-know-about-58of</guid>
      <description>&lt;p&gt;If you played with Vue &lt;strong&gt;Single File Components&lt;/strong&gt; a little bit, you probably know how to “call” a component from another one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import the child component&lt;/li&gt;
&lt;li&gt;Register it on the components object of the parent component.&lt;/li&gt;
&lt;li&gt;Add the component to the template/render function.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;some-random-thing&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SomeRandomThing&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/SomeRandomThing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;SomeRandomThing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It’s a common pattern, and it might end up becoming tedious. In this short post, we’ll learn a pattern (or two) to avoid some repetition. And we‘ll also improve our application performance for free.&lt;/p&gt;

&lt;p&gt;Let’s dive in!&lt;/p&gt;



&lt;p&gt;Imagine a Header component that holds the information and layout for our application’s header. Imagine now that this information could be user-related or company-related, depending on… I don’t know, a setting value. Whatever.&lt;/p&gt;

&lt;p&gt;Now imagine that we have a UserInfo and CompanyInfo components. And we want to display one or another depending on that setting value we had already configured before.&lt;/p&gt;


&lt;h2&gt;
  
  
  Version 1: Good ol’ way
&lt;/h2&gt;

&lt;p&gt;This is the way we outlined above.&lt;/p&gt;

&lt;p&gt;This is probably the “&lt;em&gt;default&lt;/em&gt;” way everyone would think of (including me!):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Nothing fancy. We import two components, register them, and then display one or another depending on some prop value.&lt;/p&gt;

&lt;p&gt;You might have used this “pattern” &lt;em&gt;aaaall&lt;/em&gt; over the place. And while there’s nothing inherently wrong with it, we can do better.&lt;/p&gt;




&lt;h2&gt;
  
  
  Version 2: &lt;code&gt;&amp;lt;component /&amp;gt;&lt;/code&gt; to the rescue
&lt;/h2&gt;

&lt;p&gt;There’s a built-in component in Vue called &lt;a href="https://vuejs.org/v2/guide/components.html#Dynamic-Components"&gt;Component&lt;/a&gt;. Yeah, try to search that on Google.&lt;/p&gt;

&lt;p&gt;This component &lt;code&gt;&amp;lt;component /&amp;gt;&lt;/code&gt; acts as a placeholder for another component. It accepts a special &lt;code&gt;:is&lt;/code&gt; prop with the name of the component it should render.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Notice how now we create a computed value with the name of the desired component, thus removing the v-if/v-else logic in the template in favor of the almighty . We could even pass some props as usual.&lt;/p&gt;

&lt;p&gt;Isn’t it cool?&lt;/p&gt;

&lt;p&gt;Well, it is. But there’s still a &lt;strong&gt;major pain point&lt;/strong&gt; there.&lt;/p&gt;

&lt;p&gt;We had to import and register all the valid values for the :is prop. We had to import and register UserInfo and CompanyInfo.&lt;/p&gt;

&lt;p&gt;Only if someone allowed us to dynamically import all these components on the fly so we wouldn’t have to import and register them…&lt;/p&gt;

&lt;p&gt;…oh wait!&lt;/p&gt;

&lt;p&gt;Did you say “&lt;em&gt;dynamically import&lt;/em&gt;”?&lt;/p&gt;

&lt;p&gt;We got you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Version 3: dynamic imports +  (and code splitting for free!)
&lt;/h2&gt;

&lt;p&gt;Let’s see how &lt;strong&gt;&lt;a href="https://webpack.js.org/guides/code-splitting/#dynamic-imports"&gt;dynamic imports&lt;/a&gt;&lt;/strong&gt; and  can play together:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;With the above solution, &lt;strong&gt;import&lt;/strong&gt; turns into a function which returns a Promise. It will load the desired module at &lt;strong&gt;runtime&lt;/strong&gt; if the Promise resolves (that is, nothing breaks and gets rejected).&lt;/p&gt;

&lt;p&gt;So, what is happening here? We still use our new friend , but this time we are not providing a simple string but a whole component object. What?&lt;/p&gt;

&lt;p&gt;As stated in the documentation, the :is prop can contain either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The name of a registered component, or&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A component’s options object&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bang! A “component’s options object”. This is exactly what we need!&lt;/p&gt;

&lt;p&gt;Notice how we avoided importing and registering the components because our dynamic import is doing so at runtime ❤ .&lt;/p&gt;

&lt;p&gt;There’s more information about Vue and Dynamic Imports &lt;a href="https://vuejs.org/v2/guide/components-dynamic-async.html"&gt;in the official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A little gotcha
&lt;/h3&gt;

&lt;p&gt;Notice that we access our prop &lt;code&gt;this.isCompany&lt;/code&gt; &lt;strong&gt;outside&lt;/strong&gt; of the dynamic import statement.&lt;/p&gt;

&lt;p&gt;This is mandatory because otherwise Vue cannot do its reactivity magic and update our computed value when the prop changes. Try it out, you’ll see what I mean.&lt;/p&gt;

&lt;p&gt;By accessing to our prop outside the dynamic import (by creating a simple name variable) Vue knows that our componentInstance computed property “depends on” &lt;code&gt;this.isCompany&lt;/code&gt;, so it will effectively trigger a reevaluation when our prop changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  A word of caution &lt;em&gt;(updated, August 4th)&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;When using dynamic imports, Webpack will create (on build time) &lt;strong&gt;a chunk file for every file matching the expression inside the import function&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The example above is a little contrived, but imagine that my /components folder contains 800 components. Then Webpack would create 800 chunks.&lt;/p&gt;

&lt;p&gt;Since this is not what we were looking for (heh), make sure you &lt;a href="https://twitter.com/TheLarkInn/status/1025918613557981184"&gt;write stricter expressions and/or follow folder conventions&lt;/a&gt;. For instance, I tend to group the components I want to split in a folder called /components/chunks or /components/bundles, so I know which components is Webpack splitting.&lt;/p&gt;

&lt;p&gt;Besides that &lt;em&gt;gotchas&lt;/em&gt;, we achieved an &lt;strong&gt;idiomatic&lt;/strong&gt;, &lt;strong&gt;terser&lt;/strong&gt; pattern. It comes with a wonderful side effect that makes it really shine:&lt;/p&gt;

&lt;h3&gt;
  
  
  Our “conditional” components are now code split!
&lt;/h3&gt;

&lt;p&gt;If you npm run build a component like this, you’ll notice that Webpack will create a specific bundle file for UserInfo.vue, and another one for CompanyInfo.vue. Webpack &lt;a href="https://webpack.js.org/guides/code-splitting/#dynamic-imports"&gt;does that by default&lt;/a&gt;. Webpack is pure love ❤.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;great&lt;/strong&gt; because our users won’t load these bundles until the very moment our application request them, thus reducing our initial bundle size and improving our app’s performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://webpack.js.org/guides/code-splitting/"&gt;Code Splitting&lt;/a&gt; is dope. Make sure you are familiar with it because if you are not using it yet, you can greatly improve your apps. Go for it!&lt;/p&gt;

&lt;p&gt;Here, &lt;a href="https://codesandbox.io/s/5kpzqnyp4x"&gt;take this CodeSandbox&lt;/a&gt; and feel free to play with the three solutions.&lt;/p&gt;




&lt;p&gt;By the way, you can even &lt;a href="https://webpack.js.org/api/module-methods/#import-"&gt;customize the bundle name and the loading strategy&lt;/a&gt; for dynamic imports by using magic comments.&lt;/p&gt;

&lt;p&gt;If you want to learn more about Code Splitting, Dynamic Imports and why you should care, please listen to sensei &lt;a href="https://dev.toundefined"&gt;Sean T. Larkin&lt;/a&gt;, from the Webpack core team:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/R2J9cTtlBXI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Hope it helped!&lt;/p&gt;




&lt;p&gt;This post was featured in the &lt;a href="https://www.getrevue.co/profile/vuenewsletter/issues/105-vue-js-sprint-sneak-peek-get-the-vuevixens-scholarship-for-vue-js-london-125646"&gt;#105 issue of the official Vue.js newsletter&lt;/a&gt; 💃&lt;/p&gt;

</description>
      <category>vue</category>
      <category>webpack</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
