巧用v-model实现组件间数据双向绑定
在vue的开发中,我们常常会构造自定义组件,多个自定义组件组合至父级组件中,父子组件的通信方式基本是:父组件通过Prop向子组件传递数据。
|
|
以上的示例中,每当父组件的变量A发生数据变动时,都会更新子组件中接收的msg。
但是,因为Prop的数据是单向流动的,父组件可以通过Prop向子组件传递数据,子组件却不能通过Prop将数据的变动再回传给父组件。
此时有一个问题,如果我们希望子组件也可以实时改变父组件的数据,那该如何处理?
针对子父通信,vue给出了事件监听的方式,子父组件中共同定义好相应的事件名称,子组件调用内建的$emit方法
并传入事件的名字,来向父级组件触发一个事件,同时$emit
支持第二个参数作为数据传递。然后当在父级组件监听这个事件的时候,可以通过 $event
访问到被抛出的这个值。
以上就是官方文档给出的一个子父通信方法,具体代码详见官方文档,不是本文讲解内容。
当然了,随着vuex这样的数据管控插件的加入,组件间的通信变得更加集中化,但是比起原生的通信方式成本已增大了。
很多时候,多个组件组合使用时我们希望实现子父通信,总考虑到以下问题:
- 若采用官方的父子组件事件监听来实现代码较为繁琐,多个组件就要定义多个监听事件,增加代码量而且不好管控。
- 若引入vuex集中管理,成本较大,又感觉部分功能还达不到非使用vuex不可的程度,杀鸡焉用牛刀。
那么到底有什么最优的方法呢?
此时我不禁想到vue的一个很特殊的指令v-model
,vue文档中写道:
你可以用
v-model
指令在表单<input>
、<textarea>
及<select>
元素上创建双向数据绑定。
v-model
是一个可以实现数据双向绑定的指令,那么我们可不可以使用它来实现子父通信呢?当然是可以啦!
仔细查询文档,其实就有提到在组件上使用v-model,建议仔细阅读理解v-model机制后再继续看以下代码!
于是我们可以尝试着修改一下之前的代码:
|
|
从以上代码可以看出,主要的修改是在于子组件,针对v-model
指令的特殊性,我们定义一个临时变量tempdata
用于承载子组件内的数据修改,初始化时保持其值与父组件使用v-model
传递来的value
一致。每当tempdata
发生变动时,子组件监听其变化并将该值通过$emit('input')
的方式触发父组件更新value
(即父组件使用v-model
传递的对象变量)。
以上就是本次分享的主要内容,不难发现,其实本次的实现方式还是基于官方给出的事件监听的方式,但巧妙地使用了v-model
指令为我们减少了很多代码,且更加灵活。