search
HomeWeb Front-endCSS TutorialDetailed explanation of the use of Vue's todoMVC

This time I will bring you a detailed explanation of the use of Vue's todoMVC. What are the precautions for using Vue's todoMVC? The following is a practical case, let's take a look.

This example is written in my own way by imitating the style and function of the official website example. Basically, I did not look at the source code of the official website, only referring to the custom instructions. Let’s explore it step by step. Official website demo

Function to be realized

  1. Single add todo

  2. Single delete todo

  3. Double-click to edit todo

  4. A single todo has been completed and the corresponding style status has changed

  5. All todos have been completed Corresponding style status changes

  6. Clear all completed todos

  7. Display the number of todos to be done

  8. Filter all todos, completed todos, unfinished todos

##Add a single todo

<input ref="currentInput">//操作input元素使enter一下之后清空输入框内容
data() {//一些初始化数据
 return {
  todolists: [],
  dataStatus: ["All", "Active", "Completed"],
  dataStatusIndex: 0,
  whichShow: true,
  defaultShow: true
 }
},
addTodo(e) { //添加todo
 var val = e.value
 if (val === "") {return} //如果输入内容为空则立即返回
 this.todoLists = this.todoLists.concat({//使用concat这个api添加todo
  value: val, //输入内容
  isEditing: false, //是否在编辑状态
  isActive: false, //删除X图标是否激活
  isChecked: false //是否已完成
 })
 this.$refs.currentInput.value = "" //按下enter添加todo之后把输入框value清零
 window.localStorage.setItem("content",JSON.stringify(this.todoLists))//使用localStorage以JSON格式存储数据
},
Add each todo The corresponding states of each todo are stored in the same object. When the todo state is changed by an operation, they will not be processed uniformly, so that each todo has a separate state.

