<?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: Marina Mosti</title>
    <description>The latest articles on DEV Community by Marina Mosti (@marinamosti).</description>
    <link>https://dev.to/marinamosti</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%2F122392%2F19f88e25-4d17-436e-ba7a-882b47a98fac.jpg</url>
      <title>DEV Community: Marina Mosti</title>
      <link>https://dev.to/marinamosti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marinamosti"/>
    <language>en</language>
    <item>
      <title>Loading and using a fixture from an API endpoint for Cypress e2e tests</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Wed, 19 Feb 2020 10:01:05 +0000</pubDate>
      <link>https://dev.to/marinamosti/loading-and-using-a-fixture-from-an-api-endpoint-for-cypress-e2e-tests-2811</link>
      <guid>https://dev.to/marinamosti/loading-and-using-a-fixture-from-an-api-endpoint-for-cypress-e2e-tests-2811</guid>
      <description>&lt;p&gt;I love Cypress, it’s one of those tools that for me has just made e2e testing actually fun and engaging. In this article, we’re going to explore a common scenario that you may encounter when doing e2e testing on your apps: fetching a data &lt;code&gt;fixture&lt;/code&gt; from an API endpoint before your tests and using it to write your tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Cypress fixture?
&lt;/h2&gt;

&lt;p&gt;In case you haven’t heard of fixtures before, you can think of them as a predefined piece of data that you use in your tests to perform certain actions.&lt;/p&gt;

&lt;p&gt;Consider the following fixture example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yoda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secureiam&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If we have an endpoint in our application that for example holds the user’s settings page, we may need to construct the following URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//www.holocrons.com/123/settings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this demo URL, the first segment is the &lt;code&gt;id&lt;/code&gt; of the user, so based on our dummy fixture it would be &lt;code&gt;123&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Cypress, to navigate to a URL you use the &lt;code&gt;visit&lt;/code&gt; command, so you may want to construct your action as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/123/settings&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The problem here however is that we are hardcoding a user id into our tests. In most cases this will become a problem, because unless our backend and database are set up to work with a specific id, if that user ceases to exist for some reason then all of our e2e tests will break.&lt;/p&gt;

&lt;p&gt;The first solution is to create a local fixture, so you would go into your cypress folder structure, and create a &lt;code&gt;user.json&lt;/code&gt; file inside the appointed &lt;code&gt;fixtures&lt;/code&gt; folder. Inside, we would paste the content of our demo fixture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yoda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secureiam&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, in order to use this fixture inside our test, we could set up a &lt;code&gt;beforeEach&lt;/code&gt; hook inside our spec file, and load it as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my tests&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path/to/user.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Do some things like setting up routes. &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;The Cypress &lt;code&gt;fixture&lt;/code&gt; method takes a string param that points to where the &lt;code&gt;fixture&lt;/code&gt; file is located. This path is based off where your root &lt;code&gt;cypress.json&lt;/code&gt; file is located.&lt;/p&gt;

&lt;p&gt;Once the file is loaded into the fixture, you can use &lt;code&gt;then&lt;/code&gt; block to trigger some extra actions like setting up your &lt;code&gt;cy.server()&lt;/code&gt; and some routes.&lt;br&gt;
Notice that in this example we’re setting up an alias with &lt;code&gt;.as(&lt;/code&gt;&lt;code&gt;'&lt;/code&gt;&lt;code&gt;userData&lt;/code&gt;&lt;code&gt;'&lt;/code&gt;&lt;code&gt;)&lt;/code&gt;. This is important if you’re going to be using the loaded fixture data later on in your tests, outside of the &lt;code&gt;then&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;Let’s now take our new fixture &lt;code&gt;userData&lt;/code&gt; and actually use it to set up some routes. Because we are inside the &lt;code&gt;then&lt;/code&gt; block you have two choices, you can receive as the param to the method the newly loaded &lt;code&gt;fixture&lt;/code&gt;, or you can use &lt;code&gt;this&lt;/code&gt; to access it as a property.&lt;/p&gt;

&lt;p&gt;In these examples we’re going to use the &lt;code&gt;this&lt;/code&gt; approach, but be warned - in order for &lt;code&gt;this&lt;/code&gt; to keep the correct context, we &lt;strong&gt;have&lt;/strong&gt; to use regular &lt;code&gt;function ()&lt;/code&gt; syntax, not arrow functions on our &lt;code&gt;it&lt;/code&gt; calls! If you don’t do this, you will get &lt;code&gt;undefined&lt;/code&gt; errors due to how arrow functions &lt;code&gt;this&lt;/code&gt; context works.&lt;/p&gt;

&lt;p&gt;Let’s create a &lt;code&gt;router&lt;/code&gt; alias for our settings page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my tests&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path/to/user.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Do some things like setting up routes. &lt;/span&gt;
          &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/settings`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userSettings&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;Notice how in this case we are using &lt;code&gt;this.userData.id&lt;/code&gt; to explicitly declare that our &lt;code&gt;route&lt;/code&gt; needs to point to user id &lt;code&gt;123&lt;/code&gt;, the one that was declared in the fixture. Now we can access any data inside our user.json file through the &lt;code&gt;this.userData&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Here’s another example inside an &lt;code&gt;it&lt;/code&gt; block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shows the users username in the header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visit&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/settings`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&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;userData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&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;Our tests are now hard-code free. But what happens when our tests are driven by some sort of function or endpoint that populates our database with dummy data? We are now going to look at the same problem/solution, but by loading the &lt;code&gt;fixture&lt;/code&gt; from an API endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loading API based fixtures
&lt;/h2&gt;

&lt;p&gt;In order to get our fixture from an API, we are going to create some Cypress custom commands to make the code easier to use in our tests.&lt;/p&gt;

&lt;p&gt;Head over to your &lt;code&gt;commands.js&lt;/code&gt; file, and let’s get started.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;Cypress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loadFixture&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;savePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`api/path/to/fixture/endpoint`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fixture loaded from API&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;savePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fixture written to disk&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s take a closer look at the code. First we create a new Cypress command and call it &lt;code&gt;loadFixuture&lt;/code&gt;, it will receive a single param called &lt;code&gt;savePath&lt;/code&gt;. This will be a string, and the path to where our fixture will be saved in the disk.&lt;/p&gt;

&lt;p&gt;Inside our command, we first call &lt;code&gt;cy.request&lt;/code&gt; to make a network request to our fixture endpoint in the API. This endpoint should give us a JSON response, so make sure to adjust the &lt;code&gt;url&lt;/code&gt; paramter to match your app’s needs - you can also of course pass paramters in the body or query string as needed. Check out the documentation for &lt;code&gt;cy.request&lt;/code&gt; for more options.&lt;/p&gt;

&lt;p&gt;After the request completes, we chain a &lt;code&gt;then&lt;/code&gt; callback that gives us the result from our request - this &lt;code&gt;res&lt;/code&gt; holds the response from the API. &lt;/p&gt;

&lt;p&gt;We make a couple of &lt;code&gt;cy.log&lt;/code&gt; statements so that we can track from our Cypress log what is happening, and finally call a &lt;code&gt;cy.writeFile&lt;/code&gt; command with the &lt;code&gt;savePath&lt;/code&gt; that we passed to our command, and the &lt;code&gt;body&lt;/code&gt; from the network response. This will write the JSON to a file.&lt;/p&gt;

&lt;p&gt;You may be wondering at this point why we are writing the network result to a file, we need this information to be in a file so that we can later on read it using the &lt;code&gt;cy.fixture&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;With our new command, we can now update our tests to use the new loading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my tests&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loadFixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path/to/user.json&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;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path/to/user.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Do some things like setting up routes. &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;Notice that we are now downloading the fixture on the &lt;code&gt;before&lt;/code&gt; hook, that way we can guarantee that it is only downloaded once since this type of request can usually be heavy on the server and database.&lt;/p&gt;

&lt;p&gt;Now, whenever we call the &lt;code&gt;beforeEach&lt;/code&gt; as we did before we will actually be targeting a file that has been downloaded and written before our tests begin, this also guarantees that if necessary you will be working with new generated data.&lt;/p&gt;

&lt;p&gt;As always, thanks for reading and share with me your comments on twitter at: &lt;a href="https://twitter.com/marinamosti"&gt;@marinamosti&lt;/a&gt;&lt;br&gt;
PS. All hail the magical avocado 🥑&lt;br&gt;
PSS. ❤️🔥🐶☠️&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Accessible form error auto-focus with Vuelidate in Vue</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Tue, 10 Dec 2019 19:47:23 +0000</pubDate>
      <link>https://dev.to/marinamosti/accessible-form-error-auto-focus-with-vuelidate-in-vue-4cok</link>
      <guid>https://dev.to/marinamosti/accessible-form-error-auto-focus-with-vuelidate-in-vue-4cok</guid>
      <description>&lt;p&gt;Vuelidate makes it very simple for developers to handle even the most complex cases of form validation, but what about accessibility UX? Let's take a look at some very simple practices that you can implement on your Vuelidate powered forms that will make them behave a lot more nicely for accessibility tools like screen reade&lt;/p&gt;

&lt;h2&gt;
  
  
  The form
&lt;/h2&gt;

&lt;p&gt;Let's first create a standard form, and apply some validation rules to our data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit.prevent=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
              &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
              &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
              &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
              &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
              &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
              &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
              &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
              &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
              &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our form has three inputs - the first two are of type &lt;code&gt;text&lt;/code&gt; and the last one of type &lt;code&gt;email&lt;/code&gt;. Finally, we have a &lt;code&gt;submit&lt;/code&gt; type button to trigger the &lt;code&gt;submit&lt;/code&gt; event on our &lt;code&gt;form&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;form&lt;/code&gt; element itself has a &lt;code&gt;@submit&lt;/code&gt; handler with a &lt;code&gt;prevent&lt;/code&gt; modifier so that we can stop default browser behavior and process the form submit ourselves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To learn more about event modifiers, you can check the &lt;a href="https://vuejs.org/v2/guide/events.html#Event-Modifiers"&gt;official docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's now add the code that will handle the validation rules and the submit method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vuelidate/lib/validators&lt;/span&gt;&lt;span class="dl"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&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;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&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="na"&gt;validations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&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;submit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Submit the form here!&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;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First, we import a couple of Vuelidate's &lt;a href="https://vuelidate.js.org/#sub-builtin-validators"&gt;built in validators&lt;/a&gt;: &lt;code&gt;required&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We create a local state with &lt;code&gt;data&lt;/code&gt; and set up a  property for each of our inputs, and proceed to create a &lt;code&gt;validations&lt;/code&gt; object. This object in turn defines rules for each one of our inputs.&lt;/p&gt;

&lt;p&gt;Finally, we need to head back into the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; and connect our inputs to Vuelidate through &lt;code&gt;v-model&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
            &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
        &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
        &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$model"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
        &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
        &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
        &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$model"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;change=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$touch"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that for firstName and lastName we are v-modeling directly into Vuelidate's internal &lt;code&gt;$model&lt;/code&gt; for each property, this allows us to not have to worry about triggering the &lt;code&gt;$dirty&lt;/code&gt; state of each input on  change/input events.&lt;/p&gt;

&lt;p&gt;For the email input, however, I have opted to v-model directly to the &lt;code&gt;data()&lt;/code&gt; local state and trigger the &lt;code&gt;$touch&lt;/code&gt; event manually. That way the validation won't trigger right away until after the input blur's, and the user won't be faced with an immediate error message when the &lt;code&gt;email&lt;/code&gt; condition is not met because they're starting to type it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding error messages
&lt;/h2&gt;

&lt;p&gt;Let's start by adding descriptive error messages when an input's validation fails. We are going to first add a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; element directly after the input and output the error for the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
        &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
        &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
        &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$model"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt;
        &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$error"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is required&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
        &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
        &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
        &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$model"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is required&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;change=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$touch"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ email }} doesn't seem to be a valid email&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that each &lt;code&gt;p&lt;/code&gt; tag is getting conditionally rendered by a &lt;code&gt;v-if&lt;/code&gt; statement. This statement is checking inside the Vuelidate object &lt;code&gt;$v&lt;/code&gt;, then accessing the state for each input (based on how we defined your validations and state in the previous section), and finally we access the &lt;code&gt;$error&lt;/code&gt; state of this element.&lt;/p&gt;

&lt;p&gt;Vuelidate has different states it tracks for each element, &lt;code&gt;$error&lt;/code&gt; is a boolean property that will check for two conditions - it will check that the input's &lt;code&gt;$dirty&lt;/code&gt; state is &lt;code&gt;true&lt;/code&gt;, and that ANY of the validation rules is failing. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;$dirty&lt;/code&gt; state is a boolean with the value of &lt;code&gt;false&lt;/code&gt; by default, when an input is changed by the user and a v-model state to the &lt;code&gt;$v.element.$model&lt;/code&gt; is set, it will automatically change to &lt;code&gt;true&lt;/code&gt;, indicating that the contents have been modified and the validation is now ready to display errors (otherwise the form would be in default error state when loaded).&lt;/p&gt;

&lt;p&gt;In the case of our &lt;code&gt;email&lt;/code&gt; input, since we binding the &lt;code&gt;v-model&lt;/code&gt; to our local state, we have to trigger the &lt;code&gt;$touch&lt;/code&gt; method on the &lt;code&gt;change&lt;/code&gt; event - this &lt;code&gt;$touch&lt;/code&gt; will set the &lt;code&gt;$dirty&lt;/code&gt; state to true.&lt;/p&gt;

&lt;p&gt;Now that we have a clear error message for our users when the validation fails, let's go ahead and make it accessible. As it is right now, screen readers will not pick up the change and notify the user of the problem whenever the input is re-focused, which would be super confusing.&lt;/p&gt;

&lt;p&gt;Thankfully, we have a handy tool to attach this message to our input - the  &lt;code&gt;aria-describedby&lt;/code&gt; attribute. This attribute allows to attach one or more element through their &lt;code&gt;id&lt;/code&gt; that describe the element. So let's modify our form to reflect this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit.prevent=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
            &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"firstNameError"&lt;/span&gt;
            &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
            &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
            &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
            &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$model"&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt;
            &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$error"&lt;/span&gt;
            &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstNameError"&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is required&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
            &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"lastNameError"&lt;/span&gt;
            &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
            &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
            &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
            &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$model"&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$error"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastNameError"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is required&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
            &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"emailError"&lt;/span&gt;
            &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
            &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
            &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
            &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
            &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;change=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$touch"&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$error"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"emailError"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ email }} doesn't seem to be a valid email&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Great! If you now test out the form with a screen reader such as &lt;a href="https://www.chromevox.com/"&gt;ChromeVox&lt;/a&gt;, you can trigger a validation error and focus the element - the screen reader will now &lt;em&gt;read&lt;/em&gt; the error as part of the input's information when focused, making it clearer to the user as to what is going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Triggering validations on @submit
&lt;/h2&gt;

&lt;p&gt;Let's take the form one step further, right now when you click the submit button nothing will happen. Let's trigger the validation check for all of the element's on our form when the user tries to submit the form.&lt;/p&gt;

&lt;p&gt;Modify the &lt;code&gt;submit&lt;/code&gt; method like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&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;submit&lt;/span&gt;&lt;span class="p"&gt;()&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;$v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$touch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&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;$v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$invalid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Something went wrong &lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Submit the form here&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;Two things are happening here, first we trigger the validations on every input on our form by calling &lt;code&gt;$v.$touch()&lt;/code&gt;. Vuelidate will go over every input that has a validator and trigger the validation functions, so that if there are any errors the states will be updated to show it.&lt;/p&gt;

&lt;p&gt;Vuelidate also managed a "global" state for the form which includes its own &lt;code&gt;$invalid&lt;/code&gt; state, which we will use to verify if the form is in a valid state to be submitted - if it's not, we are going to help our users out by auto-focusing the first element that has an error state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auto-focusing the element with an error
&lt;/h2&gt;

&lt;p&gt;As it is right now, when our users click the submit button and trigger the &lt;code&gt;submit()&lt;/code&gt; method, Vuelidate will verify all the inputs. If some of these inputs have errors, the &lt;code&gt;v-if&lt;/code&gt; conditions for each of these inputs will be met and the error messages will be displayed.&lt;/p&gt;

&lt;p&gt;However, screen readers will not auto-read these error messages unless we tell them to. In order to make our users' experience better, let's auto focus the input that has the problem.&lt;/p&gt;

&lt;p&gt;First, we are going to have to go back into our form and add a &lt;code&gt;ref&lt;/code&gt; attribute to each of our inputs so that we can reference and target it inside our &lt;code&gt;submit()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit.prevent=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
          &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"firstNameError"&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
          &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
          &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
          &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$model"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt;
          &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$error"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstNameError"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is required&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
          &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"lastNameError"&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
          &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
          &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
          &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$model"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$error"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastNameError"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is required&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
          &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"emailError"&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;change=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$touch"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$error"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"emailError"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ email }} doesn't seem to be a valid email&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that I have named all the &lt;code&gt;ref&lt;/code&gt; attributes the same as their respective models. This will make the looping easier in the next step.&lt;/p&gt;

