vue-自定义组件传值的实例讲解
时间:2022-06-25 15:38:02 编辑:袖梨 来源:一聚教程网
项目中,我们经常会遇到自定义组件传值的问题,方法很多种,但是原理很简单,下述文档总结实际项目中使用的传值方式。
父组件传递给子组件某一值,子组件内会修改该值,然后父组件需要获取新值
在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop给子组件下发数据,子组件通过事件给父组件发送消息。
自定义组件传值
常规prop-event
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <prop-event-value :address= "address" @update= "val => address = val" key= "4" ></prop-event-value> <script> import propEventValue from './components/prop-event-value.vue' export default { name: 'app' , components: { propEventValue }, data() { return { address: '' } } } </script> |
子组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <template> <div> <p>prop-event</p> <label for = "address" >地址</label> <input type= "text" id= "address" v-model= "tempAddress" > </div> </template> <script> export default { name: 'prop-event' , props: [ 'address' ], data() { return { tempAddress: this .address } }, watch: { tempAddress(newVal) { this .$emit( 'update' , newVal) } } } </script> |
需要注意:不要直接在子组件内操作父组件的内容
组件实例的作用域是孤立的。每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。如果你这么做了,Vue 会在控制台给出警告。
1 2 3 4 5 6 7 8 9 | export default { name: 'prop-event' , props: [ 'address' ], watch: { address(newVal) { this .$emit( 'update' , newVal) } } } |
如将上述代码替换子组件,内容会报错!
修饰符.sync
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <my-sync-value :address.sync= "address" key= "5" ></my-sync-value> <script> import mySyncValue from './components/my-sync-value.vue' export default { name: 'app' , components: { mySyncValue }, data() { return { address: '' } } } </script> |
子组件
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 | <template> <div> <p>my-sync</p> <label for = "address" >地址</label> <input type= "text" id= "address" v-model= "tempAddress" > </div> </template> <script> export default { name: 'my-sync' , props: [ 'address' ], data() { return { tempAddress: this .address } }, watch: { tempAddress(newVal) { // 必须是这个update:address this .$emit( 'update:address' , newVal) } } } </script> |
prop-update:[prop]语法糖,与prop-event对比的优势:父组件无需监听事件@update="val => address = val",自动监听update:[prop]事件。
双向数据绑定v-model
所以要让组件的 v-model 生效,它应该 (从 2.2.0 起是可配置的):
接受一个 value prop
在有新的值时触发 input 事件并将新值作为参数
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <my-vmodel-value v-model= "address" key= "6" ></my-vmodel-value> <script> import myVmodelValue from './components/my-vmodel-value.vue' export default { name: 'app' , components: { myVmodelValue }, data() { return { address: '' } } } </script> |
子组件
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 | <template> <div> <p>my-vmodel</p> <label for = "address" >姓名</label> <input type= "text" id= "address" v-model= "tempAddress" > </div> </template> <script> export default { name: 'my-vmodel' , props: [ 'value' ], data() { return { tempAddress: this .value } }, watch: { tempAddress(newVal) { // 必须是input this .$emit( 'input' , newVal) } } } </script> |
prop-input语法糖,父组件v-model默认监听input事件
需要注意,这里必须触发input事件,当然也可以自定v-model属性值和事件,请参照自定义组件的v-model
vuex
通过store传值,这里后续单独讲述vuex。
单向数据流
上述已经提及,在子组件内部改变 prop,Vue会在控制台给出告警。但经常开发周静,我们很容易忍不住修改prop中的数据,如:
Prop 作为初始值传入后,子组件想把它当作局部数据来用;
Prop 作为原始数据传入,由子组件处理成其它数据输出。
对这两种情况,正确的应对方式是:
问题1:定义一个局部变量,并用 prop 的值初始化它:
1 2 3 4 | props: [ 'initialCounter' ], data: function () { return { counter: this .initialCounter } } |
问题2:定义一个计算属性,处理 prop 的值并返回:
1 2 3 4 5 6 | props: [ 'size' ], computed: { normalizedSize: function () { return this .size.trim().toLowerCase() } } |
特别需要注意:在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。
相关文章
- 《弓箭传说2》新手玩法介绍 01-16
- 《地下城与勇士:起源》断桥烟雨多买多送活动内容一览 01-16
- 《差不多高手》醉拳龙技能特点分享 01-16
- 《鬼谷八荒》毕方尾羽解除限制道具推荐 01-16
- 《地下城与勇士:起源》阿拉德首次迎新春活动内容一览 01-16
- 《差不多高手》情圣技能特点分享 01-16