vue实现TodoList效果完整版

TodoList完整效果演示效果如下:在这里插入图片描述

整体思路分析:

1.在input框中输入内容后按enter键,把内容添加到正在进行的任务中(如果内容为空则不添加)

2、动态计算有几个正在进行和已经完成的任务

3、点击复选框,实现选中或不选中

4、点击删除按钮即可删除列表内容

5、双击列表中的内容,可对列表内容进行修改
(按enter键完成编辑,或者当input框失去焦点的时候也是完成编辑,如果想要取消修改,按esc键即可取消修改)

6、选择下拉菜单可以查看全部、正在进行、已经完成的任务状态

7、已经添加的列表任务,即便关闭浏览器或者电脑,不会自动清空,下次打开任务还在列表中(用到了本地存储)

vue代码展示:

html代码:

<template>
   <div>
      <nav>
         <h2>TodoList</h2>
         <input type="text" v-model="inputValue" @keydown.enter="add" placeholder="添加Todo">
      </nav>
      <h2>正在进行({{noLength}})</h2>
      <ul>
         <li v-for="(item,index) in list" :key="index" v-show="checked=item.isSuc==false">
            <input type="checkbox" :checked="item.isSuc" @click="change($event,item)">
            <!--  updateId: 记录当前要修改的元素下标,默认为-1  -->
            <span v-if="updateId != index" @dblclick="update(item, index)">{{item.content}}</span>
            <input type="text" v-if="updateId == index" v-model="item.content" @keydown.enter="updatesave"
                   @keydown.esc="back(item)" @blur="updatesave">
            <button @click="del(index)">删除</button>
            {{item.time | timeFilters}}
         </li>
      </ul>
      <h2>已经完成({{yesLength}})</h2>
      <ul>
         <li v-for="(item,index) in list" :key="index" v-show="checked=item.isSuc==true">
            <input type="checkbox" :checked="item.isSuc" @click="change($event,item)">
            <span v-if="updateId != index" @dblclick="update(item, index)">{{item.content}}</span>
            <input type="text" v-if="updateId == index" v-model="item.content" @keydown.enter="updatesave"
                   @keydown.esc="back(item)" @blur="updatesave">
            <button @click="del(index)">删除</button>
            {{item.time | timeFilters}}
         </li>
      </ul>
      <!-- 筛选 -->
      <h2>筛选</h2>
      <select v-model="opt">
         <option value="">请选择</option>
         <option value="all">全部</option>
         <option value="no">正在进行</option>
         <option value="yes">已经完成</option>
      </select>
      <h3>任务列表</h3>
      <ul>
         <li v-for="(item, index) in optList" :key="index">{{ item.content }}</li>
      </ul>
   </div>
</template>

js代码:
(附加了时间过滤器)