&lt;p&gt;Now that we can target the inputs, let's modify the &lt;code&gt;submit()&lt;/code&gt; method so we can loop through the different inputs and figure out which one has the error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;()&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;$v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$touch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if&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;$v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$invalid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Loop the keys&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&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;$v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// 2. Extract the input&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&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;$v&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
          &lt;span class="c1"&gt;// 3. Remove special properties&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

          &lt;span class="c1"&gt;// 4. Check for errors&lt;/span&gt;
          &lt;span class="k"&gt;if&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;$v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;$error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// 5. Focus the input with the error&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;$refs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// 6. Break out of the loop&lt;/span&gt;
            &lt;span class="k"&gt;break&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;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Submit the form here&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;Lots of code! But fear not, we're going to break this down into easy steps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First we create a &lt;code&gt;for&lt;/code&gt; loop to go through each of the properties in the &lt;code&gt;$v&lt;/code&gt; object. The &lt;code&gt;$v&lt;/code&gt; object contains several properties, between them you will find each of the inputs that are being validated - and also some special state properties like &lt;code&gt;$error&lt;/code&gt; and &lt;code&gt;$invalid&lt;/code&gt; for the whole form.&lt;/li&gt;
&lt;li&gt;We extract the input/property name into a variable for easy access&lt;/li&gt;
&lt;li&gt;We check if the input contains the &lt;code&gt;$&lt;/code&gt; character, if it does we skip this one because its a special data property and we don't care for it right now.&lt;/li&gt;
&lt;li&gt;We check the &lt;code&gt;$error&lt;/code&gt; state, if the &lt;code&gt;$error&lt;/code&gt; state is true, it means this particular input has a problem and one of the validations is failing.&lt;/li&gt;
&lt;li&gt;Finally, we use the name of the &lt;code&gt;input&lt;/code&gt; as a way to access it through the instance &lt;code&gt;$refs&lt;/code&gt;, and trigger the element's &lt;code&gt;focus&lt;/code&gt;. This is input → ref name relationship is why earlier we went with the same naming for the ref and the v-model state.&lt;/li&gt;
&lt;li&gt;We only want to focus the first element, so we call &lt;code&gt;break&lt;/code&gt; to stop the loop from continuing to execute.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Try this out, now when the user triggers the form's submit and there is an error the form will automatically focus the first input with an error. &lt;/p&gt;

&lt;p&gt;One more slight issue, the screen reader will still not read our custom error message. We need to tell it that this &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag describing the input is going to be a "live" area that will display information and that may change.&lt;/p&gt;

&lt;p&gt;In this case, we are going to add &lt;code&gt;aria-live="assertive"&lt;/code&gt; to our error messages. This way when they appear and our focus goes to the element, the screen reader will notify the users. It will also notify them if this message changes into something else, like from a &lt;code&gt;required&lt;/code&gt; validation error to a &lt;code&gt;minLength&lt;/code&gt; error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit.prevent=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
          &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"firstNameError"&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
          &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
          &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
          &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$model"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt;
          &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.firstName.$error"&lt;/span&gt;
          &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"assertive"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firstNameError"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is required&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
          &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"lastNameError"&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
          &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
          &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;
          &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$model"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.lastName.$error"&lt;/span&gt; &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"assertive"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"lastNameError"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is required&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
          &lt;span class="na"&gt;aria-describedby=&lt;/span&gt;&lt;span class="s"&gt;"emailError"&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
          &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;change=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$touch"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt;
          &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"$v.email.$error"&lt;/span&gt;
          &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"assertive"&lt;/span&gt;
          &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"emailError"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ email }} doesn't seem to be a valid email&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Auto focusing elements for the user when attempting to submit an invalid form is a very nice form of accessible UX that doesn't take a lot of effort and work on our side as developers. &lt;/p&gt;

&lt;p&gt;With the use of attributes like &lt;code&gt;aria-describedby&lt;/code&gt; and &lt;code&gt;aria-live&lt;/code&gt; we have already enhanced our form into an accessible state that most form out there in the wild wild web don't implement. This can also be enhanced futher of course, but this is a great starting point!&lt;/p&gt;

&lt;p&gt;If you want to see this example in action, I have set up a &lt;a href="https://codesandbox.io/s/vuelidate-error-focus-accessibility-6hibn"&gt;codesandbox here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As always, thanks for reading and share with me your accessible form experiences on twitter at: &lt;a href="https://twitter.com/marinamosti"&gt;@marinamosti&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;PS. All hail the magical avocado 🥑&lt;/p&gt;

&lt;p&gt;PPS. ❤️🔥🐶☠️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>a11y</category>
      <category>vuelidate</category>
    </item>
    <item>
      <title>How to target the DOM in Vue</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Thu, 21 Nov 2019 18:17:23 +0000</pubDate>
      <link>https://dev.to/marinamosti/how-to-target-the-dom-in-vue-l5j</link>
      <guid>https://dev.to/marinamosti/how-to-target-the-dom-in-vue-l5j</guid>
      <description>&lt;p&gt;This article as originally published at &lt;a href="https://www.telerik.com/blogs/how-to-target-the-dom-in-vue"&gt;https://www.telerik.com/blogs/how-to-target-the-dom-in-vue&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;A very common practice in web development is to be target an element in your DOM (Document Object Model) (aka all your HTML elements and the logical structure they represent) and to manipulate it in some way.&lt;/p&gt;

&lt;p&gt;In this article we are going to check out the power of &lt;code&gt;ref&lt;/code&gt; and some of its edge cases. Get your toast ready, and let's peel this 🥑.&lt;/p&gt;

&lt;h2&gt;
  
  
  Knights of the Old Vuepublic
&lt;/h2&gt;

&lt;p&gt;For those of us that come from the old ways, aka &lt;code&gt;jQuery&lt;/code&gt;, we were very used to targeting a DOM element in our page to modify it or use it in any certain way. In fact this was almost unavoidable in cases where you wanted to use any type of plugin that would make use of an element in your page.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;jQuery&lt;/code&gt;, you would select an element by targeting it with the &lt;code&gt;$()&lt;/code&gt;function, and that would open up a wide variety of methods for manipulating this object. Take the example of a &lt;code&gt;div&lt;/code&gt;, where you would like to set or toggle the visibility by switching around the &lt;code&gt;display&lt;/code&gt; css property.&lt;/p&gt;

&lt;p&gt;Let's consider the following markup for our example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"datOneDiv"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"myCoolClass"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: none;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;I is hidden&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;I is shown&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;I is 🐶&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;jQuery&lt;/code&gt;, this would look like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#datOneDiv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A couple of interesting things to mention here. First of all, notice that we're targeting a very specific &lt;code&gt;div&lt;/code&gt; in our document, the one with the &lt;code&gt;id&lt;/code&gt; of &lt;code&gt;datOneDiv&lt;/code&gt; as seen by the selector &lt;code&gt;#datOneDiv&lt;/code&gt; (the # here work just the same as a CSS selector, it denotes an id).&lt;/p&gt;

&lt;p&gt;The second thing to note is that as fantastically easy as this was, it prevents a lot of people from actually learning how to JavaScript, which as time go by became a problem. &lt;/p&gt;

&lt;p&gt;Do you even JS, breh? 😎💪&lt;/p&gt;

&lt;p&gt;In actual vanilla JavaScript, the same result can be achieved by using &lt;code&gt;querySelector&lt;/code&gt; and some property manipulation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#datOneDiv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The key thing to notice about this example is that once again, we are making use of an &lt;code&gt;id&lt;/code&gt; to target a very specific &lt;code&gt;div&lt;/code&gt; inside of our document. Granted, we could have also targeted the &lt;code&gt;div&lt;/code&gt; with its class by doing &lt;code&gt;.myCoolClass&lt;/code&gt;, but that as you will learn will present the same problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Vue awakens
&lt;/h2&gt;

&lt;p&gt;We are going to do some Sith killing today, don't worry no actual horned cool looking dudes were harmed in the making of this article.&lt;/p&gt;

&lt;p&gt;Consider the following Vue component &lt;code&gt;Sith.vue&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sithLord"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;I is Sith&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"keelItWithFire"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Kill the Sith DED!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script&amp;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;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;keelItWithFire&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.sithLord&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&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;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I KNOW, I KNOW. Amaga, I should be using dynamic classes, your example is so bad, the avocado is mad and you are no longer my bff. It's alright, I didn't like you anyway. However, for purposes of example let's pretend that we didn't know about all that Vue goodness and that we actually were trying to target the DOM this way to make some changes to it. (Jokes aside, if there is a way you can apply classes or styles dynamically, you should ALWAYS opt for doing it with dynamic properties! We are just doing this as an easy to follow example.)&lt;/p&gt;

&lt;p&gt;If we instantiate this component in our &lt;code&gt;App.vue&lt;/code&gt; or our main app entry point, and we click the button you will notice that it actually works. So why exactly have we been told time after time that it is SO BAD to target the DOM directly in Vue like we are doing here?&lt;/p&gt;

&lt;p&gt;Try modifying your main template (or wherever you're testing these components) to actually hold two or more Sith lords, like so.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Sith/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Sith/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now go ahead and click on the second one to kill it ded. HUH. The force is weak with this one. Do you know what happened?&lt;/p&gt;

&lt;p&gt;When the component method &lt;code&gt;keelItWithFire&lt;/code&gt; triggers on the second component, the &lt;code&gt;querySelector&lt;/code&gt; method is going through the DOM and trying to find the &lt;em&gt;first&lt;/em&gt; instance of an element with the class &lt;code&gt;sithLord&lt;/code&gt;, and sure enough it finds it!&lt;/p&gt;

&lt;p&gt;The big issue with targeting the DOM directly in Vue is first of all that components are meant to be reusable and dynamic, so we can not guarantee that the class here is going to be &lt;code&gt;unique&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Well, we can use an &lt;code&gt;id&lt;/code&gt; you see! And you are partially correct, assigning an &lt;code&gt;id&lt;/code&gt; attribute to a template in Vue will &lt;em&gt;sort of&lt;/em&gt; guarantee its uniqueness, proven that you don't instantiate more than a single one of those components in your whole application (else you're basically going to run into the same problem as above). &lt;/p&gt;

&lt;p&gt;The second caveat is that you will also have to guarantee that no other thing in your app, no other developer, and no other library is going to create an element that can potentially hold the same &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The way of the Vuedi
&lt;/h2&gt;

&lt;p&gt;Vue or do not, there is no try.&lt;/p&gt;

&lt;p&gt;In Vue we have plenty of tools to modify the template dynamically through computed properties, local state, dynamic bindings and more. But there will come a time where you will be faced with the need to actually target the DOM. A couple of common reasons are to implement an external party plugin that is not vue specific, or to target a field in a form and focus it, for example.&lt;/p&gt;

&lt;p&gt;When such a case arises, we have a pretty cool attribute we can slap to elements called &lt;code&gt;ref&lt;/code&gt;, you can check out the official documentation for it here &lt;a href="https://vuejs.org/v2/api/#ref"&gt;https://vuejs.org/v2/api/#ref&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are going to make a new component, this time a &lt;code&gt;Jedi.vue&lt;/code&gt; and this time we are going to do things as we are meant to in Vue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"jedi"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;I is Jedi&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"keelItWithFire"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Kill the Jedi DED!&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script&amp;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;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;keelItWithFire&lt;/span&gt;&lt;span class="p"&gt;()&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;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jedi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&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;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What, you thought because they were Jedi we weren't going to 🔥? Ain't no one mess with tiny hippo, ain't NO ONE 😠.&lt;/p&gt;

&lt;p&gt;Now, the important thing here is to understand what is going on when we add a &lt;code&gt;ref&lt;/code&gt; attribute to one of the elements on our &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;. In simple terms, each component instance will now hold a &lt;strong&gt;private reference&lt;/strong&gt; pointing to their own &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag, which we can target as seen on the &lt;code&gt;keelItWithFire&lt;/code&gt;function via the &lt;code&gt;$refs&lt;/code&gt; property of the instance.&lt;/p&gt;

&lt;p&gt;Other than the problems that arise with class and id targeting, it is of utmost importance to know that the biggest issue of all is that modifying DOM directly can lead to those changes being overwritten by Vue when there is a re-render cycle of the DOM either on that component or its parent.&lt;/p&gt;

&lt;p&gt;Since when we target the DOM directly Vue doesn't know about it, it won't update the virtual "copy" that it has stored - and when it has to rebuild, all those changes will be completely lost.&lt;/p&gt;

&lt;p&gt;If you don't want a certain piece of your DOM to constantly become re-rendered by Vue, you can apply the &lt;code&gt;v-once&lt;/code&gt; attribute to it, that way it will not try to re-render that specific part.&lt;/p&gt;

&lt;p&gt;So far this example doesn't seem super exciting but before we jump to a real case scenario, I want to touch up on some caveats.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caveat 1
&lt;/h3&gt;

&lt;p&gt;If you use &lt;code&gt;ref&lt;/code&gt; on top of a Vue component, such as &lt;code&gt;&amp;lt;Jedi ref="jedi"&amp;gt;&lt;/code&gt;, then what you get out of &lt;code&gt;this.$refs.jedi&lt;/code&gt; will be the component instance, not the &lt;code&gt;element&lt;/code&gt; as we are here with the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag. This means that you have access to all the cool Vue properties and methods, but also that you will have to access to the root  element of that component through &lt;code&gt;$el&lt;/code&gt; if you need to make direct DOM changes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Caveat 2
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;$refs&lt;/code&gt; are registered after the &lt;code&gt;render&lt;/code&gt;function of a component is executed. What this means is that you will NOT be able to use &lt;code&gt;$refs&lt;/code&gt;on hooks that happen before &lt;code&gt;render&lt;/code&gt; is called, for example on &lt;code&gt;created()&lt;/code&gt;, you will however have it available on &lt;code&gt;mounted()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is a way to &lt;em&gt;wait&lt;/em&gt; for &lt;code&gt;created()&lt;/code&gt; to have the elements available, and it is by leveraging the &lt;code&gt;this.$nextTick&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;What &lt;code&gt;this.$nextTick&lt;/code&gt; will do is that it will hold out on executing the function you pass to it until the next DOM update by Vue. &lt;/p&gt;

&lt;p&gt;Consider the following example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"myRef"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;No&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script&amp;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="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This doesn't exist yet!&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$nextTick&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if&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;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Now it does!&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;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;()&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;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🥑&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Now its mounted&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We have a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag with a &lt;code&gt;ref&lt;/code&gt; of &lt;code&gt;myRef&lt;/code&gt;, nothing fancy there. On the &lt;code&gt;created()&lt;/code&gt; hook though theres a couple of things going on.&lt;/p&gt;

&lt;p&gt;First, we make a check to see if &lt;code&gt;this.$refs.myRef&lt;/code&gt; is available to us, and as expect it will not be because the DOM has not yet being rendered at this point - so the console.log will be executed.&lt;/p&gt;

&lt;p&gt;After, we are setting an anonymous function to be called on &lt;code&gt;$nextTick&lt;/code&gt;, which will be executed after the DOM has had its next update cycle. Whenever this happens, we will log to the console "Now it does!".&lt;/p&gt;

&lt;p&gt;On the &lt;code&gt;mounted()&lt;/code&gt; hook, we actually use this &lt;code&gt;ref&lt;/code&gt; to change the inner text of the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag to something more worthwhile of our savior the magical avocado, and then we console log some more.&lt;/p&gt;

&lt;p&gt;Keep in mind that you will actually get the console logs in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This doesn't exist yet!&lt;/li&gt;
&lt;li&gt;Now its mounted&lt;/li&gt;
&lt;li&gt;Now it does!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;mounted()&lt;/code&gt; actually will fire before &lt;code&gt;nextTick&lt;/code&gt; because &lt;code&gt;nextTick&lt;/code&gt;happens at the end of the render cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dark side
&lt;/h2&gt;

&lt;p&gt;Well, now that you have all the awesome theory, what we can we actually do with this knowledge? Let's take a look at a common example, bringing in a third party library - &lt;code&gt;flatpickr&lt;/code&gt;, into one of our components. You can read more about &lt;code&gt;flatpickr&lt;/code&gt;here, &lt;a href="https://flatpickr.js.org/"&gt;https://flatpickr.js.org/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Consider the following component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"datepicker"&lt;/span&gt;
      &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;flatpickr&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;flatpickr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flatpickr/dist/themes/airbnb.css&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;mounted&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="nb"&gt;self&lt;/span&gt; &lt;span class="o"&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;flatpickr&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;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;datepicker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;single&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;dateFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YYYY-MM-DD HH:mm&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First, we import the library and some required styles, but then the package requires that we target a specific element in our DOM to attach itself to, we are using &lt;code&gt;ref&lt;/code&gt; here to point the library towards the correct &lt;code&gt;element&lt;/code&gt; with &lt;code&gt;this.$refs.datepicker&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This technique will work even for &lt;code&gt;jQuery&lt;/code&gt; plugins. &lt;/p&gt;