Single deletion of todo

 
  •  //绑定删除单条todo事件  
  • deleteTodo(index) { //删除单条todo
      this.todoLists.splice(index, 1)//使用splice的api
      window.localStorage.setItem("content",JSON.stringify(todoLists)) //以JSON格式存储数据//localStorage存储数据
    },
    The events of mouse movement in and out are bound to each li element to dynamically change the isActive of each todo, and then Use isActive to dynamically display classes.

    Double-click to edit todo&&single todo has been completed

    <input v-model="list.isChecked">//双向绑定isChecked
    <p v-show="!list.isEditing" :class="{deleted:list.isChecked}"> //动态绑定class该表已完成todo样式
    {{list.value}}
    </p>
    <input v-model="list.value" v-show="list.isEditing" v-todo-focus="list.value"> //绑定blur失去焦点事件
    methods: {
     toEdit(obj) { //使添加的todothing可编辑
      obj.isEditing = true
     },
     
     unEdit(obj) { //使添加的todothing不可编辑
      obj.isEditing = false
     },
    }
    directives: { //自定义focus指令,需要一个binding参数做判断
     "todo-focus": function (el, binding) {
      if (binding.value) {
       el.focus()
      }
     }
    }
    Use the isEditing attribute in each todo to control the show and whether it can be edited. Double-click p to change the current todo. isEditing is true, so it is displayed as input. After the input loses focus, it is changed to false through the blur event.

    Use todo's idChecked to control whether it is completed, thereby dynamically changing the style.

    All todos have been completed

    <span class="icon-down el-icon-arrow-down" v-show="todoLists.length>0"></span> //全部已完成事件
    selectAllTodos() { //设置所有todo为已完成,使用map的api通过todo的isChecked属性操作
     this.todoLists.map(todo => todo.isChecked = todo.isChecked ? false : true)
    }

    The number of todos to do is displayed

    <p> //times为0显示item,大于0显示items,细节注定成败
     <span>{{times}}</span>&nbsp item left
    </p>
    <p> 0">
    <span>{{times}}</span>&nbsp items left</p>
    computed: {
     times() { //使用计算属性计算待办todos的次数 
      let todoArr = this.todoLists
      let times = 0
      for (let i = 0; i Using calculated attributes to calculate todoLists, use The for loop selects the accumulation of idChecked as true, and finally returns times. <p style="text-align: left;"></p><p style="text-align: left;">Clear all completed todos<strong></strong></p><pre class="brush:php;toolbar:false"><p v-show="times < todoLists.length"> //如果待办事件次数小于总todoLists长度就显示“clear completed”
     <a>clear completed</a>
    </p>
    <p v-show="times === todoLists.length"> //如果待办事件次数等于总todoLists长度就显示“clear completed”
     <a></a>
    </p>
    clearTodos() { //清空已完成的todoLists,使用filter的api进行筛选
     this.todoLists = this.todoLists.filter(todo => todo.isChecked === false)
     window.localStorage.setItem("content",JSON.stringify(this.todoLists)) //以json格式存储数据
    },
    If the times of todo todos are less than the length of todoLists, it proves that there are completed todos, and "clear completed" can be displayed. If they are equal, it means there is no completed todo.

    Three status filtering

    All todos, completed todos, unfinished todos filtering

    
    
  •     {{item}}  

    switchStatus(index) { //通过if条件判断操作
     this.dataStatusIndex = index
     if (this.dataStatus[index] === "Active") {
      this.defaultShow = false
      this.whichShow = false
     } else if (this.dataStatus[index] === "Completed") {
      this.defaultShow = false
      this.whichShow = true
     } else if (this.dataStatus[index] === "All") {
      this.defaultShow = true
     }
    },
    I am here to judge the operation of if conditional sentences at the same time, It's a bit troublesome, and I haven't thought of any other solutions yet. Use the

    ternary operator operator and the or operator on the li element to display todos in different states.

    Complete code

    <style>
     * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
     }
     input {
      outline: none;
     }
     ul,
     li,
     ol {
      list-style: none;
     }
     #app {
      width: 800px;
      height: 900px;
      margin: 0 auto;
      text-align: center;
      background-color: rgb(245, 245, 245);
      padding: 24px 0;
     }
     #app .header {
      font-size: 48px;
     }
     .content {
      width: 72%;
      margin: 0 auto;
      box-shadow: 0 3px 3px 2px rgba(0, 0, 0, 0.25);
      position: relative;
     }
     .icon-down {
      position: absolute;
      font-size: 24px;
      top: 16px;
      left: 16px;
      cursor: pointer;
     }
     #app .content .todos_add {
      width: 100%;
      height: 56px;
      padding: 16px 56px;
      font-size: 24px;
      border: 1px solid transparent;
     }
     .content_todoLists {
      position: relative;
      z-index: 3;
     }
     .content_todoList {
      display: flex;
      flex-direction: row;
      border-top: 1px solid #ccc;
      font-size: 24px;
      padding: 8px;
      background-color: white;
      align-items: center;
     }
     .checkBox {
      width: 20px;
      height: 20px;
      margin-left: 10px;
     }
     .content_todoList_main {
      flex: 1;
      text-align: left;
      margin-left: 16px;
      font-size: 20px;
      padding: 6px 0;
     }
     .main_input {
      position: relative;
      z-index: 1;
     }
     .content_todoList_delete {
      position: absolute;
      right: 16px;
      color: rgb(252, 55, 55);
      font-weight: 500;
      display: none;
      cursor: pointer;
     }
     .show {
      display: block;
     }
     .deleted {
      text-decoration-line: line-through;
      color: #bbb;
     }
     .show:hover {
      color: rgb(255, 0, 0);
      font-weight: 700;
     }
     ::-moz-placeholder {
      color: rgb(221, 218, 218);
     }
     ::-webkit-input-placeholder {
      color: rgb(221, 218, 218);
     }
     :-ms-input-placeholder {
      color: rgb(221, 218, 218);
     }
     .data {
      display: flex;
      justify-content: space-between;
      padding: 8px;
      font-size: 14px;
      font-weight: 300;
      color: rgb(145, 145, 145);
     }
     a {
      text-decoration: none;
      color: rgb(145, 145, 145);
     }
     .data_times {
      width: 73px;
     }
     .data_clearTodos {
      width: 142px;
     }
     .data_status a {
      display: inline-block;
      border: 1px solid transparent;
      border-radius: 2px;
      padding: 1px 4px;
      margin: 0 2px;
     }
     .data_status a:hover {
      border-color: #bbb;
     }
     .data_clearTodos a:hover {
      text-decoration-line: underline;
     }
     .active {
      box-shadow: 0 0 1px black;
     }
    </style>
     <p>
      <header>todos</header>
      </p><p>
       <span>0" 
       @click="selectAllTodos">
       </span>
       <input>
       </p>
          
    •            

            {{list.value}}      

                      
    •    
       

    0">     

         {{times}} item left     

        

     0">      {{times}} items left     

        

                {{item}}           

        

         clear completed     

        

              

             <script> let vm = new Vue({ el: "#app", data() { return { todoLists: [], dataStatus: ["All", "Active", "Completed"], dataStatusIndex: 0, whichShow: true, defaultShow: true } }, computed: { times() { //使用计算属性计算待办todos的次数 let todoArr = this.todoLists let times = 0 for (let i = 0; i < todoArr.length; i++) { if (todoArr[i].isChecked === false) { times++ } } return times } }, methods: { toEdit(obj) { //使添加的todo可编辑 obj.isEditing = true }, unEdit(obj) { //使添加的todo不可编辑 obj.isEditing = false }, addTodo(e) { //添加todo var val = e.value if (val === "") { return } //如果输入内容为空则立即返回 this.todoLists = this.todoLists.concat({ //使用concat这个api添加todo value: val, //输入内容 isEditing: false, //是否在编辑状态 isActive: false, //删除X图标是否激活 isChecked: false //是否已完成 }) this.$refs.currentInput.value = "" //按下enter添加todo之后把输入框value清零 window.localStorage.setItem("content", JSON.stringify(this.todoLists)) //使用localStorage以JSON格式存储数据 }, deleteTodo(index) { //删除todo this.todoLists.splice(index, 1) window.localStorage.setItem("content", JSON.stringify(this.todoLists)) //以json格式存储数据 }, switchStatus(index) { //试下下方三个状态切换,略麻烦 this.dataStatusIndex = index if (this.dataStatus[index] === "Active") { this.defaultShow = false this.whichShow = false } else if (this.dataStatus[index] === "Completed") { this.defaultShow = false this.whichShow = true } else if (this.dataStatus[index] === "All") { this.defaultShow = true } }, clearTodos() { //清空已完成的todoLists this.todoLists = this.todoLists.filter(todo => todo.isChecked === false) window.localStorage.setItem("content", JSON.stringify(this.todoLists)) //以json格式存储数据 }, selectAllTodos() { //设置所有todo为已完成 this.todoLists.map(todo => todo.isChecked = todo.isChecked ? false : true) } }, directives: { //自定义focus指令 "todo-focus": function (el, binding) { if (binding.value) { el.focus() } } }, created() { let myStorage = window.localStorage.getItem(&#39;content&#39;) this.todoLists = JSON.parse(myStorage) || [] //因为todoLists初始值是null,使用或运算符,如果为null设为空数组 } }) </script> I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the php Chinese website!

    Recommended reading:

    Angular2 parent-child component communication method

    Javascript code optimization detailed explanation

  • The above is the detailed content of Detailed explanation of the use of Vue's todoMVC. For more information, please follow other related articles on the PHP Chinese website!

    Statement
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
    The Ultimate Guide to Linking CSS Files in HTMLThe Ultimate Guide to Linking CSS Files in HTMLMay 13, 2025 am 12:02 AM

    Linking CSS files to HTML can be achieved by using elements in part of HTML. 1) Use tags to link local CSS files. 2) Multiple CSS files can be implemented by adding multiple tags. 3) External CSS files use absolute URL links, such as. 4) Ensure the correct use of file paths and CSS file loading order, and optimize performance can use CSS preprocessor to merge files.

    CSS Flexbox vs Grid: a comprehensive reviewCSS Flexbox vs Grid: a comprehensive reviewMay 12, 2025 am 12:01 AM

    Choosing Flexbox or Grid depends on the layout requirements: 1) Flexbox is suitable for one-dimensional layouts, such as navigation bar; 2) Grid is suitable for two-dimensional layouts, such as magazine layouts. The two can be used in the project to improve the layout effect.

    How to Include CSS Files: Methods and Best PracticesHow to Include CSS Files: Methods and Best PracticesMay 11, 2025 am 12:02 AM

    The best way to include CSS files is to use tags to introduce external CSS files in the HTML part. 1. Use tags to introduce external CSS files, such as. 2. For small adjustments, inline CSS can be used, but should be used with caution. 3. Large projects can use CSS preprocessors such as Sass or Less to import other CSS files through @import. 4. For performance, CSS files should be merged and CDN should be used, and compressed using tools such as CSSNano.

    Flexbox vs Grid: should I learn them both?Flexbox vs Grid: should I learn them both?May 10, 2025 am 12:01 AM

    Yes,youshouldlearnbothFlexboxandGrid.1)Flexboxisidealforone-dimensional,flexiblelayoutslikenavigationmenus.2)Gridexcelsintwo-dimensional,complexdesignssuchasmagazinelayouts.3)Combiningbothenhanceslayoutflexibilityandresponsiveness,allowingforstructur

    Orbital Mechanics (or How I Optimized a CSS Keyframes Animation)Orbital Mechanics (or How I Optimized a CSS Keyframes Animation)May 09, 2025 am 09:57 AM

    What does it look like to refactor your own code? John Rhea picks apart an old CSS animation he wrote and walks through the thought process of optimizing it.

    CSS Animations: Is it hard to create them?CSS Animations: Is it hard to create them?May 09, 2025 am 12:03 AM

    CSSanimationsarenotinherentlyhardbutrequirepracticeandunderstandingofCSSpropertiesandtimingfunctions.1)Startwithsimpleanimationslikescalingabuttononhoverusingkeyframes.2)Useeasingfunctionslikecubic-bezierfornaturaleffects,suchasabounceanimation.3)For

    @keyframes CSS: The most used tricks@keyframes CSS: The most used tricksMay 08, 2025 am 12:13 AM

    @keyframesispopularduetoitsversatilityandpowerincreatingsmoothCSSanimations.Keytricksinclude:1)Definingsmoothtransitionsbetweenstates,2)Animatingmultiplepropertiessimultaneously,3)Usingvendorprefixesforbrowsercompatibility,4)CombiningwithJavaScriptfo

    CSS Counters: A Comprehensive Guide to Automatic NumberingCSS Counters: A Comprehensive Guide to Automatic NumberingMay 07, 2025 pm 03:45 PM

    CSSCountersareusedtomanageautomaticnumberinginwebdesigns.1)Theycanbeusedfortablesofcontents,listitems,andcustomnumbering.2)Advancedusesincludenestednumberingsystems.3)Challengesincludebrowsercompatibilityandperformanceissues.4)Creativeusesinvolvecust

    See all articles

    Hot AI Tools

    Undresser.AI Undress

    Undresser.AI Undress

    AI-powered app for creating realistic nude photos

    AI Clothes Remover

    AI Clothes Remover

    Online AI tool for removing clothes from photos.

    Undress AI Tool

    Undress AI Tool

    Undress images for free

    Clothoff.io

    Clothoff.io

    AI clothes remover

    Video Face Swap

    Video Face Swap

    Swap faces in any video effortlessly with our completely free AI face swap tool!

    Hot Article

    Hot Tools

    SublimeText3 English version

    SublimeText3 English version

    Recommended: Win version, supports code prompts!

    SecLists

    SecLists

    SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

    Dreamweaver CS6

    Dreamweaver CS6

    Visual web development tools

    Notepad++7.3.1

    Notepad++7.3.1

    Easy-to-use and free code editor

    SublimeText3 Mac version

    SublimeText3 Mac version

    God-level code editing software (SublimeText3)