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 })

猜你喜欢

转载自www.cnblogs.com/theblogs/p/10359884.html