<?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: Heitor Chang</title>
    <description>The latest articles on DEV Community by Heitor Chang (@heitorchang).</description>
    <link>https://dev.to/heitorchang</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%2F435849%2Fb4b4543d-bf56-4b92-b3ea-82cf58d5cd21.jpeg</url>
      <title>DEV Community: Heitor Chang</title>
      <link>https://dev.to/heitorchang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/heitorchang"/>
    <language>en</language>
    <item>
      <title>Tâches: a Vue 3 To-do List with Vite</title>
      <dc:creator>Heitor Chang</dc:creator>
      <pubDate>Mon, 20 Jul 2020 01:11:30 +0000</pubDate>
      <link>https://dev.to/heitorchang/taches-a-vue-3-to-do-list-with-vite-gn6</link>
      <guid>https://dev.to/heitorchang/taches-a-vue-3-to-do-list-with-vite-gn6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is my first project while learning Vue 3, so it probably won’t be “best practices”. Still, I hope you can learn something from this post. And I can probably learn something from &lt;em&gt;you&lt;/em&gt; as well, just leave some comments below! &lt;/p&gt;

&lt;p&gt;See the completed project here: &lt;a href="https://taches.surge.sh/"&gt;https://taches.surge.sh/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Following the trend of using French names (Vue and Vite), I named the project “Tâches” (tasks). There will be no more French words, I promise!&lt;/p&gt;

&lt;p&gt;To begin, create a new Vite project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init vite-app taches
cd taches
npm install
npm run dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, you will want to replace &lt;code&gt;HelloWorld&lt;/code&gt; in &lt;code&gt;src/App.vue&lt;/code&gt; with your own &lt;code&gt;&amp;lt;TodoList /&amp;gt;&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight vue"&gt;&lt;code&gt;//    src/App.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TodoList&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

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

 &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;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;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;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="nx"&gt;TodoList&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, let’s write &lt;code&gt;src/components/TodoList.vue&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Our template will contain a simple table with 3 columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a checkbox for marking the todo as done&lt;/li&gt;
&lt;li&gt;the description of the todo&lt;/li&gt;
&lt;li&gt;an action button (&lt;em&gt;Add&lt;/em&gt; in the first row and &lt;em&gt;Delete&lt;/em&gt; in the remaining rows, when &lt;em&gt;done&lt;/em&gt; is checked)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight vue"&gt;&lt;code&gt;//    src/components/TodoList.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Tâches&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;table&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"newDescription"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Add a description..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;td&amp;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;"addTodo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Add Todo&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Todo&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"todo in todos"&lt;/span&gt; &lt;span class="na"&gt;:data=&lt;/span&gt;&lt;span class="s"&gt;"todo"&lt;/span&gt; &lt;span class="na"&gt;v-on:delete-todo=&lt;/span&gt;&lt;span class="s"&gt;"deleteTodo(todo.id)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/Todo&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There's a lot of Vue-specific attributes above, so let's take a closer look:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;v-model="newDescription"&lt;/code&gt; ties the text input's value to a variable named &lt;code&gt;newDescription&lt;/code&gt; that I will show below.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@click="addTodo"&lt;/code&gt; is a click event listener that will call &lt;code&gt;addTodo()&lt;/code&gt; when this button is clicked&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;v-for="todo in todos"&lt;/code&gt; iterates over &lt;code&gt;todos&lt;/code&gt; (a list that will be defined below).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:data="todo"&lt;/code&gt; &lt;em&gt;binds&lt;/em&gt; the value of &lt;code&gt;todo&lt;/code&gt; as a prop to the component &lt;code&gt;Todo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;v-on:delete-todo="deleteTodo(todo.id)&lt;/code&gt; listens to when &lt;code&gt;delete-todo&lt;/code&gt; is emitted by the &lt;code&gt;Todo&lt;/code&gt; component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's tackle the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; part of the &lt;code&gt;TodoList&lt;/code&gt; component! In this demo, I will use &lt;code&gt;localStorage&lt;/code&gt; to persist the todos. I just couldn't figure out a simple enough REST API setup that's easy and free to use, so your todos will be stuck to whatever device you used to access this project.&lt;/p&gt;

