Vue 组件传递对象的坑
近期做的一个项目,涉及到一个类似于 dialog 的组件,由于传递的数据比较多,为了偷懒,把部分可选数据统一放到一个对象变量里,打算用对象直接传递,于是,坑就来了。
场景重现
为了方便大家理解,这里我写了一个简单的 demo :
传递的数据很简单,就是一个 info
的对象,里面有 title
和 content
两个属性。
1 | data() { |
在组件里,我将 info
对象里的 content
数组删除最后一个,然后显示出来。
1 | created() { |
接下来可以点击 demo 里的 Open Dialog
按钮,发现问题了没?对咯,子组件里更新数据,把父组件里的也更新了,按照我这个 demo ,每次点击,父组件里的 content
数组就会少一个,多点击几次后,数组就变空了。
解决方案
其实问题的核心和 Vue 并没有太多关系,这里涉及到的 Javascript 的基础知识,就是值传递和引用传递, Object 和 Array 直接赋值是引用传递,这也就是为什么在子组件里修改,会导致父组件里也更新的原因。
既然明白问题的原因,那解决起来也就很容易了,比如下面这个深拷贝函数,在子组件里处理引用传递的数据前,先进行一次深拷贝。
1 | deepcopy(source) { |
数据进行深拷贝后,似乎就脱离 Vue 的监控了,对数据进行修改, DOM 不会实时更新,我的解决办法的每次修改数据后再进行依次深拷贝,覆盖原数据,不知道各位看官有什么更好的办法?
参考
- vue组件传递对象中实现单向绑定的方法
- Vue组件的三种调用方式 (本文 demo 里的组件采用了第二种调用方式,也就是直接在 js 里调用)