Vue.js:父组件向子组件props动态传递对象的三种方法

您所在的位置:网站首页 vue父组件怎么接收子组件数据 Vue.js:父组件向子组件props动态传递对象的三种方法

Vue.js:父组件向子组件props动态传递对象的三种方法

2024-07-13 19:59| 来源: 网络整理| 查看: 265

目录 1、背景2、解决方法2.1、data与watch辅助【推荐】2.2、重建实例【适合没有实现动态更新的第三方库】2.3、Vuex辅助【不推荐】

1、背景

Vue的核心是组件模块与数据驱动。正是因为这两点,我们才能开发出各式各样的灵活的小组件。通过这些组件的相互配合就能够搭建出一个完整的界面,这里面就涉及到一个配合顺序——父组件与子组件。这两个名称的区别也仅仅是前者包含了后者,两者在开发时是独立的,但是,我们在开发过程中通常会有父子组件间的数据传递,尤其是父组件把数据交给子组件,然后让子组件渲染这种操作。

Vue为我们提供这种传递的简便方法,即子组件通过props暴露出数据接口,父组件通过绑定的方式将数据传递到子组件中。如下操作:

//子组件:child.vue {{attrs}} export default { name: 'child', props: { attrs: { type: Object, default () { return {} } } }, //从父组件传递进来的props会在mout阶段赋值,之后便不会再触发该阶段 //beforeCreate(开始创建实例)、created(数据和方法已经初始化,但dom还没有挂载到页面上)、 //beforeMount(挂载之间,准备挂载)、mounted(dom跟数据都成功挂载)、 //beforeUpdate(数据更新,页面还没有同步)、updated(数据更新,页面已经同步)、 //beforeDestroy(实例销毁前)、destroyed(实例销毁后) mounted () { }) } //父组件:father.vue export default { name: 'child', data(): return{ fatherAttrs: {aAttr: 'A', bAttr: 'B'} } }

这种方法为我们父子组件传递简化了很多,由上面我们知道父组件向子组件传递的值只会在mount阶段挂载到页面一次,之后便不再执行这个阶段。那么就存在一个问题,如果我们把fatherAttrs对象修改后,子组件的attrs对象能够接收到改变,但没有办法同步更新到页面上,即上面这种方法无法使得父组件能动态地向子组件传递数据。

那怎么办?以下提供两种解决方法

2、解决方法 2.1、data与watch辅助【推荐】

Vue内置的监听器watch是一个监听数据发生变化的处理函数,监听范围包括data函数中的数据和props函数中的数据。而我们知道data函数中的数据是与页面紧密绑定的,那么我们就可以通过监听props中的数据,如果其修改了出发watch函数,再将新值赋予data中的对象,则能实现动态更新props的对象。这是一种从子组件的角度实现的做法,具体做法如下。

//子组件:child.vue {{dataAttrs}} export default { name: 'child', data():{ return{ dataAttrs: null //新增一个对象来动态更新 } } props: { attrs: { type: Object, default () { return {} } } }, mounted () { this.dataAttrs= this.attrs; //用props中的对象对data中的对象赋初始值 }, watch: { // 监听到数据然后赋值 attrs{ // 监听数据发生变化的处理函数 handler(newV) { this.dataAttrs = JSON.parse(JSON.stringify(newV));//将监听到修改的值赋予到dataAttrs中 }, // 是否开启深度监听,由于我们上面props中是一个Object对象,所以需要开启深度监听功能 deep: true } } 2.2、重建实例【适合没有实现动态更新的第三方库】

上面第一种方法能很好地处理动态更新props的情景,但它的前提是这个子组件我们是能够修改的,也就是说,这个子组件是我们自己写的,能够随意修改里面的内容。那要是我们用的是第三方的库呢?而且这个库里面也没有实现上面那种动态更新的方法,这怎么办?这就得从父组件的角度来解决了。

在上面背景的child.vue中的注释,我们知道props无法动态更新是因为组件的生命周期在mount阶段只执行一次的原因。我们一定要实现动态监听,那就需要想方设法让mount再执行一次了,这种方法就是重建子组件的实例,销毁更新前的实例,为子组件创建一个新的生命周期。

在父组件中要让子组件重新创建,最简单的指令是v-if,当为false时,该组件在dom中被移除,当为true时,该组件重新加入到dom,此时,子组件会重新创建【注意:v-if与v-show虽然都是控制组件显示与否,但v-show只是修改了display属性,使得没有前端显示而已,其实例还是存在的。所以,一般而言,v-if与v-show相比,其消耗的时间更多】。具体做法如下:

//父组件:father.vue export default { name: 'child', data(): return{ fatherAttrs: {aAttr: 'A', bAttr: 'B'}, show: true }, methods: { changeAttrs(){ //触发该函数,动态更新子组件 this.fatherAttrs = {aAttr: 'C', bAttr: 'D'}; this.show= false; this.$nextTick(() => { this.show= true; }); } } } 2.3、Vuex辅助【不推荐】

原本不想把这个添加到这里面的,因为仅仅父子组件传递数据就需要用到Vuex的话,那真的是有些杀鸡用牛刀了。但是就顺手记录一下吧。具体做法相对上面比较复杂一点,建议参考以下文章:vue中使用vuex(超详细)。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3