• vue基于组件实现简单的todolist


    把todolist拆分为header、footer、list三个模块

    index文件

      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4     <meta charset="UTF-8">
      5     <title>todos</title>
      6     <link rel="stylesheet" type="text/css" href="css/index.css">
      7 </head>
      8 <body>
      9     <section class="todoapp" id="app">
     10         <div>
     11             <my-header
     12             @addrecord="parentAdd"
     13             ></my-header>
     14             <section class="main">
     15                 <input 
     16                 class="toggle-all" 
     17                 type="checkbox"
     18                 v-model="all"
     19 
     20                 >
     21                 <List 
     22                 :act="filters"
     23                 @rmdata="parentRm"
     24                 >
     25                 </List>
     26             </section>
     27             <my-footer
     28             v-show="!!arr.length"
     29             :n="num"
     30             :cn="cnum"
     31             ></my-footer>
     32         </div>
     33     </section>
     34 <script src="js/vue.min.js"></script>
     35 <script src="component/header.js"></script>
     36 <script src="component/footer.js"></script>
     37 <script src="component/list.js"></script>
     38 <script>
     39 /*
     40 实现的一些功能:
     41 1、输入内容回车添加内容
     42 2、全选功能
     43 3、勾选任意内容进行删除
     44 4、根据hash不同,过滤渲染的数据
     45 */
     46 new Vue({
     47     el:'#app',
     48     data:{
     49         filters:[],//拿到过滤之后的数据
     50         cunm:'/checked',//值根据hash值而改变,且会影响tab的active状态
     51         arr:[
     52             {
     53                 id:0,
     54                 city:'多伦多',
     55                 checked:true
     56             },
     57             {
     58                 id:1,
     59                 city:'悉尼',
     60                 checked:false
     61             },
     62             {
     63                 id:2,
     64                 city:'慕尼黑',
     65                 checked:false
     66             },
     67             {
     68                 id:3,
     69                 city:'雅加达',
     70                 checked:false
     71             }
     72         ]
     73     },
     74     methods:{
     75         //把传过来的数据添加到数组中
     76         parentAdd(data){
     77             this.arr.unshift(data)
     78         },
     79         //利用filter删除(把e.id等于id的过滤掉,留下不等于id的)
     80         parentRm(id){
     81             this.arr = this.arr.filter(e=>e.id!==id)           
     82         },
     83         hashFn(){
     84             //当hash改变时候,过滤数据
     85             let H = window.location.hash.split('#')[1];
     86             this.cnum = H;
     87             this.filters = this.arr.filter(e=>{
     88                 switch(H){
     89                     case '/all':
     90                         return e;
     91                         break;
     92                     case '/unchecked':
     93                         return !e.checked;
     94                         break;
     95                     case '/checked':
     96                         return e.checked;
     97                         break;
     98                     default:
     99                         return e;
    100                         break
    101                 }
    102             });
    103         }
    104     },
    105     computed:{
    106         all:{
    107             get(){
    108                 //如果arr的length没有直接返回false
    109                 if(!this.arr.length){
    110                     return false;
    111                 }   
    112                 //所有checked都是真的,就全部选中
    113                 return this.arr.every(e=>e.checked)
    114             },
    115             set(newVal){
    116                 //把所有的checked都等于newVal
    117                 return this.arr.forEach(e=>{
    118                     e.checked = newVal
    119                 })
    120             }
    121         },
    122         num(){
    123             //未选中的个数
    124             return this.arr.filter(e=>!e.checked).length;
    125         }
    126     },
    127     //当点击选中的时候,会改变arr的数据,当arr中的数据改变就重新过滤数组
    128     watch:{
    129         arr:{
    130             handler(){
    131                 this.hashFn();
    132             },
    133             deep:true
    134         }
    135     },
    136     created(){
    137         let hash = window.location.hash;
    138         //如果没有hash就给他设置
    139         if(!hash){
    140             window.location.hash = '#/all';
    141         }else{
    142             this.hashFn();
    143         }
    144         window.onhashchange = () =>{
    145             this.hashFn();
    146         }
    147     }
    148 });
    149 </script>
    150 </body>
    151 </html>

    header.js文件

     1 Vue.component('my-header',{
     2     template:`
     3         <header class="header" >
     4             <h1>todos</h1>
     5             <input 
     6             class="new-todo" 
     7             placeholder="请输入内容" 
     8             @keyup.13="add"
     9             v-model="val"
    10             >
    11             
    12         </header>
    13     `,
    14     data(){
    15         return{
    16             val:''
    17         }
    18     },
    19     methods:{
    20         add(){
    21             //添加数据
    22            if(this.val){
    23                this.$emit('addrecord',{
    24                    id:+new Date,
    25                    city:this.val,
    26                    checked:false
    27                })
    28                this.val = ''//把原先输入的内容清空
    29            }
    30         }
    31     }
    32 })

    list.js文件

     1 Vue.component('list',{
     2     //li中class是动态的,需要给个val.checked
     3     template:`
     4         <ul class="todo-list">
     5             <li 
     6             v-for="(val,key) in act"
     7             :class="{completed:val.checked}"           
     8             >
     9                 <div class="view">
    10                     <input 
    11                     class="toggle" 
    12                     type="checkbox" 
    13                     v-model="val.checked"
    14                     >
    15                     <label>{{val.city}}</label>
    16                     <button class="destroy" @click="rm(val.id)"></button>
    17                 </div>
    18             </li>
    19         </ul>
    20     `,
    21     props:['act'],
    22     methods:{
    23         rm(id){
    24             this.$emit('rmdata',id)
    25         }
    26     }
    27 })

    footer.js文件

     1 Vue.component('my-footer',{
     2     template:`
     3         <footer class="footer">
     4             <span class="todo-count">
     5                 <strong>{{n}}</strong>
     6                 <span>条未选中</span>
     7             </span>
     8             <ul class="filters">
     9                 <li v-for="(val,key) in btns">
    10                     <a 
    11                     :href="val.hash"
    12                     :class="{selected:val.hash.substring(1) == cn}"
    13                     >{{val.name}}</a>
    14                 </li>
    15             </ul>
    16         </footer>
    17     `,
    18     props:['n','cn'],
    19     data(){
    20         return {
    21             num:'#/all',
    22             btns:[
    23                 {
    24                     hash:'#/all',
    25                     name:'全部'
    26                 },
    27                 {
    28                     hash:'#/unchecked',
    29                     name:'未选中'
    30                 },
    31                 {
    32                     hash:'#/checked',
    33                     name:'已选中'
    34                 },
    35             ]
    36         }
    37         
    38     }
    39 })
  • 相关阅读:
    1836Alignment
    JS日期格式化
    excle自编公式方法
    excle的公式说明
    小技巧之一 string[]合并
    Nunit的使用小问题
    Ajax中上传文件的方式
    VSS也有BUG?
    SQL Server中将时间型的转为yyyyMMddhhmmss
    给已经存在的PDF文件加水印
  • 原文地址:https://www.cnblogs.com/theblogs/p/10359884.html
Copyright © 2020-2023  润新知