网站首页 » 前端开发 » Vue » 父子组件通信的奥秘
上一篇:
下一篇:

父子组件通信的奥秘

前言

组件通信,在 Vue 中非常地常见,我们必需得会,不仅仅如,我们还得会父子组件间通信的各种套路,所以本文要分享的就是这个,一步一步来解开父子组件通信的奥秘。

父子组件通信之旅

说起父子组件之间的数据父互,我想你脑中已经有了不二仁选,比如在父组件中添加属性来跟子组件进行单向数据传递,并在子组件中通过props 来接收。这种方式接收到的数据你不能直接修改,不然会毫不客气地给你报错

报错

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “title”

不过我们可以通过 computed 计算属性来转为本组件的计算属性,进而对这个计算属性进行修改。

在网上看到有说这个 props 只能做单向数据绑定,这个说法是不对的,没错,一般情况下它是只能作单向数据绑定,在并且在子组件中不能对它进行修改,不然就会报出上面的错误。但是有一种情况,可以实现又向数据绑定,并且可以在子组件中对它进行修改。

直接按上面的套路,在父组件中通过属性传递,并在子组件中使用 props 来接收,只不过我们传给子组件的是一个对象,而不是基本数据类型,此时就可以实现类似于数据的双向绑定效果。

除此之外我猜数组应该也是可以的,毕竟它跟对象都是址传递的,但经过测试,如果数组项为基本数据类型的值的话,虽然也可以在子组件中修改这个数组里的值,并且数组在父组件中打印出来也是更改了值的数组,但是如果你在父组件中使用{{}} 或者 watch 来显示这个数组中的数据时,它是不会实时更新的。

不过在父组件自身中更改数组里的值,{{}}或者 watch 也没有同步更新数据到视图。至于为什么官方文档中也有提及,解决方法之一就是通过实例的 this.$set() 方法来修改数组里的值,而不是通过我们常用的arr[index] 的方式来修改值,此时{{}}或者 watch 就能监听到数组中的值的变化,并会及时更新到视图。

所以如果你想实现类似双向绑定的效果,你可给属性传一个对象,对象里写上你需要的各种值。

除了上面的这种方法外,我们还有两种方法可以选择。

方法一:v-model

我们可以在子组件上使用 v-model 来实现双向绑定,当我们在子组件上添加 v-model 的时候它会自动地帮我们做一些事情。比如下面:

<yk-child v-model="message"></yk-child>

message 是我们在 data 中定义的一个变量。Vue 遇到上面的这行代码后,会给我们转换成下面这样:

<yk-child :value="message" @input="val => message = val"></yk-child>

看起来是不是很熟悉,有一个 :value=”message” ,一个 @input=”val => message = val” ,这两个不是你都已使用得滚瓜烂熟的套路吗?一个往子组件中传数据,一个负责接收子组件 $emit 出来的事件,来触发 input 事件,执行一个给 message 更新值的动作。

在子组件中使用

this.$emit("input", this.count++);
// this.count++ 只是一个参数,它可以是其它数据类型比如字符串,我们只要知道 $emit() 的第一个参数是事件名,第二个参数为回传的参数就好。

这种写法是我在研究 element 组件库时发现的。

方法二 .sync

这种方法其实跟上面的差不多,只是换了种方式。这种写法经历过时间的考验,官方把它去掉,后续版本又把它请了回来,说明这个 sync 修饰符还是很有用的。

它的写法

<yk-child :title.sync="message"></yk-child>

Vue 会自动把上用的代码转换成:

<yk-child :value="message" @input="val => message = val"></yk-child>

所以说.sync 修饰符的实现套路跟在子组件上使用 v-model 是如出一辙,只是绑定的事件名不同吧了。

在子组件中通过下面的代码回传值到父组件中

this.$emit("update:title", this.count++); 
注意

使用 .sync 修饰符时它的事件名的规则,前面一个 updata 加上冒号然后再加上 .sync 前面的属性名。但是如果组件嵌套了好多层,这种方法用起来就相当地费劲,所以这种双向绑定的方法,比较适用于嵌套一层的场景,如果嵌套了很多层,那又怎么办?此时我们可以使用 vuex 状态管理来进行数据的传递。

 

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/passing-data-between-parent-components-and-child-components/

Leave a Reply

Your email address will not be published. Required fields are marked *

评论 END