用Vue 对ToDoList 的初步实现

用Vue 对ToDoList 的初步实现

1.输入框的实现:

<input type="text" v-model="value" @keydown.enter="add">

v-model=“value” 用来进行输入数据的双向绑定。

@keydown.enter=“add” 用来添加事件。

而时间的添加需要考虑很多,暂且考虑到的是输入的值为空怎么办,输入的数据存到哪里。

所以data 数据中除了value外还需要一个列表数组(list :[])来存放数据。

这样初步的add事件如下:

add(){
     if(this.value.trim() == '') return
      this.list.push(value:this.value)
      this.value =''
   },

2. 列表:

因为正在进行和已完成的列表类似,已完成列表可以在正在进行中列表进行修改,扩展。

2.1 正在进行中:

首先进行页面的布置,所需要的元素有列表,列表中的复选框、文本框、删除按钮。要说的是文本框的作用,在修改时出现文本框进行修改,这里涉及到弹出的时机的问题,后面会提到。

<ul>
    <li v-for = "(item,index) in list" :key="index" >
    	<input type="checkbox" @click.prevent = "changeState(item)">
      	<span @click= "changeInd(item,index)">{{item}}</span>  
    	<input type="text" @blur = "changeVlu" v-model="changeValue">
    	<b @click = "del(index)">删除</b>
    </li>
  </ul>

其中 : li 根据list 列表中的数据进行遍历创建标签。

另:v-for循环数据,当用for来更新已经被渲染的元素时,需要为每项添加key(也就是每项的唯一id),为了使 Vue能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。

​ 复选框的点击事件与本身有冲突所以在点击事件上添加prevent 来避免,达到改变list的完成情况。

​ 输入文本添加span标签和点击事件的要和下面的input输入框进行交互显示,当点击span时span隐藏,input显示。而需要修改的文本也需要一个变量来暂时的储存,所以用changeValue 来双向绑定。然后添加失焦事件来进行修改。同时还需要的时修改元素的下标。changeIndex。

重点 : 如何判断 事情的完成情况?

分析: 当输入完成后状态为”正在进行中“,点击复选框改变状态”已完成“。这就需要一个参数来表明状态。这就需要在添加时就表明状态,所以对添加事件进行修改。

add(){
     if(this.value.trim() == '') return
      this.list.push({
        value:this.value,
        done: false
        })
      this.value =''
   }

用done来解决这个问题。

具体事件如下:

//状态
changeState(item){
     item.done = !item.done
   },
//修改事件
changeInd(item,index){
     this.changeIndex = index;
     this.changeValue = item.value
   },
//修改输入框事件
changeVlu(){
     this.list[this.changeIndex].value = this.changeValue;
     this.changeIndex=-1;
     this.chengeValue ='';
   }
//删除事件
del(index){
     this.list.splice(index,1)
   },

用v-show=“item.done” 来判断li的显示与隐藏。

用changeIndex 的值来判断span和input的显示与隐藏,等于-1时span显示,当等于当前下标时input显示。

2.2 已完成

已完成部分与正在进行中部分大相径庭。需要修改的是当前复选框的选中状态 和li 的显示状态。

3. 存储实现:

存储只需要监听list的变化来用localStorage存储。

localStorage.setItem('todolist',JSON.stringify(arr))

因为list数组中存储着对象,所以监听要进行深度监听 。

而页面加载完成后需要将localStorage的数据读取 ,所以要使用生命周期函数来给list初始化。

4.list 中数据的数量:

使用计算属性,来统计”已完成“和”正在进行中“的数量。用过滤器来进行统计。

this.list.filter(item =>{
     return item.done == false;
      }

5.具体代码:

//页面部分
<template>
  <div>
   <input type="text" v-model="value" @keydown.enter="add">
  <hr>
  <h2>正在进行中({{yesNum}})</h2>
  <ul>
    <li v-for = "(item,index) in list" :key="index" v-show="!item.done">
    <input type="checkbox" @click.prevent = "changeState(item)">&nbsp;&nbsp;&nbsp;&nbsp;
    <span @click= "changeInd(item,index)" v-show="changeIndex !==index">{{item.value}}</span>  &nbsp;&nbsp;&nbsp;&nbsp;
    <input type="text" v-show="index==changeIndex" @blur = "changeVlu" v-model="changeValue">
    <b @click = "del(index)">删除</b>
    </li>
  </ul>
   <hr>
  <h2>已完成({{noNum}})</h2>
  <ul>
    <li v-for = "(item,index) in list" :key="index" v-show="item.done">
    <input type="checkbox" checked @click.prevent = "changeState(item)">&nbsp;&nbsp;&nbsp;&nbsp;
    <span @click= "changeInd(item,index)" v-show="changeIndex==-1">{{item.value}}</span>  &nbsp;&nbsp;&nbsp;&nbsp;
    <input type="text" v-show="changeIndex==index" @blur = "changeVlu" v-model="changeValue">
    <b @click = "del(index)">删除</b>
    </li>
  </ul>
  </div>
</template>
//数据
data(){
    return {
     value : '',
     list : [],
     changeIndex:-1,
     changeValue : ''
    }
  }
//计算属性
computed:{
    yesNum(){
      let arr = this.list.filter(item =>{
         return item.done == false;
      })
      return arr.length;
    },
    noNum(){
      let arr = this.list.filter(item =>{
         return item.done == true;
      })
      return arr.length;
    }
  }
//生命周期
created(){  
      let list =  localStorage.getItem('todolist')
      if(list){
        this.list = JSON.parse(list)
      }
  }
//监听
watch:{
     list :{
       handler(arr){
         localStorage.setItem('todolist',JSON.stringify(arr))
       },
       deep:true
     }
  }
//方法
methods: {
   add(){
     if(this.value.trim() == '') return
      this.list.push({
        value:this.value,
        done: false
        })
      this.value =''
   },
   del(index){
     this.list.splice(index,1)
   },
   changeState(item){
     item.done = !item.done
   },
   changeInd(item,index){
     this.changeIndex = index;
     this.changeValue = item.value
   },
   changeVlu(){
     this.list[this.changeIndex].value = this.changeValue;
     this.changeIndex=-1;
     this.chengeValue ='';
   }
  }


hangeInd(item,index){
     this.changeIndex = index;
     this.changeValue = item.value
   },
   changeVlu(){
     this.list[this.changeIndex].value = this.changeValue;
     this.changeIndex=-1;
     this.chengeValue ='';
   }
  }

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值