&lt;p&gt;Let's start with the imports. I will use &lt;code&gt;ref&lt;/code&gt;, &lt;code&gt;reactive&lt;/code&gt;, and &lt;code&gt;watch&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight vue"&gt;&lt;code&gt;//    src/components/TodoList.vue

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  // ...
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watch&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;vue&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="nx"&gt;Todo&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;./Todo.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

 &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Todo.vue&lt;/code&gt; holds the component source that represents a single todo item. It's very simple and I'll leave it for last.&lt;/p&gt;

&lt;p&gt;As mentioned, I use localStorage for data persistence. Loading and saving data is done like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight vue"&gt;&lt;code&gt;//    src/components/TodoList.vue

// ...

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watch&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;vue&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="nx"&gt;Todo&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;./Todo.vue&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="nx"&gt;loadTodos&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;localTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_taches_todos&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;localTodos&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&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="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="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;loadTodos loaded: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;localTodos&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localTodos&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;function&lt;/span&gt; &lt;span class="nx"&gt;saveTodos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_taches_todos&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

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



&lt;p&gt;&lt;code&gt;todos&lt;/code&gt; is a list of todo items, where an item is an object like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{"id":1595202004079,"done":true,"description":"write a blog post"}&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;id&lt;/code&gt; is a timestamp created with &lt;code&gt;Date.now()&lt;/code&gt;. Since we use localStorage and assuming the system time is never changed, it should be unique.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;done&lt;/code&gt; is the state of the checkbox, representing whether the todo is completed or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;description&lt;/code&gt; describes the todo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So let's get to the Vue part already!&lt;/p&gt;

&lt;p&gt;Right after the localStorage functions, add these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight vue"&gt;&lt;code&gt;//    src/components/TodoList.vue

 // ...

 export default {
     setup() {
         const newDescription = ref('');
         const todos = reactive(loadTodos());

         function addTodo() {
             todos.push({ id: Date.now(), done: false, description: newDescription.value });
             newDescription.value = '';
         }

         function deleteTodo(id) {
             console.log("Delete todo with id: " + id);
             for (let i = 0; i &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nt"&gt;todos.length&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt; &lt;span class="na"&gt;i&lt;/span&gt;&lt;span class="err"&gt;++)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
                 &lt;span class="na"&gt;if&lt;/span&gt; &lt;span class="na"&gt;(todos[i].id =&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
                     &lt;span class="na"&gt;todos.splice&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;i&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="err"&gt;1);&lt;/span&gt;
                     &lt;span class="na"&gt;break&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
                 &lt;span class="err"&gt;}&lt;/span&gt;
             &lt;span class="err"&gt;}&lt;/span&gt;
         &lt;span class="err"&gt;}&lt;/span&gt;

         &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newTodos&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prevTodos) =&lt;/span&gt;&lt;span class="err"&gt;&amp;gt; &lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;
             &lt;span class="na"&gt;saveTodos&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newTodos&lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;
         &lt;span class="err"&gt;});&lt;/span&gt;

         &lt;span class="na"&gt;return&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
             &lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;newDescription&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;addTodo&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;deleteTodo&lt;/span&gt;
         &lt;span class="err"&gt;}&lt;/span&gt;
     &lt;span class="err"&gt;},&lt;/span&gt;
     &lt;span class="na"&gt;components:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;Todo&lt;/span&gt;
     &lt;span class="err"&gt;}&lt;/span&gt;
 &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I am using the new &lt;code&gt;setup()&lt;/code&gt;, and inside I define the reactive variables &lt;code&gt;newDescription&lt;/code&gt; and &lt;code&gt;todos&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; The proper use of &lt;code&gt;ref&lt;/code&gt; and &lt;code&gt;reactive&lt;/code&gt; is not clear to me. Some people claim to always use one or the other. They both must have their proper use cases, please search around for more info. &lt;/p&gt;