<script>
   export default {
      data() {
         return {
            inputValue: '',  // 搜索框的值
            list: [],  // 保存的所有数据
            updateId: -1,  // 记录要修改的元素下标
            tempValue: "",  // 临时保存元素的值
            opt: "",  // 筛选默认为空
            optList: [],  // 用于展示的数据
         }
      },
      // 初始化   每次刷新会重新加载当前组件,会自动执行该方法
      created() {
         let list = localStorage.list
         if (list) {
            this.list = JSON.parse(list)
         }
      },
      // 监听  筛选
      watch: {
         opt(opt) {
            let optList = localStorage.list;
            if (!optList) {
               return;
            }
            this.optList = [];
            console.log(this.optList);
            let lists = JSON.parse(optList);

            switch (opt) {
               // 全部
               case "all":
                  this.optList = lists;
                  break;
               // 正在进行
               case "no":
                  lists.map((item) => {
                     if (!item.isSuc) {
                        this.optList.push(item);
                     }
                  });
                  break;
               // 已经完成
               case "yes":
                  lists.map((item) => {
                     if (item.isSuc) {
                        this.optList.push(item);
                     }
                  });
                  break;
            }
         },
      },
      //  计算(正在进行)和(已经完成)的结果
      computed: {
         noLength() {
            // 未完成数组的长度
            let num = 0;
            this.list.map((item) => { // map 数组遍历
               if (!item.isSuc) {
                  num++;
               }
            });
            return num;
         },
         yesLength() {
            // 已完成数组的长度
            let num = 0;
            this.list.map((item) => { // map 数组遍历
               if (item.isSuc) {
                  num++;
               }
            });
            return num;
         },
      },
      methods: {
         // 搜索框回车  添加数据到---->正在进行
         add() {
            //  非空校验   input值为空的时候  回车无效
            if (this.inputValue.trim() == '') {  //$.trim()函数用于去除字符串两端的空白字符
               return
            }
            // 添加数据
            this.list.push({
               content: this.inputValue,
               isSuc: false,
               time: new Date().getTime(), //getTime 转换时间戳  --->毫秒
            })
            this.inputValue = '';
            this.save();
            console.log(this.list)
            // 按添加的时间排序
            this.list.sort((a, b) => {
               return b.time - a.time;
            });
         },
         // 通过复选框判断是否选中
         change(event, item) {
            item.isSuc = event.target.checked
            this.save();
         },
         //  删除
         del(index) {
            this.list.splice(index, 1)  // splice万能方法  可对数组执行 增、删、改操作
            this.save()
         },
         // 双击修改  设置修改状态
         update(item, index) {
            this.updateId = index; // 把要修改的元素下标赋给 updateId
            this.tempValue = item.content; //记录当前元素修改前的文本内容,为了还原使用
         },
         // 修改后保存
         updatesave(item, index) {
            this.updateId = -1; // 还原文本展示的状态  意思是没有要修改的意思
            this.save();
         },
         // 还原
         back(item) {
            item.content = this.tempValue; // 把临时记录的文本重新赋给item.content
            this.tempValue = "";
            this.updateId = -1;
         },

         //  封装存储到本地的方法
         save() {
            localStorage.list = JSON.stringify(this.list)
         }
      },
      // 过滤器
      filters: {
         timeFilters(ms) {
            let data = new Date();   //创建当前时间
            let now = data.getTime();  // 获取时间戳
            let rel = (now - ms) / 1000 / 60;  // 转换为分钟
            let daystr = "";
            if (rel < 1) {
               daystr = "刚刚";
            } else if (rel >= 1 && rel < 3) {
               daystr = "1分钟前";
            } else if (rel >= 3 && rel < 10) {
               daystr = "3分钟前";
            } else if (rel >= 10 && rel < 30) {
               daystr = "10分钟前";
            } else if (rel >= 30 && rel < 40) {
               daystr = "30分钟前";
            } else if (rel >= 60 && rel < 120) {
               daystr = "1小时前";
            } else if (rel >= 120 && rel < 300) {
               daystr = "2小时前";
            } else if (rel >= 300 && rel < 1440) {
               daystr = "5小时前";
            } else if (rel >= 1440 && rel < 2880) {
               daystr = "1天前";
            } else if (rel >= 2880 && rel < 10080) {
               daystr = "2天前";
            } else if (rel >= 10080 && rel < 43200) {
               daystr = "7天前";
            } else if (rel >= 43200) {
               daystr = "30天前";
            }
            return daystr;
         }
      },
   }
</script>

css代码:

<style lang="scss" scoped>
   /* Todolist 样式*/
   nav {
      width: 100%;
      height: 60px;
      background-color: rgba(0, 0, 0, 0.8);
      display: flex;
      justify-content: center;
      align-items: center;

      h2 {
         color: white;
      }

      input {
         margin-left: 30px;
         width: 300px;
         height: 30px;
         border: 0;
         border-radius: 5px;
      }
   }

   ul {
      list-style: none;

      li span {
         width: 150px;
         display: inline-block;
         text-align: left;
      }
   }
</style>
  • 7
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值