用vue制作一个任务清单(todoList)

功能需求:

(1)能显示未完成的任务和已完成的任务.
(2)能添加新的任务。
(3)能修改任务的状态(未完成->已完成)
(4)能删除任务。
(5)能清空所有任务。

效果图:

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="todoList.css">
  <script src="https://cdn.staticfile.org/vue/3.0.5/vue.global.js"></script>
  <title>todoList清单</title>
</head>

<body>
  <div id="root" class="container">
    <div class="add-todo">
      <h1>欢迎使用ToDoS</h1>
      <!-- keydown 键盘事件 按下enter直接添加  -->
      <input type="text" v-model="inputstr" @keydown.enter="add" placeholder="按下回车键添加任务" class="new-todo" />
    </div>

    <h2>正在进行({{nolist}})</h2>
    <!-- 显示未完成的数量  -->
    <ul class="todo_item">
      <li v-for="(item,index) in list" :key="index" v-show="!item.isdone">
        <input type="checkbox" @click.prevent="handleClick(item)" class="checkbox"/>
        <!-- 点击添加  -->
        <span class="content" @dblclick="updateIndex(item,index)" v-show="ifnum!=index">{{item.text}}</span>
        <!-- 双击内容修改  -->
        <input type="text" v-show="ifnum==index" v-model="item.text" @keydown.enter="complete"
          @keydown.esc="cancel(item)" @blur="complete" />

        <!-- 日期 -->
          <font color="#999">&emsp;{{getdate()}}&emsp;</font>

          <button @click="del(index)" class="del">删除</button>
       
        <!-- 删除功能 -->
      </li>
    </ul>

    <h2>已经完成({{yeslist}})</h2>
    <!-- 显示已完成数量 -->
    <ul class="todo_item">
      <li v-for="(item,index) in list" :key="index" v-show="item.isdone">
        <input type="checkbox" checked @click.prevent="handleyes(item)" @dblclick="updateIndex" />
        <span class="content" @dblclick="updateIndex(item,index)" v-show="ifnum!=index">{{item.text}}</span>

        <input type="text" v-show="ifnum==index" v-model="item.text" @keydown.enter="complete"
          @keydown.esc="cancel(item)" @blur="complete" />

        
        <font color="#999">&emsp;{{getdate()}}&emsp;</font>
        <button @click="del(index)" class="del">删除</button>
      </li>
      <button @click="allDelete" class="allDel">全部删除</button>
    </ul>

    <p>注:双击todo可修改内容</p>

  </div>
</body>

<script>
  const { createApp,ref } = Vue
  const app = Vue.createApp({
    data() {
      return {
        list: JSON.parse(localStorage.getItem('list'))||[],
        inputstr: "",
        ifnum: -1,
        str: "",
        times:'',//格式化之后的当前时间s
      };
    },
  created() {
    this.getTimes()
  },
    props:{
      selector: {
			type: Number,
			required: true,
		},
		done: {
			type: Boolean,
			required: true,
    },
  },
    // 计算属性
    computed: {
      yeslist() {
        let num = 0;
        this.list.map(item => {
          if (item.isdone) {
            num++;
          }
        });
        return num;
      },
      nolist() {
        let num = 0;
        this.list.map(item => {
          if (!item.isdone) {
            num++;
          }
        });
        return num;
      },

    },
    methods: {
      add() {
        this.list.push({
          text: this.inputstr,
          isdone: false,
          time: new Date().getTime()
        });
        this.inputstr = "";
        this.save();
      },
      handleClick(item) {
        item.isdone = true;
        this.save();
      },
      handleyes(item) {
        item.isdone = false;
        this.save();
      },
      updateIndex(item, index) {
        this.str = item.text;
        this.ifnum = index;
        this.save();
      },
      complete() {
        this.ifnum = -1;
        this.save();
      },
      cancel(item) {
        item.text = this.str;
        this.str = "";
        this.ifnum = -1;
        this.save();
      },

      del(index) {
        this.list.splice(index, 1);
        this.save();
      },
      // 删除全部
      allDelete(){
        this.list.splice(0, this.list.length);
        this.save();
      },
      save() {
        localStorage.list = JSON.stringify(this.list);
      },
    // 时间
    getdate() {
		      var date = new Date();
		      var seperator1 = "-";
		      var year = date.getFullYear();
		      var month = date.getMonth() + 1;
		      var strDate = date.getDate();
		
		      if (month >= 1 && month <= 9) {
		        	month = "0" + month;
		      }
		      if (strDate >= 0 && strDate <= 9) {
		      	  strDate = "0" + strDate;
		      }
		      var currentdate = year + " /" + month + " / " + strDate ;
		      return currentdate;
	    }
    },
    created() {
      let list = localStorage.list;
      if (list) {
        this.list = JSON.parse(list);
      }
    }


  })
  const vm = app.mount("#root")
</script>

</html>

style样式:

html,
body {
	margin: 0;
	padding: 0;
}
li,ul{
    list-style: none;
    padding: 0;
}
body {
	width: 100vw;
    min-height: 100vh;
    display: grid;
    align-items: center;
    justify-items: center;
    background: rgb(216, 243, 214);
}
button{
    background: linear-gradient(#b6f1a2, #6df86d);
    border: none;
    border-radius: 10%;
    color: #fff;
}
/* 多选框 */
input[type="checkbox"] {
    -webkit-appearance: none;
    width: 20px;
    height: 20px;
    margin-top: 2px;
    border-radius: 50%;
    border: 1px solid #b6f1a2;
}
input[type="checkbox"]:checked {
    background: #b6f1a2;
}
.container{
    width: 100%;
    max-width: 400px;
    box-shadow: 0px 0px 24px rgba(26, 25, 25, 0.15);
    border-radius: 24px;
    padding: 48px 28px;
    background-color: rgb(229, 230, 235);
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px rgb(229, 230, 235), 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px rgb(229, 230, 235), 0 17px 2px -6px rgba(0, 0, 0, 0.2);
}
h1{
    margin: 24px 0;
    font-size: 28px;
    color: #384280;
    width: 100%;
}
h2{
    color: #6b729c;
}
.add-todo {
    position: relative;
    display: flex;
    align-items: center;
}
.add-todo input{
    padding: 16px 52px 16px 18px;
    border-radius: 48px;
    border: none;
    outline: none;
    box-shadow: 0px 0px 24px rgba(0, 0, 0, 0.08);
    font-size: 16px;
    color: #626262;
}
.add-todo>button {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: linear-gradient(#b6f1a2, #6df86d);
    border: none;
    outline: none;
    color: white;
    position: absolute;
    right: 0px;
    cursor: pointer;
}
/* todo列表 */
.todo_item>li{
    background: white;
    padding: 16px;
    border-radius: 8px;
    color: #626262;
    margin-top: 20px;
}
/* 删除全部 */
.allDel{
    margin-top: 20px;
    width: 100px;
    height: 40px;
    font-size: 18px;
    font-weight: bold;
}
/* p{
    color: #fff;
} */

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值