&lt;p&gt;From what I gathered, &lt;code&gt;ref&lt;/code&gt; is used for scalar types (primitives), while &lt;code&gt;reactive&lt;/code&gt; is more appropriate for objects and arrays.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;newDescription&lt;/code&gt; is used to create new todos, while &lt;code&gt;todos&lt;/code&gt; is an array that holds all the data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;addTodo()&lt;/code&gt; appends a new todo object to the &lt;code&gt;todos&lt;/code&gt; array. Note that I don't pass any arguments--the value of the reactive variable &lt;code&gt;newDescription&lt;/code&gt;, tied to the text input, is used.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;deleteTodo&lt;/code&gt; takes the &lt;code&gt;id&lt;/code&gt; associated with the &lt;code&gt;&amp;lt;Todo&amp;gt;&lt;/code&gt; element, and the &lt;code&gt;todos&lt;/code&gt; array is spliced so that the chosen todo object is removed.&lt;/p&gt;

&lt;p&gt;I am specifically using &lt;code&gt;todos&lt;/code&gt; in &lt;code&gt;watch&lt;/code&gt; instead of &lt;code&gt;watchEffect&lt;/code&gt;, because I only care about &lt;code&gt;todos&lt;/code&gt; changing.&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;watch&lt;/code&gt;, I save the current state of the &lt;code&gt;todos&lt;/code&gt; array in localStorage.&lt;/p&gt;

&lt;p&gt;Finally, we return the pieces used in the template: &lt;code&gt;todos&lt;/code&gt;, &lt;code&gt;newDescription&lt;/code&gt;, &lt;code&gt;addTodo&lt;/code&gt; and &lt;code&gt;deleteTodo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Todo&lt;/code&gt; component is also used, so it must be added to &lt;code&gt;components&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight vue"&gt;&lt;code&gt;//    src/components/TodoList.vue

     // ...
     components: {
         Todo
     }
 }
&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;Speaking of &lt;code&gt;Todo&lt;/code&gt;, this component looks like this (it's saved in &lt;code&gt;src/components/Todo.vue&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"checkbox"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"data.done"&lt;/span&gt; &lt;span class="na"&gt;:checked=&lt;/span&gt;&lt;span class="s"&gt;"data.done"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"data.done"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;"$emit('delete-todo')"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Delete&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;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;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;data&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="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The information used in each &lt;code&gt;Todo&lt;/code&gt; is passed as a &lt;code&gt;data&lt;/code&gt; prop from &lt;code&gt;TodoList&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The checkbox tracks &lt;code&gt;data.done&lt;/code&gt;, and its &lt;code&gt;checked&lt;/code&gt; attribute matches the state of &lt;code&gt;data.done&lt;/code&gt; as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The value of the description is obtained with &lt;code&gt;{{ data.description }}&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Delete button only appears if &lt;code&gt;data.done&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, controlled by &lt;code&gt;v-if&lt;/code&gt;. &lt;code&gt;$emit&lt;/code&gt; sends &lt;code&gt;'delete-todo'&lt;/code&gt; to its parent, &lt;code&gt;TodoList&lt;/code&gt;, which will then call &lt;code&gt;deleteTodo(todo.id)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, we just need to say that &lt;code&gt;data&lt;/code&gt; is an Object inside &lt;code&gt;props: { ... }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A minor detail in the default CSS will center the text of each description. You may edit &lt;code&gt;src/index.css&lt;/code&gt; and remove &lt;code&gt;text-align: center;&lt;/code&gt; if it annoys you (it did annoy me).&lt;/p&gt;

&lt;p&gt;And that's all! The source code is available at &lt;a href="https://github.com/heitorchang/taches"&gt;https://github.com/heitorchang/taches&lt;/a&gt; and again, a built page is available at &lt;a href="https://taches.surge.sh"&gt;https://taches.surge.sh&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;To build your project, just run &lt;code&gt;npm run build&lt;/code&gt;.  Until next time!&lt;/p&gt;

</description>
      <category>vue</category>
    </item>
  </channel>
</rss>
