一、需求简述:
1、在输入框内输入待办事项,回车后添加到列表;
2、点击此事项可以将其状态改为已完成,再次点击变为未完成;
3、可以实现已完成、未完成筛选;
4、计数;
5、在全部列表中可以进行删除;
二、实现要点:
1、在输入框内输入待办事项,回车后添加到列表;
输入框监听回车按键,调用clickenter方法,向存放全部数据的数组rowdatas中push一组数据。
clickenter() {
  this.rowdatas.push({
     text: this.val,
     col: false
   });
   this.val = "";
},2、点击此事项可以将其状态改为已完成,再次点击变为未完成;
全部列表中遍历rowdatas数组,并根据每一条数据的col属性,判断是否已完成,进行绑定class,
在li中的p标签监听点击事件(防止事件冒泡带来的影响),调用gofinish(index),并将本条数据中的col属性取反,实现状态改变。
<li v-if="seled == '全部'" v-bind:class="{coled:rowdata.col}" v-for="(rowdata,index) in rowdatas">
  <p @click="gofinish(index)">{{rowdata.text}}</p>
  <button @click="del(index)">删除</button>
</li>gofinish: function(index) {
  this.rowdatas[index].col = !this.rowdatas[index].col;
},3、可以实现已完成、未完成筛选;
设置两个新数组nofinish、finish用来存储已完成和未完成列表的数据,并多创建两个li遍历这两个数组,使用v-if判断select筛选中的值,来决定到底遍历哪一个数组。
<select v-model="seled">
  <option :value="sel" v-for="(sel,index) in sels">{{sel}}</option>
</select>
<ul>
  <li v-if="seled == '全部'" v-bind:class="{coled:rowdata.col}" v-for="(rowdata,index) in rowdatas">
    <p @click="gofinish(index)">{{rowdata.text}}</p>
    <button @click="del(index)">删除</button>
  </li>
  <li v-if="seled == '未完成'" v-bind:class="{coled:rowdata.col}" v-for="(rowdata,index) in nofinish">{{rowdata.text}}</li>
  <li v-if="seled == '已完成'" v-bind:class="{coled:rowdata.col}" v-for="(rowdata,index) in finish">{{rowdata.text}}</li>
</ul>4、计数
使用computed计算属性,计算ischange(当前数量)的值,判断select的选中的选项,如果是全部,那么返回数量为rowdatas数组的长度(全部事件数量),如果为未完成,那么从rowdatas中使用filter筛选出col属性为false的数据并赋值给nofinish数组,最后返回nofinish数组的长度。已完成同未完成理论。
computed: {
 ischange: function() {
    if (this.seled == "全部") {
      return this.rowdatas.length
    } else if (this.seled == "未完成") {
      this.nofinish = this.rowdatas.filter(function(arr) {
         return arr.col == false;
        }
      );
      return this.nofinish.length
    } else if (this.seled == "已完成") {
       this.finish = this.rowdatas.filter(function(arr) {
         return arr.col == true;
        }
      );
      return this.finish.length
    }
  }
}5、在全部列表中可以进行删除;
点击删除按钮调用del函数,从rowdatas中删除此条数据
del: function(index) {
  this.rowdatas.splice(index, 1);
}三、项目截图

四、项目代码
<template>
  <div class="todolist2">
    <header class="header">
      <h1>{{message}}</h1><input placeholder="请输入待办事项" @keyup.enter="clickenter" type="text" v-model="val">
    </header>
    <div class="content">
      <select v-model="seled">
        <option :value="sel" v-for="(sel,index) in sels">{{sel}}</option>
      </select>
      <ul>
        <li v-if="seled == '全部'" v-bind:class="{coled:rowdata.col}" v-for="(rowdata,index) in rowdatas">
          <p @click="gofinish(index)">{{rowdata.text}}</p>
          <button @click="del(index)">删除</button>
        </li>
        <li v-if="seled == '未完成'" v-bind:class="{coled:rowdata.col}" v-for="(rowdata,index) in nofinish">{{rowdata.text}}</li>
        <li v-if="seled == '已完成'" v-bind:class="{coled:rowdata.col}" v-for="(rowdata,index) in finish">{{rowdata.text}}</li>
      </ul>
    </div>
    <span>{{ischange}}</span>
  </div>
</template>
<script>
export default {
  name: "todolist2",
  data() {
    return {
      message: "this is a todolist",
      val: "",
      rowdatas: [],
      sels: ["全部", "已完成", "未完成"],
      seled: "全部",
      nofinish:[],
      finish:[]
    };
  },
  methods: {
    clickenter() {
      this.rowdatas.push({
        text: this.val,
        col: false
      });
      this.val = "";
    },
    gofinish: function(index) {
      this.rowdatas[index].col = !this.rowdatas[index].col;
    },
    del: function(index) {
      this.rowdatas.splice(index, 1);
    }
  },
  computed: {
    ischange: function() {
      if (this.seled == "全部") {
        return this.rowdatas.length
      } else if (this.seled == "未完成") {
        this.nofinish = this.rowdatas.filter(function(arr) {
           return arr.col == false;
          }
        );
        return this.nofinish.length
      } else if (this.seled == "已完成") {
         this.finish = this.rowdatas.filter(function(arr) {
           return arr.col == true;
          }
        );
        return this.finish.length
      }
    }
  }
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.header {
  width: 100%;
  height: 80px;
  background-color: #000;
  color: #ffffff;
}
.header h1 {
  width: 50%;
  float: left;
  text-align: center;
}
.header input {
  margin-top: 30px;
}
.coled {
  background-color: #eeeeee;
}
ul li{
  width:100%;
  position: relative;
}
ul li button{
  position: absolute;
  top: 0;
  right: 20%;
}
</style>