&lt;p&gt;But beware of the dark side. Angerlar, jFear, Reactgression; the dark side of the Force are they. (Disclaimer, this is a joke. I don't actually dislike the other frameworks. Except maybe jQuery, jQuery is evil.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Hope you had some fun learning about &lt;code&gt;ref&lt;/code&gt; today, it's a misunderstood and underused tool that will get you out of trouble when used in the right moment!&lt;/p&gt;

&lt;p&gt;The sandbox with the code examples used in this article can be found on the following link: &lt;a href="https://codesandbox.io/s/target-dom-in-vue-r9imj"&gt;https://codesandbox.io/s/target-dom-in-vue-r9imj&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As always, thanks for reading and share with me your ref experiences on twitter at: &lt;a href="https://twitter.com/marinamosti"&gt;@marinamosti&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;PS. All hail the magical avocado 🥑&lt;/p&gt;

&lt;p&gt;PSS. ❤️🔥🐶☠️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>dom</category>
    </item>
    <item>
      <title>Demystifying the v-model Directive in Vue</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Sat, 26 Oct 2019 16:16:33 +0000</pubDate>
      <link>https://dev.to/marinamosti/demystifying-the-v-model-directive-in-vue-3hdh</link>
      <guid>https://dev.to/marinamosti/demystifying-the-v-model-directive-in-vue-3hdh</guid>
      <description>&lt;p&gt;This post was originally published at &lt;a href="https://www.telerik.com/blogs/demystifying-the-v-model-directive-in-vue"&gt;https://www.telerik.com/blogs/demystifying-the-v-model-directive-in-vue&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;More often than not I get comments and messages asking me to go into detail about &lt;code&gt;v-model&lt;/code&gt; by people that have read an article or attended a workshop and the &lt;em&gt;magic&lt;/em&gt; of &lt;code&gt;v-model&lt;/code&gt; is touched on but not thoroughly explained.&lt;/p&gt;

&lt;p&gt;Today, we will go into detail on what exactly this directive does for us in Vue, and a top-level glance at how it works behind the scenes.&lt;/p&gt;

&lt;p&gt;This article is intended for novice and intermediate users who want to further their understanding of the directive, and I am assuming a general basic knowledge of Vue as a whole.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two-way binding and the basics
&lt;/h2&gt;

&lt;p&gt;Often times we find ourselves describing the &lt;code&gt;v-model&lt;/code&gt; directive as a magical entity that allows creating a two way biding to an input element. But what exactly does the two way binding mean? And why should you care?&lt;/p&gt;

&lt;p&gt;Vue and other frameworks like it have a bunch of &lt;em&gt;magical&lt;/em&gt; methods and ways of doing things, &lt;code&gt;v-model&lt;/code&gt; is a great example of this type of thing. &lt;/p&gt;

&lt;p&gt;The entry-level knowledge required to use it is minimal because frankly, you don't really NEED to understand how it works in order to use it - but when you fully grasp the concept behind it the &lt;em&gt;way&lt;/em&gt; you use it or think about it changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Listen to user input
&lt;/h2&gt;

&lt;p&gt;Let's start with a simple input element. It will be of type email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&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;The problem is simple, we need to be able to &lt;em&gt;know&lt;/em&gt; what the user types in here. We need to maybe send it to the back end for them to log the user in, or to capture it for a registration form.&lt;/p&gt;

&lt;p&gt;How would you approach this using jQuery or vanilla JS?&lt;/p&gt;

&lt;p&gt;In jQuery maybe you would add an &lt;code&gt;id&lt;/code&gt; attribute to the element, and target it directly to extract the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The problem with this approach is that you are stuck having to then add an event listener if you want to react to keystrokes because so far you are getting a static value at the moment the code is executed. It is NOT &lt;em&gt;reactive&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Let's try this again with an event listener and vanilla JS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// when the user types this will fire&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;doSomethingWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputValue&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;Alright, we're getting somewhere! So far we are able to call the function &lt;code&gt;doSomethingWith&lt;/code&gt; with the event's value (what the user typed). This seems like a lot of code though, and what happens if we have a form with 30 different inputs?&lt;/p&gt;

&lt;p&gt;Let's do it the Vue way. We are going to add an event listener to the input and call our fake &lt;code&gt;doSomethingWith&lt;/code&gt; function every time it fires.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;input=&lt;/span&gt;&lt;span class="s"&gt;"doSomethingWith"&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;I don't know about you, but this seems like magical avocado mischief to me. How does Vue accomplish the same thing behind the scenes?&lt;/p&gt;

&lt;p&gt;First of all, notice that we don't need an &lt;code&gt;id&lt;/code&gt; anymore. In fact, I would argue that using &lt;code&gt;id&lt;/code&gt; in Vue is a terrible idea! &lt;/p&gt;

&lt;p&gt;If you use ids in Vue, and you use the component in several places then you are going to have several instances of an element with the same id - which spells out CHAOS. &lt;/p&gt;

&lt;p&gt;Your developer avocado has gone bad, frand. GG. 🥑☠️&lt;/p&gt;

&lt;p&gt;Let's go back to our example though when we add &lt;code&gt;@input&lt;/code&gt; to our element, Vue is smart enough to attach the necessary event listener to this particular element via reference. It will also handle &lt;em&gt;removing&lt;/em&gt; this event listener for us!&lt;/p&gt;

&lt;p&gt;Finally, it will call the function that we passed inside the &lt;code&gt;" "&lt;/code&gt; whenever the event is fired, and it will pass it the &lt;code&gt;event&lt;/code&gt; object. Neat!&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing the input programmatically
&lt;/h2&gt;

&lt;p&gt;Let's move on to problem #2.&lt;/p&gt;

&lt;p&gt;You managed to listen to the events of the user making inputs on your field, good work! (Hopefully using Vue and not jQuery, come on. I am disappoint. ☹️)&lt;/p&gt;

&lt;p&gt;Now, part two of "two-way binding". What if we want to dynamically do something with the user's email and have the input reflect the change? &lt;/p&gt;

&lt;p&gt;Maybe we have some sort of form autocomplete, or validation, or we have another input element that will prepopulate their name from the database. There's a lot of possible scenarios.&lt;/p&gt;

&lt;p&gt;Let's approach this problem with jQuery first. 🤢&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is the value we are storing somewhere&lt;/span&gt;
&lt;span class="c1"&gt;// So that later we can send it to the backend&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;somevalue@theuserentered.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;userEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Now what if we want to change the email on the input programmatically?&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;changeEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newEmail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newEmail&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;userEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newEmail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;changeEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-email@is-wrong.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can see from this last example how quickly this can start to get really messy. Monolithic files of jQuery for event handling and input validation are a thing of the past!&lt;/p&gt;

&lt;p&gt;You can also appreciate how it's going to be a problem keeping a &lt;code&gt;state&lt;/code&gt;. We have a high-level variable &lt;code&gt;userEmail&lt;/code&gt; that is keeping the value, and we have to be careful that we are orderly about our code. Now do this 40 times for a big form, please.&lt;/p&gt;

&lt;p&gt;One thing that you may have also not considered at this point is that we are trying to be really careful about setting the &lt;code&gt;.val&lt;/code&gt; of our input when we change it on the &lt;code&gt;changeEmail&lt;/code&gt; function. But what if another dev, or even ourselves make another function that modifies the &lt;code&gt;userEmail&lt;/code&gt; variable somewhere else?&lt;/p&gt;

&lt;p&gt;We have to keep in mind that every time this variable changes the input has to be updated, or we have to get into some rather advanced javascript that will set up getters and setters for us to fix that reactivity problem.&lt;/p&gt;

&lt;p&gt;Let's approach this second problem in Vue. We are going to create first a local state in our make-believe component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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;email&lt;/span&gt;&lt;span class="p"&gt;:&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now that we have our local state, we have to tell the input to use it and bind it to the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; 
  &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; 
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;input=&lt;/span&gt;&lt;span class="s"&gt;"doSomethingWith"&lt;/span&gt;  
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&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;doSomethingWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Do other stuff, eat avocados, play zelda and admire a raccoon&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;That's it! Every time the &lt;code&gt;email&lt;/code&gt; state changes, the input will be updated accordingly. We now have two ways of binding to the input.&lt;/p&gt;

&lt;p&gt;First, when our local state changes. Second, when the user types on the field, the &lt;code&gt;input&lt;/code&gt; listener will update the &lt;code&gt;state&lt;/code&gt; with the value. When the state updates, it will update the input. &lt;/p&gt;

&lt;p&gt;Do you see the cycle? DO YA?&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter v-model
&lt;/h2&gt;

&lt;p&gt;The kind folks at the Vue realized that this pattern of adding two one-way bindings, one that feeds &lt;em&gt;into&lt;/em&gt; the input, and one that feeds &lt;em&gt;out&lt;/em&gt; of the input was very common when dealing with forms and user data.&lt;/p&gt;

&lt;p&gt;Thus, the magical avocado and the &lt;code&gt;v-model&lt;/code&gt; directive were born. Both were cared for and nurtured, and the magical avocado went bad throughout the night and we had to toss it out. But such is life.&lt;/p&gt;

&lt;p&gt;What happens then when you have to two-way bind your inputs, do you have to go through this double process where you bind the &lt;code&gt;:input&lt;/code&gt; to some sort of state, and then listen to an event and re-write all the state?&lt;/p&gt;

&lt;p&gt;The answer is no! &lt;code&gt;v-model&lt;/code&gt; your friendly neighborhood avocado to the rescue.&lt;/p&gt;

&lt;p&gt;We currently have this for our form input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; 
  &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; 
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;input=&lt;/span&gt;&lt;span class="s"&gt;"doSomethingWith"&lt;/span&gt;  
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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;email&lt;/span&gt;&lt;span class="p"&gt;:&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;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;doSomethingWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Do other stuff, eat avocados, play zelda and admire a raccoon&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;And with the power invested in me by Vue, and the blessing of captain planet (yes, I'm old), we can make it all nice and simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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;email&lt;/span&gt;&lt;span class="p"&gt;:&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it! &lt;code&gt;v-model&lt;/code&gt; will make sure that the correct event is being listened to (in the case of native elements like inputs, selects, etc.) and then bind our local &lt;code&gt;email&lt;/code&gt; data property to it! Ah-two, ah-way, ah-binding. 👌&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Keep in mind, &lt;code&gt;v-model&lt;/code&gt; has some caveats regarding which property it has to bind to and which event it has to listen to.&lt;/p&gt;

&lt;p&gt;Vue is super smart regarding this behind the scenes when being used on inputs, selects, checkboxes and radio buttons - but when you are working with custom components you are going to have to do this heavy lifting yourself.&lt;/p&gt;

&lt;p&gt;This, however, is out of the scope of this beginner article. But you can check out this reference on &lt;code&gt;v-model&lt;/code&gt; on custom components on the &lt;a href="https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components"&gt;official documentation&lt;/a&gt;, or the last part of my &lt;a href="https://dev.to/vuevixens/hands-on-vuejs-for-beginners-part-7-3e1c"&gt;Vue for Beginners Series&lt;/a&gt; where I touch up on a little about &lt;code&gt;v-model&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As always, thanks for reading and share with me your experiences with v-model on twitter at: &lt;a href="http://www.twitter.com/marinamosti"&gt;@marinamosti&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS. All hail the magical avocado 🥑&lt;/p&gt;

&lt;p&gt;PSS. ❤️🔥🐶☠️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vmodel</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>In Vue, when do I actually need the :key attribute and why?</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Mon, 14 Oct 2019 07:13:08 +0000</pubDate>
      <link>https://dev.to/marinamosti/in-vue-when-do-i-actually-need-the-key-attribute-and-why-ga5</link>
      <guid>https://dev.to/marinamosti/in-vue-when-do-i-actually-need-the-key-attribute-and-why-ga5</guid>
      <description>&lt;p&gt;This article was originally published at &lt;a href="https://www.telerik.com/blogs/in-vue-when-do-i-actually-need-the-key-attribute-and-why"&gt;https://www.telerik.com/blogs/in-vue-when-do-i-actually-need-the-key-attribute-and-why&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;So you find yourself writing a Vue app. Maybe you are using the amazing &lt;a href="https://cli.vuejs.org"&gt;Vue CLI 3&lt;/a&gt;, and got yourself a nice set up that gives you some eslint errors and hints.&lt;/p&gt;

&lt;p&gt;All of a sudden you are minding your own business, eating your avocado toast and morning &lt;em&gt;latte&lt;/em&gt; and the squiggly lines catch your attention. That last &lt;code&gt;v-for&lt;/code&gt; loop seems to be &lt;strong&gt;wrong&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Maybe you decide to ignore it and to carry on with your avocado induced nirvana but then it strikes you one more time. Console errors 🚧. You panic a little, Vue is demanding it. &lt;code&gt;:key&lt;/code&gt; has not been set.&lt;/p&gt;

&lt;p&gt;You give in to your instincts and add a &lt;code&gt;:key&lt;/code&gt; based on the array's loop, you know it has to be unique. Sweet relief, the errors are gone and you can move on seeking the betterment of humanity through javascript.&lt;/p&gt;

&lt;p&gt;Except, what exactly does this all even mean? And why should you care?&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the basics of &lt;code&gt;:key&lt;/code&gt; 🔑
&lt;/h2&gt;

&lt;p&gt;As suggested by &lt;a href="https://vuejs.org/v2/api/#key"&gt;the official docs&lt;/a&gt; the &lt;code&gt;key&lt;/code&gt; special attribute is used by Vue as a &lt;em&gt;hint&lt;/em&gt; for it to understand what exactly it is you're trying to accomplish.&lt;/p&gt;

&lt;p&gt;But what exactly does it mean to say that it is only a &lt;em&gt;hint&lt;/em&gt;? Vue is &lt;strong&gt;smart&lt;/strong&gt;. If you don't add the &lt;code&gt;:key&lt;/code&gt; attribute to your &lt;code&gt;v-for&lt;/code&gt; loop the app will not come crashing down on itself in fiery wrath. It is not actually even &lt;em&gt;required&lt;/em&gt; that you add it.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;:key&lt;/code&gt; is missing, Vue will use internal functions or algorithms to try to figure out the best way to avoid moving DOM elements around. Less movement means less re-rendering and better performance.&lt;/p&gt;

&lt;p&gt;This process, however, has the faults of being generic and automated, and even though it is &lt;em&gt;GOOD&lt;/em&gt; at its job - you, the programmer 💻, will probably know better on how the performance and DOM manipulation should happen. This implies that you understand the attribute in order to actually get the desired outcome.&lt;/p&gt;

&lt;p&gt;So why do we get &lt;em&gt;eslint&lt;/em&gt; warnings and console warnings? ⚠️&lt;/p&gt;

&lt;p&gt;There are particular cases where the use of &lt;code&gt;key&lt;/code&gt; is &lt;em&gt;vital&lt;/em&gt;, either to provide data consistency and not lose values (for example in forms) or to attain object constancy in animations. More on these later.&lt;/p&gt;

&lt;p&gt;My personal suggestion, in this case, is that you continue to use it in every case, but, with a better understanding of &lt;em&gt;what&lt;/em&gt; it will accomplish and &lt;em&gt;why&lt;/em&gt; you need to add it.&lt;/p&gt;

&lt;p&gt;Let's talk specifics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preserving state
&lt;/h2&gt;

&lt;p&gt;When working with HTML elements that have a &lt;em&gt;state&lt;/em&gt; in our &lt;code&gt;v-for&lt;/code&gt; loops we have to be careful that that state does not get destroyed when the DOM is re-rendered.&lt;/p&gt;

&lt;p&gt;Elements like &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; all hold an internal state that captures the &lt;code&gt;value&lt;/code&gt; of that element. When Vue's virtual DOM is modified because our reactive data changed, we can have cases where the DOM that holds our looped elements can be completely or partially destroyed if the &lt;code&gt;key&lt;/code&gt; is not properly set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Wrong --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"input in myForm"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Right --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"input in myForm"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"unique-condition"&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;This problem will lead to a situation VERY hard to debug if you don't know exactly what you are looking for, because it may simply "look" like there's a problem with how the data you are gathering from the form is being magically deleted.&lt;/p&gt;

&lt;p&gt;This same case applies to looping through elements that make use of the &lt;code&gt;v-html&lt;/code&gt; directive. The &lt;code&gt;key&lt;/code&gt; property will assist Vue in making a better job of recognizing each element on the list, and not destroying elements potentially that could hold elements with a state within them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Wrong --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-html=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;input /&amp;gt;"&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"item in items"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Right --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-html=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;input /&amp;gt;"&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"item in items"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"unique-condition"&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;This of course also applies to looping custom made components that hold state, the same rule of thumb applies. If the &lt;code&gt;key&lt;/code&gt; is not defined, you are at risk of data and state being destroyed due to a re-render of the DOM.&lt;/p&gt;

&lt;p&gt;Finally, keep an eye out for &lt;code&gt;v-for&lt;/code&gt; loops that cycle on an element that contains a stateful element WITHIN it. The same problem can obviously occur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Wrong --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"item in items"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Right --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"item in items"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"unique-condition"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Object Constancy
&lt;/h2&gt;

&lt;p&gt;Animations are not just a pretty way to move data around 🎬, they convey important information to our users of what is happening to the information they are looking at. When an object moves around the screen, slides, or fades, we expect that object to be consistent and easy to track as it conveys the information it’s trying to show us.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wait, what?
&lt;/h3&gt;

&lt;p&gt;Imagine a mobile menu sliding in from the left 📲 after you’ve touched on a hamburger 🍔 icon (🤔 We have hamburger and kebab menus, let's make 🥑 menu happen team!). &lt;/p&gt;

&lt;p&gt;It transitions smoothly into halfway through the screen and clearly displays the options that you, the user, has for navigating the webpage. However, when you touch on one of the menu items, the menu magically snaps to the right side of the screen and disappears to the right hand of the phone.&lt;/p&gt;

&lt;p&gt;Confused, you tap the hamburger icon and the menu reappears from the left side of the screen once again. 🤷‍&lt;/p&gt;

&lt;p&gt;This is a great example of a lack of object constancy. We expect the virtual object of the menu to be “hidden” on the same side of our phone, and that it “slides in” to the viewport when we press the button. When this animation is not consistent or clear, it creates a bad user experience and also causes problems tracking the information.&lt;/p&gt;

&lt;p&gt;This is a VERY simple example, but what happens when we take it a step further and have a list of items that are trying to convey for example some charted data, or a todo list. When one of those items slides to the left or fades out, we expect THAT item to disappear. If for some unknown reason to the user, the object magically disappeared, and then another one slid to the left it would create confusion and the animation -  rather than serving a strong visual cue, it would create discomfort and confusion.&lt;/p&gt;

&lt;h3&gt;
  
  
  A real-world example
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Talk is cheap. Show me the code. - Linus Torvalds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve created a simplified example of the last user interaction that I described so that you can see it in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/s/jjlwv87w1v"&gt;https://codesandbox.io/s/jjlwv87w1v&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open up the Sandbox, and look at the &lt;code&gt;App.vue&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;We have two lists of items been fed by the same pool of data, a property called &lt;code&gt;list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the top list, we create a &lt;code&gt;v-for&lt;/code&gt; loop that is using the unique &lt;code&gt;id&lt;/code&gt; property of each item as a way to track the uniqueness of each of the list items - as usually suggested by the compiler, and to increase DOM performance.&lt;/p&gt;

&lt;p&gt;On the bottom list, we are using a common “&lt;em&gt;hack&lt;/em&gt;“, to use the array’s &lt;code&gt;index&lt;/code&gt; as a way to loop our items and satisfy the &lt;code&gt;:key&lt;/code&gt; warning.&lt;/p&gt;

&lt;p&gt;I’m not going to touch deeply on the DOM implications of using the &lt;code&gt;index&lt;/code&gt; as a key, for it can &lt;em&gt;sometimes&lt;/em&gt; be the correct answer if you know exactly what you are doing regarding index management. But instead, let’s focus on the implications it has for UX.&lt;/p&gt;

&lt;p&gt;Both lists are wrapped inside a &lt;code&gt;&amp;lt;group-transition&amp;gt;&lt;/code&gt; component that will allow us to visually identify what is happening. Go ahead and play around with the top list, click around a few objects, and then hit the &lt;code&gt;reset&lt;/code&gt; button. Smooth, right? The object you click is the one that is sliding away. Mission accomplished.&lt;/p&gt;

&lt;p&gt;Go ahead and click around the second list now. I don’t know about you, but to me, this seems bugged.&lt;/p&gt;

&lt;p&gt;Chris Fritz has an amazing example of how fluid animations can give you an intuitive user experience. Be sure to check it out &lt;a href="https://jsfiddle.net/chrisvfritz/sLrhk1bc/"&gt;in this fiddle&lt;/a&gt;. Also, try playing around with the &lt;code&gt;:key&lt;/code&gt;, if you break the system then the numbers will simply stop animating.&lt;/p&gt;

&lt;p&gt;Keep in mind for this last example that &lt;code&gt;&amp;lt;group-transition&amp;gt;&lt;/code&gt; actually throws a warning if you remove &lt;code&gt;key&lt;/code&gt;, and also the rendering will completely break.&lt;/p&gt;

&lt;p&gt;Try adding an index to the &lt;code&gt;v-for&lt;/code&gt; loop and setting it as the value for the &lt;code&gt;:key&lt;/code&gt;, as some people do to "satisfy" the condition and remove the warning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Breaking things apart
&lt;/h3&gt;

&lt;p&gt;What exactly is happening here that breaks our &lt;em&gt;object constancy&lt;/em&gt; in the second example? 🔎&lt;/p&gt;

&lt;p&gt;When we click on one of the items to trigger the &lt;code&gt;removeFromList&lt;/code&gt; method, Vue does a couple of things on the background. First of all, the method updates the &lt;code&gt;array&lt;/code&gt; that holds our &lt;code&gt;list&lt;/code&gt; by calling the &lt;code&gt;splice&lt;/code&gt; method on the &lt;code&gt;item&lt;/code&gt;'s index.&lt;/p&gt;

&lt;p&gt;Once the &lt;code&gt;list&lt;/code&gt; 📝 has been updated however, Vue has to re-render the DOM in order to &lt;em&gt;react&lt;/em&gt; to the changes in the state, this is the core of Vue's reactivity.&lt;/p&gt;

&lt;p&gt;Usually, Vue would know that for a &lt;code&gt;v-for&lt;/code&gt; loop, it needs to figure out which element it needs to update via the &lt;code&gt;key&lt;/code&gt;, this is what you already know. However, because of the &lt;code&gt;&amp;lt;transition-group&amp;gt;&lt;/code&gt; Vue keeps a partial state copy to perform the animations while the elements get removed from the screen, &lt;strong&gt;even though&lt;/strong&gt; this element doesn't exist any longer on the actual component's &lt;code&gt;state&lt;/code&gt;.&lt;br&gt;
When we use &lt;code&gt;:key&lt;/code&gt; with the object's id on the first example, Vue has an &lt;em&gt;exact&lt;/em&gt; reference to what we are trying to accomplish, because this particular &lt;code&gt;item&lt;/code&gt; has a &lt;em&gt;unique&lt;/em&gt; way to identify itself. So when Vue needs to remove it, both from the state, and from the animation it can tell exactly which one it needs to work with.&lt;/p&gt;

&lt;p&gt;When we use &lt;code&gt;:key&lt;/code&gt; with the index however, we run into a problem. Remember the step by step we just went through? Let's try that again but let's take a closer look at what the index is doing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We click on an item - let's use &lt;code&gt;id&lt;/code&gt; 2 as an example.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;removeFromList&lt;/code&gt; method finds that the index of this item is actually &lt;code&gt;1&lt;/code&gt; and promptly removes this item from the array.&lt;/li&gt;
&lt;li&gt;Vue knows it has to do some DOM re-rendering because the &lt;code&gt;list&lt;/code&gt; got updated, and tries its best to figure out which items it has to redraw on the screen. So it starts with index &lt;code&gt;1&lt;/code&gt; (cycling the array), looks like that didn't change. It goes on to index &lt;code&gt;1&lt;/code&gt; and notices the content is different (what was in index 2 now is in index 1, because splice moved it all one space down). Then goes on to index &lt;code&gt;2&lt;/code&gt; and the same problem occurs, and so on. Vue effectively re-render the who list.&lt;/li&gt;
&lt;li&gt;On the other hand, &lt;code&gt;&amp;lt;transition-group&amp;gt;&lt;/code&gt; is trying its best to catch up with the DOM changing and the &lt;code&gt;state&lt;/code&gt; getting modified, and in its best attempt it "copies" the deleted item into the end of the list and animates it leaving the screen. It has &lt;em&gt;no&lt;/em&gt; way to know how to re-order its internal state to accommodate for the index changes in the state.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;key&lt;/code&gt; attribute has a lot more under the hood than it appears. Now that you understand exactly what it is trying to accomplish, and the reasons behind the "magic", you can make better calls when developing your loops - and obtain more granular control over your application and how it performs. 💪&lt;/p&gt;

&lt;p&gt;As always, thanks for reading and share with me your thoughts on Twitter at &lt;a href="https://twitter.com/marinamosti"&gt;@marinamosti&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;PS. All hail the magical avocado 🥑&lt;/p&gt;

&lt;p&gt;PSS. ❤️🔥🐶☠️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>key</category>
      <category>javascript</category>
    </item>
    <item>
      <title>So what actually is Vue.set?</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Wed, 09 Oct 2019 04:58:45 +0000</pubDate>
      <link>https://dev.to/marinamosti/so-what-actually-is-vue-set-5afi</link>
      <guid>https://dev.to/marinamosti/so-what-actually-is-vue-set-5afi</guid>
      <description>&lt;p&gt;This article was originally published at &lt;a href="https://www.telerik.com/blogs/so-what-actually-is-vue-set"&gt;https://www.telerik.com/blogs/so-what-actually-is-vue-set&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Talking about &lt;code&gt;Vue.set&lt;/code&gt; is talking about reactivity, so prepare yourself for some theory on this one. However, as always, it doesn't need to be something hard or boring. Find your avocados and chips, make some guacamole, and let's dip right in.&lt;/p&gt;

&lt;h1&gt;
  
  
  Data and Reactivity
&lt;/h1&gt;

&lt;p&gt;Whenever you create a &lt;code&gt;data()&lt;/code&gt; property function inside a Vue component, and return the object back, Vue does a lot of things behind the scenes to hook everything up inside your component and to make it reactive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;chili&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;peppers&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first thing that Vue will do here with our awesome awesome awesome RHCP data, is walk through each of the &lt;code&gt;properties&lt;/code&gt; of the &lt;code&gt;return { }&lt;/code&gt; object, and create a unique &lt;code&gt;getter&lt;/code&gt; and &lt;code&gt;setter&lt;/code&gt; for each one. The nitty gritty of how this actually happens is beyond the scope of this article, but &lt;a href="https://www.vuemastery.com/courses/advanced-components/build-a-reactivity-system"&gt;Vue Mastery&lt;/a&gt; has a very nice video explaining this in detail.&lt;/p&gt;

&lt;p&gt;The purpose of creating these is so that when you access these properties inside your code, by doing &lt;code&gt;this.red&lt;/code&gt; for example, or when setting them with &lt;code&gt;this.red = "hotter"&lt;/code&gt; you are actually calling these &lt;code&gt;getters&lt;/code&gt; and &lt;code&gt;setters&lt;/code&gt; that Vue created for you.&lt;/p&gt;

&lt;p&gt;Inside this magical land of SETGET, Vue hooks up your computer properties, watchers, props, data, etc. to become &lt;code&gt;reactive&lt;/code&gt;, in super simple terms, a function is called that updates the whole shebang every time the setter is changed.&lt;/p&gt;

&lt;h1&gt;
  
  
  The pitfall
&lt;/h1&gt;

&lt;p&gt;Awesome! This is what we love about Vue right, its amazing reactivity and under-the-hood power. But there is a dark side here that needs to explored.&lt;/p&gt;

&lt;p&gt;Let's change our data a little bit and see what happens when we start trying to work with dynamic data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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;members&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;Alright, nothing fancy so far, we have a &lt;code&gt;members&lt;/code&gt; property of our data into which we want to add band member information. Now for the sake of example, let's add a method that will pretend to pull some information from a remote http call, that will give us back a JSON object with the band info.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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;members&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;span class="nx"&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;getMembers&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;newMember&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Flea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bass&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;baeLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A++&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Some magical method that gives us data got us this sweet info&lt;/span&gt;

   &lt;span class="c1"&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;Hm. Ok, so looking at this example let's stop and think. There are many ways to resolve this current dilema, how do we add this &lt;code&gt;newMember&lt;/code&gt; object into our current &lt;code&gt;members&lt;/code&gt; property?&lt;/p&gt;

&lt;p&gt;Maybe you're thinking let's turn &lt;code&gt;members&lt;/code&gt; into an array and &lt;code&gt;push&lt;/code&gt; it, sure, but that's cheating because it breaks my CAREFULLY constructed example that I didn't just make up as I was typing this.&lt;/p&gt;

&lt;p&gt;In this scenario, we NEED to have &lt;code&gt;members&lt;/code&gt; as an object. Ok, simple - you'd say, let's just add a new property to the &lt;code&gt;members&lt;/code&gt; property, it's an object after all. In fact, let's go ahead and make the member's name the name of the property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;getMembers&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;newMember&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Flea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bass&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;baeLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A++&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// Totally important property that we will never use&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Some magical method that gives us data got us this sweet info&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;members&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;newMember&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newMember&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;Lok'tar Ogar!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Cs5PBOnbE7MU8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Cs5PBOnbE7MU8/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Except, no, because A. this is not Orgrimmar and B. we now have a problem.&lt;/p&gt;

&lt;p&gt;If you were to run this code on your browser and test it right now, you will see that you are actually pushing this new data into the &lt;code&gt;members&lt;/code&gt; data, but this change to the component state will not actually make any of your application re-render.&lt;/p&gt;

&lt;p&gt;In a scenario where you are just using this data for some computation, or for some type of internal storage then doing things this way won't impact your application - however, and this is a huge HOWEVER, if you are using this data reactively on your app to display some information on your page, or for conditional rendering with &lt;code&gt;v-if&lt;/code&gt; or &lt;code&gt;v-else&lt;/code&gt; then things are going to get funky.&lt;/p&gt;

&lt;h1&gt;
  
  
  Actually using Vue.set
&lt;/h1&gt;

&lt;p&gt;So now that we understand where the problem is actually coming from, we can learn what is the proper solution. Allow me to introduce you to &lt;code&gt;Vue.set&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Vue.set&lt;/code&gt; is a tool that allows us to add a new property to an already reactive object, and makes sure that this new property is ALSO reactive. This completely takes care of the problem that we were experiencing on the other example, because when our new property on &lt;code&gt;members&lt;/code&gt; gets set, it will automatically be hooked into Vue's reactivity system, with all the cool getters/setters and Vue-magic behind the scenes.&lt;/p&gt;

&lt;p&gt;A small note is however required to understand how this affects arrays. So far we have only really played around with objects, which are super easy to understand. New prop? Add it with Vue.set if you want it to be reactive. Simple.&lt;/p&gt;

&lt;p&gt;Following up with our example, let's switch things up to use &lt;code&gt;Vue.set&lt;/code&gt; instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;getMembers&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;newMember&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Flea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bass&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;baeLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A++&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Some magical method that gives us data got us this sweet info&lt;/span&gt;

   &lt;span class="c1"&gt;//this.members[newMember.name] = newMember;&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;$set&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;members&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newMember&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newMember&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;This bit is new &lt;code&gt;this.$set(this.members, newMember.name, newMember);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There's two things I want to mention for this piece of code. I've been telling you so far that &lt;code&gt;Vue.set&lt;/code&gt; is how we are going to be doing things, but now im using &lt;code&gt;this.$set&lt;/code&gt;, but fear not - this is only an alias, so it will do and behave in the exact same way. The cool thing, is that you don't have to import Vue inside your components to use it.&lt;/p&gt;

&lt;p&gt;The second thing I want to make note of is the syntax of this function. It takes three paramters, the &lt;code&gt;object&lt;/code&gt; or &lt;code&gt;array&lt;/code&gt; which we are going to modify (in this case &lt;code&gt;this.members&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;A second paramter which points to the &lt;code&gt;property&lt;/code&gt; or &lt;code&gt;key&lt;/code&gt; of the first object/array that we passed (so &lt;code&gt;newMember.name&lt;/code&gt; because we want it to be dynamic).&lt;/p&gt;

&lt;p&gt;And finally a third paramter which is the value we want to set into it. (In our case, &lt;code&gt;newMember&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;         &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;members&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;newMember&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newMember&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//            V               V              V&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;$set&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;members&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newMember&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="nx"&gt;newMember&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(PS. My ASCII skills are not for sale ^)&lt;/p&gt;

&lt;p&gt;But what's up with array reactivity?&lt;/p&gt;

&lt;p&gt;When we create an &lt;code&gt;array&lt;/code&gt; inside the initial state, Vue sets it up to be reactive for us, however Vue is unable to currently detect when you directly assign a value using an index. For example, if we were doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;membersArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myNewValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then Vue won't be able to detect this change, and thus it would not be reactive. Please keep in mind that if you modify arrays with operations like &lt;code&gt;pop&lt;/code&gt;, &lt;code&gt;splice&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt; then those operations WILL trigger reactivity on the arrays, so you can safely use those.&lt;/p&gt;

&lt;p&gt;In the off case that you need to set an index value directly, we have &lt;code&gt;Vue.set&lt;/code&gt; to help us out. Let's see how that would look on our previous example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$set&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;membersArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myNewValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you want to read more about all the reactivity caveats check out this &lt;a href="https://vuejs.org/v2/guide/list.html#Caveats"&gt;link to the official documentation&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Vue 3.0
&lt;/h1&gt;

&lt;p&gt;This is all still subject to change at the time of this writing, but the word on the street is that these caveats will no longer be an issue. In other words, in Vue 3.0 you will be safe to forget about these edge cases completely, with the exception of those poor souls that still have to target some old browsers that will not fully support the new reactivity system.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>A first look at the Vue CLI</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Mon, 23 Sep 2019 15:24:41 +0000</pubDate>
      <link>https://dev.to/marinamosti/a-first-look-at-the-vue-cli-380c</link>
      <guid>https://dev.to/marinamosti/a-first-look-at-the-vue-cli-380c</guid>
      <description>&lt;p&gt;This article was originally published at &lt;a href="https://www.telerik.com/blogs/a-first-look-at-the-vue-cli" rel="noopener noreferrer"&gt;https://www.telerik.com/blogs/a-first-look-at-the-vue-cli&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Hello again! 😃&lt;/p&gt;

&lt;p&gt;I've recently completed a &lt;a href="https://dev.to/vuevixens/hands-on-vuejs-for-beginners-part-1-2j2g"&gt;beginners tutorial series for Vue.JS&lt;/a&gt; (shameless self promotion, sorry 😅), in which we went over all the basics of how &lt;strong&gt;Vue&lt;/strong&gt; works. &lt;/p&gt;

&lt;p&gt;However, we only looked at &lt;strong&gt;Vue&lt;/strong&gt; from the perspective of adding a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag to a static HTML file and setting it up directly on the page's JS.&lt;/p&gt;

&lt;p&gt;It's time to graduate to the big girl tools, and to look at one of the most pleasurable aspects of working with &lt;strong&gt;Vue&lt;/strong&gt; - the CLI (Command Line Interface).&lt;/p&gt;

&lt;p&gt;Fear not, it's super easy!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sadly, for this tutorial i'm going to have to assume that you have a little knowledge of how to navigate inside the terminal with basic &lt;code&gt;cd&lt;/code&gt; commands, because this is way out of scope of what Vue CLI is or does. The &lt;code&gt;cd&lt;/code&gt; command is super basic though, and you can easily google for a video or quick tutorial if you need a refresher &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Getting set up
&lt;/h1&gt;

&lt;p&gt;There's a couple of things that we need to get set up in your computer before we begin. Feel free to skip over some of these if you already have them, but be super careful that you're not skipping over something vital.&lt;/p&gt;

&lt;h2&gt;
  
  
  NodeJS
&lt;/h2&gt;

&lt;p&gt;In order to get the CLI working on our system, we're going to need to install Node first, particularly at the time in writing this we need to have at least version &lt;strong&gt;8.9&lt;/strong&gt; but &lt;strong&gt;8.11+&lt;/strong&gt; is recommended.&lt;/p&gt;

&lt;p&gt;If you've installed Node before, but are unsure of which version you're using, open up your terminal and run the following command &lt;code&gt;node -v&lt;/code&gt;. You should get an output like &lt;code&gt;v11.9.0&lt;/code&gt;, if you get an error then you probably don't have Node installed on your machine.&lt;/p&gt;

&lt;p&gt;Head over to the official page for node &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;https://nodejs.org/en/&lt;/a&gt; and on the very homepage you'll see two green buttons for downloading. Go ahead and click on the version that says &lt;code&gt;LTS&lt;/code&gt; (Long term support) unless you know what you're doing and wanting the latest version.&lt;/p&gt;

&lt;p&gt;You will get a download for your current operating system, double click it and go through the installation wizard. Once you're done, fire up the terminal once again and try running &lt;code&gt;node -v&lt;/code&gt; once more to check that everything is working.&lt;/p&gt;

&lt;p&gt;One more thing, when installing Node you also get &lt;code&gt;NPM&lt;/code&gt; (Node package manager) installed on your computer for free! We're going to be using this later, so just keep that in mind in case you wonder where this came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yarn (Optional)
&lt;/h2&gt;

&lt;p&gt;Some people prefer to use &lt;code&gt;yarn&lt;/code&gt; over &lt;code&gt;npm&lt;/code&gt; as their choice of package manager, personally I don't have a preference and will use both depending on the project and the team's requirements - but if you want to take it for a go just head over to &lt;a href="https://yarnpkg.com/en/" rel="noopener noreferrer"&gt;https://yarnpkg.com/en/&lt;/a&gt; and click on the &lt;code&gt;Install Yarn&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;Once again, download the file and follow the install wizard. Once it's done, you can check that &lt;code&gt;yarn&lt;/code&gt; was correctly added to your machine by running &lt;code&gt;yarn -v&lt;/code&gt; on your terminal. &lt;/p&gt;

&lt;h1&gt;
  
  
  Installing the CLI
&lt;/h1&gt;

&lt;p&gt;Sweet! Now that we have all that we need, we can actually go ahead and install the &lt;strong&gt;Vue CLI&lt;/strong&gt; on our computer.&lt;/p&gt;

&lt;p&gt;Open up your terminal, and run the following command. (Note, that i'm going to be showing both NPM and YARN commands, you don't have to run both - pick the one that you want to use and that you have installed from the previous section).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @vue/cli

yarn global add @vue/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run this command in your terminal, it's going to execute a handful of scripts and you're going to get some very cryptic output. Don't worry about this, go get yourself some coffee and wait until it's done installing everything.&lt;/p&gt;

&lt;p&gt;Note the &lt;code&gt;-g&lt;/code&gt; and &lt;code&gt;global&lt;/code&gt; flags on both of these commands, what this means is that you're installing this package &lt;code&gt;globally&lt;/code&gt; on your computer. In short, this means that you will be able to use the commands from anywhere inside your filesystem, without having to navigate to a specific folder.&lt;/p&gt;

&lt;p&gt;Once more, let's check that everything was installed properly by running &lt;code&gt;vue --version&lt;/code&gt; on the terminal, you should get output back with the version number of the CLI.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating our first project
&lt;/h1&gt;

&lt;p&gt;It's time to get our hands dirty and actually use this thing. Fire up your terminal if you haven't already and navigate to the folder in which you want to create your project.&lt;/p&gt;

&lt;p&gt;The command you want to run now is &lt;code&gt;vue create &amp;lt;name&amp;gt;&lt;/code&gt;, where &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; is the name of your project - and also the folder that will be created.&lt;/p&gt;

&lt;p&gt;Let's create our first project then by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vue create avocados
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fitting, right?&lt;/p&gt;

&lt;p&gt;You're going to get hit with a bunch of questions that will help you configure your project, but don't panic, they're all very self explanatory.&lt;/p&gt;

&lt;p&gt;The first screen will allow you to either select a default configuration (which is ok for beginner use), or to hand pick your options through the manual configuration option.&lt;/p&gt;

&lt;p&gt;Don't worry if you didn't select an option such as say, Vuex, on your project set up - there's always a chance to reinstall all of these at any point in time later on on top of your project.&lt;/p&gt;

&lt;p&gt;If you picked a manual setup, you're going to go through a wizard of options that will configure the options for your project. You can navigate this with your arrow keys, select and unselect options with the spacebar, and skip to the next screen with the enter key.&lt;/p&gt;

&lt;p&gt;In here you can make choices like adding TypeScript support, Router base configuration or even Vuex for global state management. &lt;/p&gt;

&lt;p&gt;Once you're done the CLI will do its thing, and after a few seconds your shiny new project will be ready. Go ahead and &lt;code&gt;cd&lt;/code&gt; into it - and let's check out the folder structure together.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Folder Structure
&lt;/h1&gt;

&lt;p&gt;Alright! I'm going to open this new project inside VS Code, and i'm using the Material Icon Theme to make the icons pretty, in case you were wondering.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcq71fahqstxe5tt8svbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcq71fahqstxe5tt8svbr.png" alt="Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quick run down!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;node_modules&lt;/em&gt;: Holds your dependencies code, the ones that you can install or remove using &lt;code&gt;npm&lt;/code&gt; and &lt;code&gt;yarn&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;public&lt;/em&gt;: This folder will hold the &lt;code&gt;index.html&lt;/code&gt; that your webserver will load up when you navigate to the app's url. All the files that it will need will be auto injected by Vue, so you don't really need to worry much about what happens here.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;src&lt;/em&gt;: This is where you will put all your code, components, assets, etc.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;root files&lt;/em&gt;: On your project root you will see a bunch of configuration files like &lt;code&gt;.eslintrc.js&lt;/code&gt; for your ES Lint configuration, &lt;code&gt;.gitignore&lt;/code&gt; for GIT, your &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;yarn.lock&lt;/code&gt; files for package management, and others depending on your previous choices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So ok yeah, now what?&lt;/p&gt;

&lt;p&gt;A good rule of thumb is that when you have a new project and you want to see your available scripts you should check out the &lt;code&gt;package.json&lt;/code&gt; file. Go ahead and open it and you'll see an entry in the JSON that is called &lt;code&gt;scripts&lt;/code&gt;.&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serve&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-cli-service serve&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-cli-service build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-cli-service lint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the left side you'll get the name of the script, and on the right side of the key:value pair you'll get what that script actually does for you.&lt;/p&gt;

&lt;p&gt;How do I use them? Well, it's actually very simple.&lt;/p&gt;

&lt;p&gt;If you're using NPM, you would type into your terminal &lt;code&gt;npm run &amp;lt;scriptname&amp;gt;&lt;/code&gt;, for example &lt;code&gt;npm run serve&lt;/code&gt;. If you're using YARN, then you would type &lt;code&gt;yarn serve&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Serve and Build
&lt;/h1&gt;

&lt;p&gt;There's two main scripts that you will be working with when using the Vue CLI, one is &lt;code&gt;serve&lt;/code&gt; and the one other one is &lt;code&gt;build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Go ahead and run &lt;code&gt;npm run serve&lt;/code&gt; or &lt;code&gt;yarn serve&lt;/code&gt; on your terminal (you need to be on the project directory before), and give it a few seconds to perform its magic. It will compile and bundle all your current assets, and finally spit out this legend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9r6v9d87tjte321r8hof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9r6v9d87tjte321r8hof.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A couple of things are now happening.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This command fired up a server for you, which won't "quit" until you hit &lt;code&gt;control + c&lt;/code&gt; on your terminal window.&lt;/li&gt;
&lt;li&gt;The server will be on the lookout for changes you do on your code and when you save them, it will rebundle your assets immediately (and yell at you if you have errors).&lt;/li&gt;
&lt;li&gt;It gives you this &lt;code&gt;localhost&lt;/code&gt; url that you can copy and paste or command/control click into your browser and will allow you to serve and view your project.&lt;/li&gt;
&lt;li&gt;It has a &lt;strong&gt;hot reload&lt;/strong&gt; function that will dynamically reload parts of your app from within your browser when something changes, so for example if you change a bit of CSS, the browser will auto-magically get updated after the CLI finishes recompiling.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, bottom line, if you're working on your project you want this running in the background all the time.&lt;/p&gt;

&lt;p&gt;On the other hand, you have the &lt;code&gt;build&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Go ahead and run &lt;code&gt;npm run build&lt;/code&gt; or &lt;code&gt;yarn build&lt;/code&gt; and give it a few seconds to compile your assets.&lt;/p&gt;

&lt;p&gt;You will get a new folder in your root called &lt;code&gt;dist&lt;/code&gt; which will have inside a copy of your &lt;code&gt;index.html&lt;/code&gt;, but this time its minified and it will have the embedded scripts and styles that it needs to load.&lt;/p&gt;

&lt;p&gt;Inside this folder you will also get &lt;code&gt;css&lt;/code&gt; and &lt;code&gt;js&lt;/code&gt; folders that hold your compiled project.&lt;/p&gt;

&lt;p&gt;In short, this is the folder that you would eventually want to put into your web server to deploy your application.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bonus
&lt;/h1&gt;

&lt;p&gt;Vue CLI actually has a GUI. 🤯&lt;/p&gt;

&lt;p&gt;Head over to your project root in the terminal and run the command &lt;code&gt;vue ui&lt;/code&gt; and prepare to be amazed. You will get a full web-app GUI that will allow you to view/remove/install plugins, check out your dependencies, play around with your project's configuration and even execute the scripts you learned earlier!&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Knowing and using the &lt;strong&gt;Vue CLI&lt;/strong&gt; is a -must- for any developer that wants to use Vue to make SPAs. I know the terminal can be a dark and scary new world for first timers, but I promise once you go through these steps a couple of times it'll become less and less daunting to use. (And if everything else fails, you have the web UI to back you up!)&lt;/p&gt;

</description>
      <category>vue</category>
      <category>beginners</category>
      <category>cli</category>
    </item>
    <item>
      <title>Hands-on Vue.js for Beginners (Part 7)</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Tue, 05 Mar 2019 14:30:12 +0000</pubDate>
      <link>https://dev.to/marinamosti/hands-on-vuejs-for-beginners-part-7-3e1c</link>
      <guid>https://dev.to/marinamosti/hands-on-vuejs-for-beginners-part-7-3e1c</guid>
      <description>&lt;p&gt;We are nearing the end of journey, and you are almost ready to graduate from Vue Padawan level. But first &lt;strong&gt;watchers&lt;/strong&gt;, you must learn.&lt;/p&gt;

&lt;p&gt;We're going to tackle two very important concepts today, &lt;strong&gt;watchers&lt;/strong&gt;, as mentioned, and form &lt;strong&gt;input bindings&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's get started and we'll build a super simple form to showcase both these fantastic features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vue 101&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;What's your favorite game ever?&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ response }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&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="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&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;favoriteGame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's take a look at what we're doing here. &lt;/p&gt;

&lt;p&gt;Inside our &lt;code&gt;&amp;lt;div id="app"&amp;gt;&lt;/code&gt; we've created a label and the most basic form of an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tag. After, we're outputting the result of a &lt;code&gt;response&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Inside our &lt;strong&gt;Vue&lt;/strong&gt; instance, we're declaring a local state that includes two properties, &lt;code&gt;favoriteGame&lt;/code&gt; and &lt;code&gt;response&lt;/code&gt;. Also note, that we're using the &lt;code&gt;data()&lt;/code&gt; as a function with the &lt;code&gt;return&lt;/code&gt; syntax this time, if we don't v-model won't work.&lt;/p&gt;

&lt;p&gt;The idea here, is that we want to first be able to store whatever the user inputs on the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; field into a variable, that way we can use it later on as we see fit.&lt;/p&gt;

&lt;p&gt;In vanilla JS or even jQuery you may be tempted to try to capture the &lt;code&gt;input&lt;/code&gt; element with a  &lt;code&gt;$('input')&lt;/code&gt; or &lt;code&gt;document.querySelector&lt;/code&gt;, but in &lt;strong&gt;Vue&lt;/strong&gt; we have a much simpler way to achieve this mundane task. &lt;/p&gt;

&lt;p&gt;Introducing &lt;code&gt;v-model&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  v-model
&lt;/h1&gt;

&lt;p&gt;As you've learned before, everything that starts with a &lt;code&gt;v-&lt;/code&gt; is a &lt;strong&gt;Vue directive&lt;/strong&gt;. What &lt;code&gt;v-model&lt;/code&gt; in particular translates to, in very simple terms, is: &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Vue&lt;/strong&gt;, I want you to grab this input that i'm putting this &lt;code&gt;v-model&lt;/code&gt; directive on, and make a two way relation with it. I'm going to give you a &lt;code&gt;property&lt;/code&gt;, and whenever I change this property anywhere in my code - I want you to change it on the input, and likewise, whenever this input changes - I want you to reflect those changes in my prop.
&lt;/h2&gt;

&lt;p&gt;Let's try to put this in action, go to the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; declaration, and add the &lt;code&gt;v-model&lt;/code&gt; directive to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;favoriteGame&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now go and run this in your browser and type something into your magical input box of goodness. Taaaaa...da?&lt;/p&gt;

&lt;p&gt;Ok, even though nothing seems to be happening. Go ahead and open your &lt;strong&gt;Vue&lt;/strong&gt; devtools and inspect the &lt;code&gt;&amp;lt;Root&amp;gt;&lt;/code&gt; element's data. YEAH. Progress!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DdZgRMFo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/me1nmdwfmhv5plz1x2bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DdZgRMFo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/me1nmdwfmhv5plz1x2bg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go into the dev tools and change the value of &lt;code&gt;favoriteGame&lt;/code&gt; into something else (don't forget the quotes wrapping it, we need a string here). EZ-BINDS-R-US 💪&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vue&lt;/strong&gt; is VERY smart about how to bind with every type of native HTML form inputs, so really you only need to drop in the &lt;code&gt;v-model&lt;/code&gt; bomb and profit, but the power of v-model really shows when you start building your own wrapper components and using it a-la-carte.&lt;/p&gt;

&lt;p&gt;Behind the scenes &lt;code&gt;v-model&lt;/code&gt; is actually setting up a &lt;code&gt;v-bind:value&lt;/code&gt; and a &lt;code&gt;v-on:input&lt;/code&gt; even binding, but going in depth on this is a bit out of scope so i'm just going to drop you a link if you're interested in looking further and look the other way. &lt;a href="https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components"&gt;v-model on Components&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Watchers
&lt;/h1&gt;

&lt;p&gt;Now that we have our sweet sweet two-way binding &lt;code&gt;v-model&lt;/code&gt; awesomeness in place, let's actually do something with it. &lt;/p&gt;

&lt;p&gt;You've already learned that with a state &lt;code&gt;data&lt;/code&gt; prop you can put it in your template with &lt;code&gt;{{ favoriteGame }}&lt;/code&gt;, so no need to go over that again. You've learned how to use it inside a &lt;code&gt;method&lt;/code&gt; and &lt;code&gt;computed&lt;/code&gt; prop with &lt;code&gt;this.favoriteGame&lt;/code&gt; - so no need to redo that. But what happens when you want to "listen" or "react" to this property actually getting modified?&lt;/p&gt;

&lt;p&gt;Computed properties are fantastic at recalculating stuff and returning a value, but what if we want to modify another piece of state on our app when this value changes, or maybe even fire an async request of some sort? In these niche cases &lt;code&gt;watchers&lt;/code&gt; come and save the day.&lt;/p&gt;

&lt;p&gt;Let's go an add the boilerplate for creating a watched prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&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="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&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;favoriteGame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&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="c1"&gt;// Watchers here&lt;/span&gt;
    &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;favoriteGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Favorite game was &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;oldValue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; and now is &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;newValue&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;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Watchers are defined inside a &lt;code&gt;watch&lt;/code&gt; property in our instance or component, and we pass it an object that will include a property for each one of the props we want to watch.&lt;/p&gt;

&lt;p&gt;In simple terms, every &lt;code&gt;data&lt;/code&gt; prop or &lt;code&gt;props&lt;/code&gt; prop you want to watch/react to needs to go inside this &lt;code&gt;watch: {}&lt;/code&gt; with its name. So if your prop is named &lt;code&gt;favoriteGame&lt;/code&gt; that's the name of your function.&lt;/p&gt;

&lt;p&gt;Each one of these functions gets two params passed to it, the first one will be the &lt;code&gt;newValue&lt;/code&gt; that this prop is getting, and the second one is the &lt;code&gt;oldValue&lt;/code&gt; that it used to have before the change.&lt;/p&gt;

&lt;p&gt;Check out the &lt;code&gt;console.log&lt;/code&gt; statement and refresh your browser window. Try typing something into the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; and check out your console output. Every time our &lt;code&gt;favoriteGame&lt;/code&gt; prop changes in ANY way, this watcher will be fired.&lt;/p&gt;

&lt;p&gt;Now let's actually do something cool with it. Remember our &lt;code&gt;response&lt;/code&gt; prop? Let's put something into it depending on what the user answers, and have some fun with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;favoriteGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;// If its an empty string, pass&lt;/span&gt;

    &lt;span class="c1"&gt;// If the new value contains the keyword metroid&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ceres station is under attack!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// If the new value contains the word zelda&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zelda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Its dangerous to go alone, take this 🗡️&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// If the OLD value was metroid, and user changed it something else&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;)&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET TO DA CHOPPA NAO&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Default response&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sure, why not?&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In case you don't know, &lt;code&gt;indexOf&lt;/code&gt; checks the string and returns &lt;code&gt;-1&lt;/code&gt; in case there was no match, and else it returns the position of the string we're searching for in the string being searched.&lt;/p&gt;

&lt;p&gt;Go ahead and have some fun with this, make some new examples and play with it in your browser. &lt;/p&gt;

&lt;p&gt;I hope you can see now the power of watched properties, the way I have found it useful is to think, if my property changes and I need to REACT programmatically to it (with an ajax call, an external function, updating a secondary value, etc), then watchers are usually a good call. For anything else, go with computed properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vue 101&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;What's your favorite game ever?&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"favoriteGame"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ response }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&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="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&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;favoriteGame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&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="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;favoriteGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ceres station is under attack!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zelda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Its dangerous to go alone, take this 🗡️&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
            &lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
          &lt;span class="p"&gt;)&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nothing is true , everything is permitted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="k"&gt;return&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sure, why not?&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Congratulations on making it this far!&lt;/p&gt;

&lt;p&gt;You now have the basic tools to actually build a really cool and functional application in &lt;strong&gt;Vue&lt;/strong&gt;, I guarantee it. However, there is still a lot to learn and a lot to explore in order for you to squeeze every inch of juice out of this framework.&lt;/p&gt;

&lt;p&gt;But don't worry, I've said it before and I stand by it today, one of the key aspects I enjoy most about &lt;strong&gt;Vue.js&lt;/strong&gt; is the &lt;a href="https://vuejs.org"&gt;documentation&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I remember back when I was starting out with programming I was really afraid of having to dive docs because they were usually really poorly explained, and assumed a high level of understanding of the language and the framework/lib that I was trying to use.&lt;/p&gt;

&lt;p&gt;Thankfully, the Vue docs team has done a wonderful job of making a complete guide full with examples for everything that we have covered in this guide plus everything else you need to excel at this framework.&lt;/p&gt;

&lt;p&gt;This concludes the Beginner series for Vue! &lt;/p&gt;

&lt;p&gt;If you want to keep up with my articles, keep an eye on my Twitter account at &lt;a href="https://twitter.com/MarinaMosti"&gt;@marinamosti&lt;/a&gt; and check out my other articles at &lt;a href="https://www.telerik.com/blogs/author/marina-mosti"&gt;Progress' blog&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Beware the power of the magical avocado, and thanks for reading! ♥&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Hands-on Vue.js for Beginners (Part 6)</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Fri, 01 Mar 2019 14:23:46 +0000</pubDate>
      <link>https://dev.to/marinamosti/hands-on-vuejs-for-beginners-part-6-5e7l</link>
      <guid>https://dev.to/marinamosti/hands-on-vuejs-for-beginners-part-6-5e7l</guid>
      <description>&lt;p&gt;Let's talk about computed properties.&lt;/p&gt;

&lt;p&gt;So far you've learned how &lt;strong&gt;Vue&lt;/strong&gt; handles its own local state, the one we put inside &lt;code&gt;data&lt;/code&gt;, and how a component can handle its &lt;code&gt;prop&lt;/code&gt; properties - the ones that get handed down by the parent.&lt;/p&gt;

&lt;p&gt;However, there is a type of properties in &lt;strong&gt;Vue&lt;/strong&gt; which are called &lt;strong&gt;Computed Properties&lt;/strong&gt;. Let's take a look at these today.&lt;/p&gt;

&lt;p&gt;We're going to use a clean slate today, so that we can build a clear example. Here's the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vue 101&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;age-calculator&amp;gt;&amp;lt;/age-calculator&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&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;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age-calculator&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="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;p&amp;gt;
          NAME has been kicking butt for X days!
        &amp;lt;/p&amp;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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've gone ahead and added the scaffolding for an &lt;code&gt;age-calculator&lt;/code&gt; component, right now it only outputs a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag with an X where we're going to perform some sort of calculation. I've also added the corresponding tags &lt;code&gt;&amp;lt;age-calculator&amp;gt;&lt;/code&gt; to the &lt;code&gt;div#app&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If you need a refresher on basic components, take a look at &lt;a href="https://dev.to/vuevixens/hands-on-vuejs-for-beginners-part-5--1jbi"&gt;Part V&lt;/a&gt; of this series, or better yet, nosedive &lt;a href="https://vuejs.org/v2/guide/components.html" rel="noopener noreferrer"&gt;the official docs&lt;/a&gt;!&lt;/p&gt;

&lt;h1&gt;
  
  
  When a simple prop isn't enough
&lt;/h1&gt;

&lt;p&gt;Before we write any code, let's talk about what we're trying to accomplish.&lt;/p&gt;

&lt;p&gt;I want to have a component where I pass it someone's age, and it will tell us how many days they've been around to enjoy avocados. If you don't like avocados then this is where our relationship ends, have a nice life.&lt;/p&gt;

&lt;p&gt;Let's tackle the easy tasks that we already know how to accomplish, first we need an array of people with ages so that we can loop through it and output a bunch of components. Let's add the corresponding &lt;code&gt;data&lt;/code&gt;.&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;people&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mario&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Luigi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Samus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marina&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="c1"&gt;//Add yourself here :)&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, let's set up our &lt;code&gt;v-loop&lt;/code&gt; to output an &lt;code&gt;age-calculator&lt;/code&gt; per each one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;age-calculator&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"person in people"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"person.name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/age-calculator&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome, now let's allow the &lt;code&gt;age-calculator&lt;/code&gt; component to receive a &lt;code&gt;person&lt;/code&gt;, remember we do this with a &lt;code&gt;prop&lt;/code&gt;. So first, let's add this new &lt;code&gt;prop&lt;/code&gt; to the component.&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="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age-calculator&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="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;p&amp;gt;
      {{ person.name }} has been kicking butt for X days!
    &amp;lt;/p&amp;gt;
  `&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bonus!&lt;/strong&gt; Before you learned that to declare the props that a component can receive, you set up an array of strings &lt;code&gt;props: ['person']&lt;/code&gt; and this is fine in most cases. But what happens if we want a bit more control?&lt;/p&gt;

&lt;p&gt;You can also, like in this case, set &lt;code&gt;props&lt;/code&gt; to be equal to an &lt;strong&gt;object&lt;/strong&gt;. Inside this object, we can create a property per each property we want to declare. &lt;/p&gt;

&lt;p&gt;Inside the property declaration, in this case &lt;code&gt;person&lt;/code&gt;, we can set some configuration values. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;type&lt;/code&gt; to declare which (duh) &lt;strong&gt;type&lt;/strong&gt; of data we're passing, so &lt;code&gt;Object&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Number&lt;/code&gt; for example. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;required&lt;/code&gt; is a &lt;strong&gt;boolean&lt;/strong&gt; that allows us to mark this property as required for the component to work. &lt;/p&gt;

&lt;p&gt;You can also set a &lt;code&gt;default&lt;/code&gt; value, but we're not going to use that here.&lt;/p&gt;

&lt;p&gt;Next, look at the template. We are now outputting the person's name &lt;code&gt;{{ person.name }}&lt;/code&gt; onto the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag. &lt;/p&gt;

&lt;p&gt;One more thing before we can actually run this in our browser though. Can you tell what we're missing?&lt;/p&gt;

&lt;p&gt;We still need to pass the actual &lt;code&gt;person&lt;/code&gt; to the &lt;code&gt;age-calculator&lt;/code&gt; component!&lt;/p&gt;

&lt;p&gt;Go into the render loop and pass in our variable.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;calculator&lt;/span&gt; 
  &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;person in people&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
  &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;person&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;person.name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/age-calculator&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go ahead and run this in your browser to check that everything is working. Baby-steps!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; Before we move on, if you're curious what setting a &lt;code&gt;prop&lt;/code&gt; to &lt;strong&gt;required&lt;/strong&gt; will do for you, try removing this last bit we did when we pass the person to the component and look at your dev tools in the console section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0uhzn5szgsbdfscmm64j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0uhzn5szgsbdfscmm64j.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Handy, ain't it? 👌&lt;/p&gt;

&lt;h1&gt;
  
  
  The actual Computed Property
&lt;/h1&gt;

&lt;p&gt;Alright, enough setting up and review. &lt;/p&gt;

&lt;p&gt;We still have one more feature to tackle inside our component, we want to &lt;strong&gt;calculate&lt;/strong&gt; the number of days each person has been alive. &lt;/p&gt;

&lt;p&gt;Granted, it's not a very hard calculation, we just have to multiply 365 times the number of years (we're not going to go hardcore with JS Dates here). And in fact, we could go ugly and direct and put this straight into our template.&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="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;p&amp;gt;
          {{ person.name }} has been kicking butt for {{ person.age * 365 }} days!
        &amp;lt;/p&amp;gt;
      `&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, sort of. But what happens when you require more logic? A harder &lt;code&gt;computation&lt;/code&gt;, some ifs/ands/ors/whens/beers? Then you're in a real problem because you can't really put that much logic inside the template, or it's going to get unmanageable real quick.&lt;/p&gt;

&lt;p&gt;Here's where &lt;strong&gt;computed properties&lt;/strong&gt; shine. Computed properties are in the end functions, that will execute a bit of code, and return a value. This value is now treated like a property, which means we can straight up use it in our template.&lt;/p&gt;

&lt;p&gt;Let's take a look at how to set it up. First, let's add the computed wrapper to our component.&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="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age-calculator&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="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;p&amp;gt;
      {{ person.name }} has been kicking butt for {{ person.age * 365 }} days!
    &amp;lt;/p&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Computed props go here&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;So far so good, in fact this structure is the exact same one we have been using for &lt;code&gt;methods&lt;/code&gt;, remember? (If you're thinking a method could also solve our problem, you're on the right track - we'll talk about this in a minute.)&lt;/p&gt;

&lt;p&gt;Let's create a new &lt;strong&gt;computed&lt;/strong&gt; property called &lt;code&gt;daysAlive&lt;/code&gt;, it needs to be a function, and it needs to return something.&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="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;daysAlive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;//Remember, computed props are functions in the end&lt;/span&gt;
    &lt;span class="k"&gt;return&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;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;365&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;Take note that just like in &lt;code&gt;methods&lt;/code&gt; we need to access the &lt;code&gt;person&lt;/code&gt; prop though &lt;code&gt;this&lt;/code&gt;, only inside the template we can use it directly! Other than that, nothing too fancy going on.&lt;/p&gt;

&lt;p&gt;Now let's use this new &lt;code&gt;daysAlive&lt;/code&gt; prop in our template.&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="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
  &amp;lt;p&amp;gt;
    {{ person.name }} has been kicking butt for {{ daysAlive }} days!
  &amp;lt;/p&amp;gt;
`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we're outputting the value of the &lt;code&gt;daysAlive&lt;/code&gt; --&lt;strong&gt;property&lt;/strong&gt;--, (aha moment here). &lt;strong&gt;Vue&lt;/strong&gt; treats computed props as, well, props - so we can use this here as you would a &lt;code&gt;props&lt;/code&gt; prop, or a &lt;code&gt;data&lt;/code&gt; prop. &lt;/p&gt;

&lt;p&gt;In fact, &lt;strong&gt;Vue&lt;/strong&gt; makes it so that if you would need to use this prop inside a &lt;code&gt;method&lt;/code&gt; for example, you would have to access it through &lt;code&gt;this.daysAlive&lt;/code&gt;. Neat right? It ACTUALLY becomes a prop. 🤯&lt;/p&gt;

&lt;p&gt;YAY, run it in the browser and bask in your awesomeness.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0q9lul5pzyjq6p8z03sh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0q9lul5pzyjq6p8z03sh.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Methods vs Computed Properties
&lt;/h1&gt;

&lt;p&gt;You may have noticed a lot of similarities between methods and computed props, I mean, they're basically identical at code level. However there is a CORE difference that you need to understand in order to harness them fully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Computed properties&lt;/strong&gt; get cached. &lt;/p&gt;

&lt;p&gt;What this means is, in the simplest possible way to explain it, that behind the scenes &lt;strong&gt;Vue&lt;/strong&gt; will "read" your code and look for &lt;strong&gt;reactive dependencies&lt;/strong&gt; - so &lt;code&gt;data&lt;/code&gt; props and &lt;code&gt;props&lt;/code&gt; props. It will &lt;strong&gt;watch&lt;/strong&gt; these properties, and whenever they change, &lt;strong&gt;Vue&lt;/strong&gt; will recalculate the value of your computed property. If they don't change, it'll just use a cached/stored value.&lt;/p&gt;

&lt;p&gt;Methods, on the other hand, are ran EVERY time - there is no caching, no code reading, no magic. They're just plain old functions.&lt;/p&gt;

&lt;p&gt;Why does this matter? When are these functions called?&lt;/p&gt;

&lt;p&gt;Every time your component/app re-renders (so every time a component's data change, or every time it's parent's data changes), &lt;strong&gt;Vue&lt;/strong&gt; will figure out if that data is tied to a &lt;strong&gt;computed&lt;/strong&gt; property, if it's not - it won't call this function again. For regular methods however, they will be re-run every time!&lt;/p&gt;

&lt;p&gt;For this example, where we're doing a very simple calculation for these few objects it doesn't really matter, frankly. But when you start doing some serious code weightlifting on top of a thousand components, then you're going to want to leverage this caching or your app is going to take a hit on each render cycle.&lt;/p&gt;

&lt;p&gt;If you want to read more, here's a link to the official docs regarding &lt;a href="https://vuejs.org/v2/guide/computed.html" rel="noopener noreferrer"&gt;computed properties&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's the complete code for today.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vue 101&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;age-calculator&lt;/span&gt; 
      &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"person in people"&lt;/span&gt; 
      &lt;span class="na"&gt;:person=&lt;/span&gt;&lt;span class="s"&gt;"person"&lt;/span&gt;
      &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"person.name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/age-calculator&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&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;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age-calculator&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="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;p&amp;gt;
          {{ person.name }} has been kicking butt for {{ daysAlive }} days!
        &amp;lt;/p&amp;gt;
      `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;daysAlive&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;365&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;people&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mario&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Luigi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Samus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&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;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it for today! Thanks for reading, and we'll keep on going next week with &lt;code&gt;watchers&lt;/code&gt;! 🕵️‍♀️ 👀&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Understanding the Spread Operator in JavaScript</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Tue, 26 Feb 2019 17:27:46 +0000</pubDate>
      <link>https://dev.to/marinamosti/understanding-the-spread-operator-in-javascript-485j</link>
      <guid>https://dev.to/marinamosti/understanding-the-spread-operator-in-javascript-485j</guid>
      <description>&lt;p&gt;&lt;code&gt;{...object}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The first time I looked at this I was really confused about what it was supposed to mean, or even do, but harnessing the power of the spread operator in JavaScript has definitely payed off.&lt;/p&gt;

&lt;p&gt;In my latest entry to &lt;a href="https://dev.to/vuevixens/hands-on-vuejs-for-beginners-part-5--1jbi"&gt;Hands-on Vue for Beginners&lt;/a&gt; series, I used a spread operator in the tutorial and promised I would make a post explaining what it is, and how it works, for anyone that is not yet familiar with it.&lt;/p&gt;

&lt;p&gt;Disclaimer. The spread operator is an ES6 feature, and thus is not supported in every browser (IE strikes again). However you can rest assured that it will work on all major and modern browsers. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Browser_compatibility"&gt;Browser Compatibility&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Diving in
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;MDN&lt;/strong&gt; explains it like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I don't know about you, but for me when I was trying to learn all this it was super daunting and confusing. So let's break it down to digestible pieces.&lt;/p&gt;

&lt;p&gt;Imagine you have a function, where you want to add three values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;c&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;c&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 imagine, you have an array of values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, if we ask ourselves, how would we go about putting those values into the function add them. A practical approach would be to maybe do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&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="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I mean, it sort-of works. Right? But take it up a nudge, what happens when you have a function that will accept a dynamic number of arguments? Or even simpler yet, what if we have a scenario where this function wants 20 values and I give you an array with 20 numbers. &lt;/p&gt;

&lt;p&gt;This is when things start to get really ridiculous, are you going to access all the values directly via index? (There's ways to do this with array functions like &lt;code&gt;reduce&lt;/code&gt;, I know, but bare with me for the sake of example.)&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;omgwhy&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="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;omgwhy&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;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here's where the spread operator shines! Imagine that this &lt;code&gt;values&lt;/code&gt; array is a box, it contains all these numbers in it in a VERY neat and orderly fashion, each one has an index - and that contains it perfectly.&lt;/p&gt;

&lt;p&gt;When we access an array's index value like this &lt;code&gt;values[1]&lt;/code&gt; we are very neatly taking out that single value, which is what we did on the first example. But to continue with the metaphor, what if we wanted to take out ALL the values in the exact order in which they are in the box?&lt;/p&gt;

&lt;p&gt;Maybe it could be cool to be able to do something like this &lt;code&gt;values[0-11]&lt;/code&gt;, but instead we type it like this &lt;code&gt;...values&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now in this case in particular with the function, you would say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Tada! Now, watch carefully because when take the values out of the array they're not just getting thrown around into the wind, they're all going into their respective parameters in the function. &lt;code&gt;a&lt;/code&gt; will get &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt; will get &lt;code&gt;2&lt;/code&gt; and so on.&lt;/p&gt;

&lt;h1&gt;
  
  
  Merging
&lt;/h1&gt;

&lt;p&gt;Alright, so &lt;strong&gt;spreading&lt;/strong&gt; arrays into functions is nice. But i've honestly not used it a lot. However merging two arrays together or two objects becomes a breeze!&lt;/p&gt;

&lt;p&gt;Let's cook up an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;favoriteGames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Zelda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Metroid&lt;/span&gt;&lt;span class="dl"&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;favoriteBands&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Queen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RHCP&lt;/span&gt;&lt;span class="dl"&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;lifeFavorites&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;favoriteGames&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;favoriteBands&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So first we're just defining a couple of arrays for examples, &lt;code&gt;favoriteGames&lt;/code&gt; and &lt;code&gt;favoriteBands&lt;/code&gt;. But let's take a look closely at the third line.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const lifeFavorites =&lt;/code&gt; we're going to store the result of the merge here, nothing too fancy and we're setting it to be equal to a NEW array. &lt;/p&gt;

&lt;p&gt;Notice &lt;code&gt;= [somestuffshere];&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is super important to understand, when you spread an array or an object those spread values needs to be used somehow, you need to clean up after yourself. So in this case we're saying:&lt;/p&gt;

&lt;p&gt;Ok, JS, grab the contents of these two array boxes, dump all the crap they have in them into this new box and call it &lt;code&gt;lifeFavorites&lt;/code&gt;. Thankfully the actual crap-dumping is done in a very orderly fashion and order of the values will be respected.&lt;/p&gt;

&lt;p&gt;So the result will actually be:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;['Zelda', 'Metroid', 'Queen', 'RHCP']&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/immarina/embed/xMvWyO?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h1&gt;
  
  
  Making copies
&lt;/h1&gt;

&lt;p&gt;Another great way to use the spread operator is to make a copy of an array or an object. In JavaScript when you assign an object or array to a variable you're actually storing something called the "pointer", which sort of works like the address of where that object is being stored.&lt;/p&gt;

&lt;p&gt;So if you do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marina&lt;/span&gt;&lt;span class="dl"&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;anotherObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The big problem here will be that both &lt;code&gt;obj&lt;/code&gt; and &lt;code&gt;anotherObj&lt;/code&gt; are actually pointing to the same object. So if you change one or the other, they will both change because the pesky &lt;strong&gt;pointer&lt;/strong&gt; is addressed to the same object.&lt;/p&gt;

&lt;p&gt;In frameworks like &lt;strong&gt;Vue&lt;/strong&gt; this becomes a real problem and a real pain to debug, because in some cases like when making copies of &lt;strong&gt;props&lt;/strong&gt; you never want to modify the original object. In &lt;strong&gt;React&lt;/strong&gt; this is also used when changing the state, you're not supposed to directly modify the value.&lt;/p&gt;

&lt;p&gt;So how do we make a copy with the spread operator?&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;baseObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marina&lt;/span&gt;&lt;span class="dl"&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;myCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;baseObject&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;baseArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&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;arrayCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;baseArray&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Something important to note is that when making a copy of any object/array using a the spread operator the copy will be shallow. This means that if your object has a child object, that &lt;code&gt;child&lt;/code&gt; will still have a pointer to the original object. (Thanks to everyone that pointed this in the comments)&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Parent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;child&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Child&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// The thing to note here is that the COPY will have a child property, but this&lt;/span&gt;
&lt;span class="c1"&gt;// child property is actually pointing to the same exact object as ORIGINAL&lt;/span&gt;

&lt;span class="c1"&gt;// So:&lt;/span&gt;
&lt;span class="c1"&gt;// original.child === copy.child&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it! Once again, we're pouring out our boxes into another box that contains it, and that will ensure that the resulting object/array are actually a copy of the original - and you can safely modify them without fear of messing with the first.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Hands-on Vue.js for Beginners (Part 5) </title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Fri, 22 Feb 2019 17:59:01 +0000</pubDate>
      <link>https://dev.to/marinamosti/hands-on-vuejs-for-beginners-part-5--1jbi</link>
      <guid>https://dev.to/marinamosti/hands-on-vuejs-for-beginners-part-5--1jbi</guid>
      <description>&lt;p&gt;This time around we're going to look (finally) at components! So get some ☕️ and let's get started.&lt;/p&gt;

&lt;p&gt;Here's the clean slate for today's article 😁&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://cdn.jsdelivr.net/npm/vue/dist/vue.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&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="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;data&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;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/html&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Component Basics
&lt;/h1&gt;

&lt;p&gt;We're going to nosedive right into component creation because this is where really fun stuff starts. But rest assured that this is only barely brushing the power of components. Also, we still have yet to learn &lt;code&gt;computed&lt;/code&gt; properties and &lt;code&gt;watchers&lt;/code&gt;, which will also be a huge aid. But we'll cover that next time on top of what we learn today.&lt;/p&gt;

&lt;p&gt;Components are a core part of the &lt;strong&gt;Vue.js&lt;/strong&gt; framework, they are your Lego blocks for building reactive, rich applications - and luckily for us, they are super simple to learn and use!&lt;/p&gt;

&lt;p&gt;Think of a component as any element in your webpage/app that you want to use one or several times. It can be as &lt;em&gt;smol&lt;/em&gt; as a button, or input, or as a big as your whole menu bar or even the whole page's view.&lt;/p&gt;

&lt;p&gt;The advantage of creating a component is that you write the logic for how its displayed (HTML/CSS), and how it interacts with the user (JS) once - and then you just use it all over your app.&lt;/p&gt;

&lt;p&gt;As usual, we're going to start with the simplest possible example, a button. &lt;br&gt;
Let's define first the &lt;strong&gt;blueprint&lt;/strong&gt; or &lt;strong&gt;template&lt;/strong&gt; for this component, we'll call it &lt;code&gt;awesome-button&lt;/code&gt; and it shall be so!&lt;/p&gt;

&lt;p&gt;Let's define a new &lt;code&gt;awesome-button&lt;/code&gt; component. Copy this code above your &lt;code&gt;new Vue&lt;/code&gt; declaration.&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="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;awesome-button&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="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;button @click="clickHandler"&amp;gt;Click me for some awesomeness&amp;lt;/button&amp;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;clickHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YAAAS 😎&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;The &lt;code&gt;Vue&lt;/code&gt; object that is made available to us through the &lt;code&gt;Vue.js&lt;/code&gt; script tag that we added on day 1 has this &lt;code&gt;component&lt;/code&gt; method that we are calling here. It allows us to create a new component, as expected. The first parameter we are setting is a &lt;em&gt;String&lt;/em&gt;, which will be the name of our component.&lt;/p&gt;

&lt;p&gt;The second parameter is a JavaScript &lt;code&gt;object&lt;/code&gt;, which - surprise - is actually the same type of configuration object that we have been using for our main &lt;code&gt;Vue instance&lt;/code&gt;! What does this mean for you? That you already know how to assign properties and methods for this new component.&lt;/p&gt;

&lt;p&gt;In the example above, you will notice just one difference - the &lt;code&gt;template&lt;/code&gt; property. In here we're declaring a &lt;strong&gt;String&lt;/strong&gt; (note that we're also using the &lt;strong&gt;back-tick&lt;/strong&gt; character to wrap it so that we can declare multiple lines later on if we need without having to concatenate multiple strings), this &lt;strong&gt;String&lt;/strong&gt; will hold our actual HTML code for &lt;code&gt;this&lt;/code&gt; &lt;strong&gt;component&lt;/strong&gt;. In the case of this particular example, just a simple &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; tag will suffice.&lt;/p&gt;

&lt;p&gt;If you reload your page right now, nothing will happen. Remember earlier I told you this was only the blueprint/template? It's time to actually render it on our page.&lt;/p&gt;

&lt;p&gt;Head over to the &lt;code&gt;&amp;lt;div id="app"&amp;gt;&lt;/code&gt; where we have been placing all our markup, and create a new &lt;code&gt;&amp;lt;awesome-button&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;Your HTML should now look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;awesome-button&amp;gt;&amp;lt;/awesome-button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load the page, and now you will actually see the button is rendered on the page. Place a couple, or ten more (reader's choice), &lt;code&gt;awesome-button&lt;/code&gt; tag on the page. Now you start to see the power of components, although at this point I think we can take it up a nudge.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Bonus:&lt;/em&gt; If you're the curious type, take a look at your &lt;code&gt;page source&lt;/code&gt; and compare it to the &lt;code&gt;inspect&lt;/code&gt; feature with your browser's developer tools. When the page load, &lt;em&gt;Vue.js&lt;/em&gt; is using the &lt;code&gt;&amp;lt;awesome-button&amp;gt;&lt;/code&gt; tag as a placeholder to where it should put the parsed content of our template.&lt;/p&gt;

&lt;h1&gt;
  
  
  Level 2 - Something a little more useful
&lt;/h1&gt;

&lt;p&gt;Let's revisit our example from last week, and play some more with our &lt;code&gt;games&lt;/code&gt; data.&lt;/p&gt;

&lt;p&gt;First, let's re-add this array of games into our &lt;code&gt;data()&lt;/code&gt; in the main &lt;strong&gt;Vue&lt;/strong&gt; instance.&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;app&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="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;games&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Mario 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nintendo 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The Legend of Zelda Ocarina of Time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nintendo 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Secret of Mana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Nintendo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fallout 76&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Multiple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Nintendo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&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;Just as before, feel free to update these with your favorite titles.&lt;/p&gt;

&lt;p&gt;This time, however, we are going to create a &lt;code&gt;game-card&lt;/code&gt; component, that will make a bit more sense to display our data in.&lt;/p&gt;

&lt;p&gt;Ready for 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="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;game-card&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="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gameData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div style="border-radius: .25rem; border: 1px solid #ECECEC; width: 400px; margin: 1rem; padding: 1rem;"&amp;gt;
      &amp;lt;h2&amp;gt;{{ gameData.name }} - &amp;lt;small&amp;gt;{{ gameData.console }}&amp;lt;/small&amp;gt;&amp;lt;/h2&amp;gt;

      &amp;lt;span v-for="heart in gameData.rating"&amp;gt;❤️&amp;lt;/span&amp;gt;

      &amp;lt;button @click="increaseRating"&amp;gt;Increase Rating&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;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;increaseRating&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// this.game.rating++ ?&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;Don't get overwhelmed, you already know all/most-all of this 😃!&lt;/p&gt;

&lt;p&gt;We're creating a new &lt;code&gt;Vue.component&lt;/code&gt; and naming it &lt;code&gt;game-card&lt;/code&gt;. Let's skip &lt;code&gt;props&lt;/code&gt; for a second, and look at the &lt;code&gt;template&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nothing new here, except you may have noticed we're accessing the properties of a &lt;code&gt;gameData&lt;/code&gt; property that is not defined inside &lt;code&gt;data&lt;/code&gt;, but inside the &lt;code&gt;props&lt;/code&gt; property. &lt;/p&gt;

&lt;p&gt;Afterward, we declare our &lt;code&gt;methods&lt;/code&gt; object, with the &lt;code&gt;increaseRating&lt;/code&gt; method inside it. I've purposely commented out &lt;code&gt;this.game.rating++&lt;/code&gt; which would be how you may want to address this particular function, but it won't work! Now it's time to talk about &lt;code&gt;props&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Component Props
&lt;/h1&gt;

&lt;p&gt;One of the reserved properties we can have on our custom components is called &lt;code&gt;props&lt;/code&gt;. In its simplest form, it will take an array of &lt;strong&gt;Strings&lt;/strong&gt; that will define variables. In our previous example, we are telling the component blueprint/template that we want it to be aware of a property called &lt;code&gt;game&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Props&lt;/code&gt; will allow us to &lt;em&gt;pass&lt;/em&gt; information into our components from outside! Let's view this in action, it'll be easier to grasp.&lt;/p&gt;

&lt;p&gt;First, let's add a bunch of &lt;code&gt;&amp;lt;game-card&amp;gt;&lt;/code&gt; items to our app. We will be using a &lt;code&gt;v-for&lt;/code&gt; loop just like we did before, but we're going to loop on top of our custom components this time!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;awesome-button&amp;gt;&amp;lt;/awesome-button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;game-card&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"game in games"&lt;/span&gt; &lt;span class="na"&gt;:game-data=&lt;/span&gt;&lt;span class="s"&gt;"game"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"game.name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/game-card&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is quite a bit of &lt;code&gt;game&lt;/code&gt; being tossed around, so let's look at it in detail.&lt;/p&gt;

&lt;p&gt;First step, we are creating our &lt;code&gt;&amp;lt;game-card&amp;gt;&lt;/code&gt; component, like we discussed earlier.&lt;/p&gt;

&lt;p&gt;After, we add the &lt;code&gt;v-for="game in games"&lt;/code&gt; loop like we saw last week. This creates a &lt;code&gt;game&lt;/code&gt; variable that will hold the current game in the loop, and we can use it right away!&lt;/p&gt;

&lt;p&gt;Finally, we assign to the template's &lt;strong&gt;prop&lt;/strong&gt;, &lt;code&gt;gameData&lt;/code&gt;, a value, in this case our &lt;code&gt;game&lt;/code&gt; variable from the loop. Notice that instead of camel case, we're using a hyphen &lt;code&gt;game-data&lt;/code&gt; because HTML is case insensitive. If you are having a hard time grasping this, try thinking it in object terms. We are doing something similar to &lt;code&gt;game-card.props.gameData = game&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Don't forget about the &lt;code&gt;:key&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;There is a huge gotcha to mention here, we are passing &lt;code&gt;game&lt;/code&gt; to our &lt;code&gt;game-data&lt;/code&gt; prop, but there is a &lt;code&gt;:&lt;/code&gt; behind it. Did you notice?&lt;/p&gt;

&lt;p&gt;When we assign a property to a component instance, there's two ways to go about it. Following our example, we could either do it with the &lt;code&gt;:&lt;/code&gt; before it (this is a shorthand for &lt;code&gt;v-bind:&lt;/code&gt;!). This will make sure the data that we are passing &lt;strong&gt;after&lt;/strong&gt; the &lt;code&gt;="&amp;lt;here&amp;gt;"&lt;/code&gt; is used by JavaScript as a variable, or an actual piece of &lt;strong&gt;code&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you were to type instead &lt;code&gt;gameData="game"&lt;/code&gt;, then &lt;em&gt;Vue&lt;/em&gt; will take this as assigning the &lt;code&gt;gameData&lt;/code&gt; prop the &lt;strong&gt;String&lt;/strong&gt; &lt;code&gt;"game"&lt;/code&gt;. So something like: &lt;code&gt;game-card.props.gameData = "game"&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Go ahead and take a break from theory and actually go and run this in your browser. You will see as expected, that our whole &lt;code&gt;&amp;lt;game-card&amp;gt;&lt;/code&gt; component's template is being rendered for each one of our &lt;code&gt;game&lt;/code&gt;'s. &lt;/p&gt;

&lt;p&gt;The greatest part about this is that if we were to make a change to our HTML, it will be updated everywhere in our app. &lt;/p&gt;

&lt;p&gt;Also, and &lt;strong&gt;most importantly&lt;/strong&gt;, &lt;em&gt;components&lt;/em&gt; allow you to &lt;strong&gt;contain&lt;/strong&gt; the logic for that particular component. Let's revisit that &lt;code&gt;game-card&lt;/code&gt;'s &lt;code&gt;increaseRating()&lt;/code&gt; method.&lt;/p&gt;

&lt;h1&gt;
  
  
  Component Data vs. Props
&lt;/h1&gt;

&lt;p&gt;Props for components actually can be a very lengthy subject, but there is a very important rule of thumb that you must always keep in mind. A property should NEVER be modified from inside a component. &lt;/p&gt;

&lt;p&gt;In fact, if you try to do this, &lt;em&gt;Vue&lt;/em&gt; will throw all sorts of warnings and yell at you in the console - because this WILL lead to unexpected behavior. Here's the documentation, in case you want to read about it: &lt;a href="https://vuejs.org/v2/guide/migration.html#Prop-Mutation-deprecated"&gt;Mutating props in Vue2 is an anti-pattern&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;How then, will we modify the value of &lt;code&gt;rating&lt;/code&gt; inside of our component's storage? The key is in the question itself! We need to make a copy of this &lt;code&gt;prop&lt;/code&gt; into our &lt;code&gt;data&lt;/code&gt; so that we can actually modify it.&lt;/p&gt;

&lt;p&gt;Let's first add our &lt;code&gt;data&lt;/code&gt; to our &lt;code&gt;game-card&lt;/code&gt; component, and assign it a new non-conflicting name (props and data props will conflict if named the same), and then pre-fill it with the prop's value.&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="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;game&lt;/span&gt;&lt;span class="p"&gt;:&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;gameData&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;Couple of things to note here, but before that, if you don't know yet what &lt;code&gt;{...gameData}&lt;/code&gt; is doing, it's a spread operator. I won't go into full detail here and will try to post a brief article about it soon, but basically were making a &lt;em&gt;copy&lt;/em&gt; of the &lt;code&gt;gameData&lt;/code&gt; prop, because we don't ever want to modify that from the child.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;data&lt;/code&gt; property's &lt;code&gt;return&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;When we learned about the &lt;code&gt;data&lt;/code&gt; property, I told you that it needed to hold an object with all the properties we needed, and this is how we've been doing it for our main &lt;strong&gt;Vue instance&lt;/strong&gt;. However for &lt;strong&gt;components&lt;/strong&gt; we actually need to make it a function, by adding &lt;code&gt;()&lt;/code&gt;, and second &lt;code&gt;return&lt;/code&gt; the actual object.&lt;/p&gt;

&lt;p&gt;But WHY?! 😫 &lt;/p&gt;

&lt;p&gt;Simply put, there can be one or many instances of your component, right? &lt;/p&gt;

&lt;p&gt;Each instance will need a &lt;em&gt;unique&lt;/em&gt; data object! You don't want to share a single &lt;code&gt;data&lt;/code&gt; object between all of those, or they would all share the same &lt;code&gt;title&lt;/code&gt; for example - and the point of this whole app would be lost.&lt;/p&gt;

&lt;p&gt;So the whole reason behind making it a &lt;strong&gt;function&lt;/strong&gt; and &lt;em&gt;returning&lt;/em&gt; an object, is that &lt;strong&gt;Vue&lt;/strong&gt; can ☎️ call this function every time it &lt;em&gt;creates&lt;/em&gt; one of our &lt;code&gt;game-cards&lt;/code&gt;. That way each one will get a unique object of data to play with!&lt;/p&gt;

&lt;p&gt;Accessing our props: &lt;/p&gt;

&lt;p&gt;When we create the &lt;code&gt;game&lt;/code&gt;'s &lt;strong&gt;data&lt;/strong&gt; property, we are assigning it &lt;code&gt;this.gameData&lt;/code&gt;, so a couple of things to learn here. &lt;code&gt;props&lt;/code&gt; can &lt;strong&gt;also&lt;/strong&gt; be accessed within your component scripts via &lt;code&gt;this&lt;/code&gt; just as your local state props from &lt;code&gt;data&lt;/code&gt;. So here, we are setting &lt;code&gt;game&lt;/code&gt; to be equal to the &lt;code&gt;gameData&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;This means now we have to update our HTML, so inside the component switch the &lt;code&gt;gameData&lt;/code&gt; reference for &lt;code&gt;game&lt;/code&gt; like so:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;border-radius: .25rem; border: 1px solid #ECECEC;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;small&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/small&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;heart in game.rating&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;❤️&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;increaseRating&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Increase&lt;/span&gt; &lt;span class="nx"&gt;Rating&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this once again in your browser, and you should get the same results.&lt;/p&gt;

&lt;p&gt;Finally, we are at the point where we can make our &lt;code&gt;increaseRating&lt;/code&gt; method work! Head to the method and replace the comment with 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="nx"&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;increaseRating&lt;/span&gt;&lt;span class="p"&gt;()&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;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&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;With every click, we're going to increment the component's &lt;strong&gt;internal&lt;/strong&gt; &lt;code&gt;data&lt;/code&gt; property which holds the &lt;code&gt;game&lt;/code&gt;'s rating, -not- the prop.&lt;/p&gt;




&lt;p&gt;There is a lot of theory to be learned about components, i've just began to scratch the surface, but hopefully you are starting to have a clearer picture of why frameworks like &lt;strong&gt;Vue&lt;/strong&gt; are so popular, and so much fun to use.&lt;/p&gt;

&lt;p&gt;From this point forward we're going to start looking at what I consider intermediate topics, like &lt;code&gt;computed&lt;/code&gt; properties, &lt;code&gt;watchers&lt;/code&gt;, &lt;code&gt;events&lt;/code&gt;, etc. So hopefully you are excited to get to know the meaty part of Vue soon enough.&lt;/p&gt;

&lt;p&gt;In case you need it, here's the complete code for today, and thanks for reading! 🤗😋&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vue 101&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;awesome-button&amp;gt;&amp;lt;/awesome-button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;game-card&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"game in games"&lt;/span&gt; &lt;span class="na"&gt;:game-data=&lt;/span&gt;&lt;span class="s"&gt;"game"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"game.name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/game-card&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&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;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;awesome-button&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="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;button @click="clickHandler"&amp;gt;Click me for some awesomeness&amp;lt;/button&amp;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;clickHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YAS. 😎&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;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;game-card&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="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gameData&lt;/span&gt;&lt;span class="dl"&gt;'&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;game&lt;/span&gt;&lt;span class="p"&gt;:&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;gameData&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="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div style="border-radius: .25rem; border: 1px solid #ECECEC; width: 400px; margin: 1rem; padding: 1rem;"&amp;gt;
          &amp;lt;h2&amp;gt;{{ game.name }} - &amp;lt;small&amp;gt;{{ game.console }}&amp;lt;/small&amp;gt;&amp;lt;/h2&amp;gt;

          &amp;lt;span v-for="heart in game.rating"&amp;gt;❤️&amp;lt;/span&amp;gt;

          &amp;lt;button @click="increaseRating"&amp;gt;Increase Rating&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;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;increaseRating&lt;/span&gt;&lt;span class="p"&gt;()&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;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&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="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;games&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Mario 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nintendo 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The Legend of Zelda Ocarina of Time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nintendo 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Secret of Mana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Nintendo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fallout 76&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Multiple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Nintendo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&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;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>vue</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Hands-on Vue.js for Beginners (Part 4)</title>
      <dc:creator>Marina Mosti</dc:creator>
      <pubDate>Thu, 14 Feb 2019 18:32:38 +0000</pubDate>
      <link>https://dev.to/marinamosti/hands-on-vuejs-for-beginners-part-4-324l</link>
      <guid>https://dev.to/marinamosti/hands-on-vuejs-for-beginners-part-4-324l</guid>
      <description>&lt;p&gt;Welcome back! 🤩&lt;/p&gt;

&lt;p&gt;Last time we took at conditional rendering with &lt;code&gt;v-if&lt;/code&gt; and &lt;code&gt;v-show&lt;/code&gt;. This time we will learn how to loop through arrays and objects and create an element for each one of the items in them. We will also apply some of the concepts we have learned before.&lt;/p&gt;

&lt;h1&gt;
  
  
  v-for
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;v-for&lt;/code&gt; is one of the fundamental directives of &lt;em&gt;Vue.js&lt;/em&gt;, and once you understand how it works the extension of what you can build inside your apps will grow exponentially.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;v-for&lt;/code&gt; is, simply put, a &lt;code&gt;for&lt;/code&gt; loop. If you don't yet know what this means, a for loop is a piece of code that gets executed one time per each element in a group - which in turn is usually an &lt;code&gt;Array&lt;/code&gt; or an &lt;code&gt;Object&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We're going to start with an empty slate today so that everything we do has a clear purpose. Here's a copy of our base &lt;code&gt;index.html&lt;/code&gt; file for you to copy and paste into your editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vue 101&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;data&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="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="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start by creating a simple list, an array, that we can loop to output its content. We will create a property inside our &lt;code&gt;data&lt;/code&gt; object, called &lt;em&gt;games&lt;/em&gt;. Feel free to change the titles to your own personal favorites 🙃🎮&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="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="nl"&gt;games&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Mario 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The Legend of Zelda Ocarina of Time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Secret of Mana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Metroid&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome! Now that we have our array set up, let's create a sad and simple &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; element where will display it. For the sake of example, let's keep it simple for now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Game title here&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, looking good! Now we have to tell &lt;em&gt;Vue&lt;/em&gt; that we want to output as many &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; elements inside the &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; as needed to loop through our whole array. &lt;/p&gt;

&lt;p&gt;In other languages, and even in vanilla JavaScript, you may be used to doing something that looks similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$game&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$games&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$game&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;endforeach&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where the loop &lt;em&gt;encloses&lt;/em&gt; the element(s) it's going to output or print out.&lt;/p&gt;

&lt;p&gt;In &lt;em&gt;Vue&lt;/em&gt; we declare our &lt;code&gt;v-for&lt;/code&gt; directive on TOP of the element we want to loop. Make these changes to your &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; and we'll dissect them after.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;game in games&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;game&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take a look.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;v-for&lt;/code&gt; was added directly to the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;, not the &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; as we saw earlier. This reads: "For each &lt;code&gt;game&lt;/code&gt; in my &lt;code&gt;games&lt;/code&gt; array, please make a new &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; inside these &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; tags.&lt;/li&gt;
&lt;li&gt;Note that &lt;code&gt;games&lt;/code&gt; is the property that we added earlier with the array inside our &lt;code&gt;data&lt;/code&gt;, so we have to use this variable name.&lt;/li&gt;
&lt;li&gt;The variable &lt;code&gt;game&lt;/code&gt; (singular) is defined by us, we could use &lt;code&gt;item&lt;/code&gt;, &lt;code&gt;game&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt; or whatever we feel like. But be sure to understand that this &lt;code&gt;*game* in games&lt;/code&gt; is what you will be using as a variable inside your loop.&lt;/li&gt;
&lt;li&gt;Finally, inside our &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tag we're outputting the contents of our &lt;code&gt;game&lt;/code&gt; variable, so while the loop is running for each of our games, this will output the string into the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run your app inside the browser, and you should see your list of items being outputted to the screen.&lt;/p&gt;

&lt;h1&gt;
  
  
  Taking it up a notch
&lt;/h1&gt;

&lt;p&gt;So far, so good? &lt;code&gt;v-for&lt;/code&gt; is actually a very simple concept, and this example is super boring. So how about we make things a bit more complicated, by making our array include some objects, and also applying some &lt;code&gt;v-if&lt;/code&gt;s inside our list?&lt;/p&gt;

&lt;p&gt;First things first, let's update our &lt;code&gt;games&lt;/code&gt; property with some more interesting data.&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="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="nl"&gt;games&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Mario 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nintendo 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The Legend of Zelda Ocarina of Time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nintendo 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Secret of Mana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Nintendo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fallout 76&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Multiple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Nintendo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&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;As always feel free to use your own favorite titles. PS. Super Metroid's rating of 6 is not a typo, it's just THAT good - and I'm biased. 😬 Also, Bethesda, you should be ashamed. &lt;em&gt;cough&lt;/em&gt; Anyways.&lt;/p&gt;

&lt;p&gt;If you run your app this point it will not particularly break, but it will just output the objects in a string format, which is not pretty. In fact, we're going to scratch our &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; approach completely, and use a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; to output our information. (Don't worry, it'll still be ugly).&lt;/p&gt;

&lt;p&gt;Update your whole &lt;code&gt;&amp;lt;div id="app"&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"game in games"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ game.name }} - &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&lt;/span&gt;{{ game.console }}&lt;span class="nt"&gt;&amp;lt;/small&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"star in game.rating"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;❤️&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"game.rating &amp;gt; 5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wow, this game must be &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;REALLY&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; good&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WOAH. Ok, maybe not, but don't worry, you already know everything you need to understand what's happening here.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;div v-for="game in games"&lt;/code&gt; Same old, we're going to loop our &lt;code&gt;games&lt;/code&gt; array prop and store each game in the &lt;code&gt;game&lt;/code&gt; variable.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;h1&lt;/code&gt;. Ok, so &lt;code&gt;game&lt;/code&gt; is an object, which in turn holds its own properties, &lt;em&gt;name&lt;/em&gt;, &lt;em&gt;console&lt;/em&gt; and &lt;em&gt;rating&lt;/em&gt;. Inside the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; we're going to output the game's *name: &lt;code&gt;game.name&lt;/code&gt;. And the console: &lt;code&gt;game.console&lt;/code&gt;. As you can see now, &lt;code&gt;v-for&lt;/code&gt; is not limited to outputting just a single element as we saw before with the &lt;code&gt;li&lt;/code&gt;, but you can actually output as much HTML as you need.&lt;/li&gt;
&lt;li&gt;The nested &lt;code&gt;v-for&lt;/code&gt;. So inside the &lt;code&gt;span&lt;/code&gt; element we actually have a nested &lt;code&gt;v-for&lt;/code&gt; loop (which is TOTALLY ok to do), except it's a little different, we're not looping an array or an object. I didn't LIE to you, maybe just withheld some information - like for example, you can actually loop a numeric value (in this case &lt;code&gt;game.rating&lt;/code&gt; and the loop will count up from &lt;code&gt;1&lt;/code&gt; till it reaches the value of the rating. Simple?&lt;/li&gt;
&lt;li&gt;Finally, &lt;code&gt;v-if&lt;/code&gt;. We are going to output a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; tag inside our loop &lt;em&gt;IF&lt;/em&gt; the condition is met, so if and only if the current game's rating is greater than 5. Take a guess which?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Go ahead and run this again in your browser and behold the awesomeness of not bothering with CSS.&lt;/p&gt;

&lt;h1&gt;
  
  
  What if I don't need a wrapping DIV?
&lt;/h1&gt;

&lt;p&gt;If at any point you find yourself making a bunch of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements simply to wrap up your &lt;code&gt;v-for&lt;/code&gt; loops, there's a special HTML tag you can use to help your case. &lt;code&gt;&amp;lt;template&amp;gt;&amp;lt;/template&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you, for example, remove the wrapping &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and change it for &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; take a look at your developer console and you'll see that the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; elements are not wrapped by anything. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8h8b3svfc8a2prnjs8dy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8h8b3svfc8a2prnjs8dy.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; is special, because &lt;em&gt;Vue&lt;/em&gt; will treat it as a wrapper element but it won't be rendered into the HTML when we execute it, so you can safely use it to wrap a bunch of other elements logically for the loop without affecting your markup.&lt;/p&gt;

&lt;h1&gt;
  
  
  The :key attribute
&lt;/h1&gt;

&lt;p&gt;One final thing that I purposely left for the end. The &lt;code&gt;:key&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;When you are looping through elements with &lt;code&gt;v-for&lt;/code&gt; &lt;em&gt;Vue.js&lt;/em&gt; has NO clue how to track your elements for reactivity, because it can't "tell apart" one object from the other. What this means for you is that since &lt;em&gt;Vue&lt;/em&gt; can't do this, it will re-render the WHOLE section of the page that is being created by this loop. In our case it's a very small section and the performance hit would probably be minimal, but it's something that you should keep in mind - and just do it for best practice.&lt;/p&gt;

&lt;p&gt;Now, how do we use it?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;:key&lt;/code&gt; expects some string it'll use to "name" or "track" the element, so we need to give it a unique identifier. In the case of our &lt;code&gt;games&lt;/code&gt; it's simple, we can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"game in games"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"game.name"&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;I'm pretty certain that we're not going to have the same game twice in this list, so this is pretty safe. An &lt;code&gt;id&lt;/code&gt; if you have data coming from a database is also &lt;em&gt;ideal&lt;/em&gt; to use here.&lt;/p&gt;

&lt;p&gt;If you are curious about the intricacies of &lt;code&gt;:key&lt;/code&gt; you can always take a look at the documentation. &lt;a href="https://vuejs.org/v2/guide/list.html#key" rel="noopener noreferrer"&gt;Key's docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In fact, now that you have gotten this far I can't stress enough the importance of getting acquainted with the documentation. &lt;em&gt;Vue.js&lt;/em&gt; 's docs are impressively good, and very very clear with code examples, the documentation team does a fantastic job to keep them updated and clear - big shout out to all of them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final code
&lt;/h1&gt;

&lt;p&gt;Here's the final code, just in case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vue 101&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"game in games"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"game.name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ game.name }} - &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&lt;/span&gt;{{ game.console }}&lt;span class="nt"&gt;&amp;lt;/small&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"star in game.rating"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;❤️&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"game.rating &amp;gt; 5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wow, this game must be &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;REALLY&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; good&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;games&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Mario 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nintendo 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The Legend of Zelda Ocarina of Time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nintendo 64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Secret of Mana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Nintendo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fallout 76&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Multiple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Metroid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Super Nintendo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&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;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Challenge
&lt;/h1&gt;

&lt;p&gt;This time you get a challenge if you wish to accept it. Add a &lt;code&gt;@click&lt;/code&gt; listener to the &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; which outputs the game's rating, and increase the ranking by &lt;code&gt;1&lt;/code&gt; with each click for that UNIQUE game. You already know everything you need to achieve this 😉.&lt;/p&gt;

&lt;p&gt;Tip: You'll need to pass the &lt;code&gt;game&lt;/code&gt; you're looping to the click function, and inspect it.&lt;/p&gt;

&lt;p&gt;Good luck!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
