vue2学习笔记2
    
      
        
        2021.01.26
      
      
        
          
          le31ei
        
      
      
  
    
    Program
  
      
      
       
        
            热度 
           ℃
        
      
      
     
  
  
    
      1. filter/map/reduce
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | const nums = [1, 2, 4, 10, 15, 20, 200, 40, 300]
 
 
 
  let result = nums.filter(function(n){   if (n % 2 === 0){     return true   } })
 
  let result = nums.map(function(n){   return n*2 })
 
  let result = nums.reduce(function(preValue, n){   return preValue+n }, 0)
   | 
 
2. v-model
表单绑定,实现表单元素和数据的双向绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | <div id="app">     <input type="text" v-model="message">   	<input type="text" :value="message" @input="message=$event.target.value">  // v-bind加事件实现双向绑定     {{message}} </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',         data: {             message: 'test'         }     }) </script>
   | 
 
绑定radio控件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | <div id="app">     <label for="male">         <input type="radio" id="male" name="gender" v-model="gender" value="男">男     </label>     <label for="female">         <input type="radio" id="female" name="gender" v-model="gender" value="女">女     </label>     {{gender}} </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',         data: {             gender: ''         }     }) </script>
   | 
 
修饰符
lazy:懒加载,失焦的时候或者回车的时候,才更新变量
<input type="text" v-model.lazy="message">
number:对输入的类型限定为数字
trim:对输入的内容去除空格
3. 组件化
使用组件的步骤
- 创建组件构造器:
Vue.extend() 
- 注册组件:
Vue.component() 
- 使用组件
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | <div id="app">     <my-cpn></my-cpn> </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>
      const cpn = Vue.extend({         template: `<div>                     <h2>标题</h2>                     <p>内容</p>                    </div>`     })     Vue.component('my-cpn', cpn)        let app = new Vue({         el: '#app', 				components: {                        cpn2: cpn         }     });
  </script>
   | 
 
