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