父组件和子组件
在父组件中的components中定义子组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
   | <div id="app"> <cpn></cpn>     <cpn2></cpn2> </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     const cpn1 = Vue.extend({         template: `         <div>             <h1>标题1</h1>             <p>内容1</p>         </div>         `     })     const cpn2 = Vue.extend({         template: `         <div>             <h1>标题2</h1>             <p>内容2</p>             <cpn1></cpn1>         </div>         `,         components: {             cpn1: cpn1    // cpn2父组件中定义cpn1子组件         }     })     let app = new Vue({         el: '#app',         components: {             cpn2: cpn2,         }     });
  </script>
   | 
 
语法糖写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | <div id="app">     <my-cpn></my-cpn> </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>
      Vue.component('my-cpn', {         template: `<div>                     <h2>标题</h2>                     <p>内容</p>                    </div>`     })      let app = new Vue({         el: '#app',     });
  </script>
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | <div id="app">     <my-cpn></my-cpn> </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',       	components: {           cpn2: {             template: `<div>                     <h2>标题</h2>                     <p>内容</p>                    </div>`           }         }     });
  </script>
   | 
 
模板分离
text/x-template或者直接template标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   | <div id="app">     <cpn></cpn>     <cpn2></cpn2> </div> <script type="text/x-template" id="mycpn">     <div>         <h2>标题</h2>         <p>内容</p>     </div> </script> <template id="mycpn2">     <div>         <h2>标题2</h2>         <p>内容2</p>     </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',         components: {             cpn: {                 template: '#mycpn'             },             cpn2: {                 template: '#mycpn2'             }         }     }); </script>
   | 
 
组件数据存放
data属性,但必须是一个函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | <template id="mycpn2">     <div>         <h2>标题2</h2>         <p>{{message}}</p>     </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',         components: {             cpn2: {                 template: '#mycpn2',                 data(){                        return {                         message: 'testme'                     }                 }             }         }     }); </script>
   | 
 
组件通信
父组件向子组件传值使用:props
子组件向父组件传值使用:$emit events
父组件传值,通过v-bind读取父组件的值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | <div id="app">     <cpn2 :cmovies="movies" :cmessage="message"></cpn2> </div> <template id="mycpn2">     <div>         <h2>标题2</h2>         <p>{{cmessage}}</p>         <ul v-for="item in cmovies">             <li>{{item}}</li>         </ul>     </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     const cpn = {         template: '#mycpn2',         props: ['cmovies', 'cmessage'], 				props: {                        cmovies: Array,             cmessage: String         }         	props: {                      cmovies: {                 type: String,                 default: '123',       					required: true             }         }     }
      let app = new Vue({         el: '#app',         components: {             cpn2: cpn         },         data: {             movies: ['test1', 'test2', 'test3', 'test4'],             message: '父组件数据'         }     }); </script>
   | 
 
子组件向父组件传递
通过$emit发送事件的方式传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
   | <div id="app">     <cpn2 @itemclick="cpnclick"></cpn2> </div> <template id="mycpn2">     <div>         <button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>     </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     const cpn = {         template: '#mycpn2',         data(){             return{                 categories: [                     {id: 'aaa', name: 'test1'},                     {id: 'bbb', name: 'test2'},                     {id: 'ccc', name: 'test3'},                 ]             }         },         methods: {             btnClick(item){                 this.$emit('itemclick', item)             }         }     }
      let app = new Vue({         el: '#app',         components: {             cpn2: cpn         },         methods: {              cpnclick(item){                 console.log('父组件收到')                 console.log(item)             }         }
      }); </script>
   | 
 
父子组件双向绑定
props的属性只能从父组件传过来,不能在子组件进行model绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
   | <template id="counter">     <div>         props: {{number1}}<br>         data: {{cnumber1}}<br>         <input type="text" v-model="cnumber1" @input="update"><br>         props: {{number2}}<br>         data: {{cnumber2}}<br>         <input type="text" v-model="cnumber2">
      </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',         data: {             num1: 0,             num2: 1         },         methods: {             updatefather(num){                 this.num1 = num             }         },         components: {             cpn: {                 template: '#counter',                 props: {                     number1: String,                     number2: String                 },                 data(){                     return{                         cnumber1: this.number1,                         cnumber2: this.number2                     }                 },                 methods: {                     update(event){                         this.$emit('updatefather', event.target.value)                     }                 }             }         }     }); </script>
   | 
 
监听某个值的改变,可以直接用watch方法
父子组件互相访问
父组件访问子组件:使用$children或者$ref
子组件访问父组件:使用$parent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
   | <div id="app">     <cpn></cpn>     <cpn ref="aaa"></cpn>     <button @click="btnClick">按钮</button> </div> <template id="cpn">     <div>         子组件     </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',         methods: {             btnClick() {                 this.$children[0].showMessage()                 this.$refs['aaa'].showMessage()               	this.$refs.aaa.showMessage()             }         },         components: {             cpn: {                 template: '#cpn',                 methods: {                     showMessage(){                         console.log('show message')                     }                 }             }         }     }); </script>
   | 
 
4. slot插槽
组件的插槽为了让封装的组件更具有扩展性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | <div id="app">     <cpn><button>按钮</button></cpn>     <cpn><span>span标签</span></cpn>     <cpn></cpn> </div> <template id="cpn">     <div>         <div>子组件</div>         <slot><button>默认按钮</button></slot>     </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',         components: {             cpn: {                 template: '#cpn'             }         }     }); </script>
   | 
 
具名插槽
1 2 3
   | <slot name='left'></slot> 替换方法: <cpn><span slot='left'>testme</span></cpn>
   | 
 
作用域插槽
父组件替换插槽的标签,但是内容由子组件来提供
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
   | <div id="app"> <cpn></cpn>     <cpn>         <template slot-scope="slot">             <span v-for="item in slot.data">{{item}}</span>  // 数据在子组件中,但是该标签的作用域在父组件里面,需要将内容传递过来         </template>     </cpn> </div> <template id="cpn">     <div>         <slot :data="pLanguage">             <ul>                 <li v-for="item in pLanguage">{{item }}</li>             </ul>         </slot>     </div>
  </template> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script>     let app = new Vue({         el: '#app',         components: {             cpn: {                 template: '#cpn',                 data(){                     return{                         pLanguage: ['test1', 'test2', 'test3']                     }                 }             }         }     }); </script>
   |