vue父子组件数据交互,为什么子组件watch方法调用多次?

题目描述

child.vue是子组件
parent.vue是父组件

  1. 父组件在一个table中循环引用子组件
  2. 父组件通过props传递属性 itemDefaultValue 给子组件,子组件watch监听父组件传递过来的属性,子组件使用一个新值itemDefaultValueCopy 深拷贝传递过来的值并和子组件v-model绑定,点击按钮触发父组件向子组件传值,watch方法被调用多次(其实是和表格有多少行数据有关)

题目来源及自己的思路

调用多次的问题奇怪之处:
当我 itemDefaultValue:[1],这种情况下每次点击按钮,watch方法都会触发多次
当我 itemDefaultValue:this.defaultValue,watch方法没有触发(this.defaultValue是vue data对象的值)

相关代码

父组件:parent.vue

export default {
        name: 'paper_index',
        components: {
            PopTipTransfer
        },
        data () {
            return {
                defaultValue: [1],
                editInlineColumns: [
                    {
                        title: '操作',
                        key: 'action',
                        align: 'center',
                        fixed: 'right',
                        width: 200,
                        render: (h, params) => {
                            return h('div', [
                                h(PopTipTransfer, {
                                    ref: 'pop',
                                    props: {
                                        itemDefaultValue: this.defaultValue
                                    }
                                }, [
                                    h('Button', {
                                        props: {
                                            type: 'text',
                                            size: 'small'
                                        }
                                    }, '项目管理')
                                ])
                            ]);
                        }
                    }
                ]
            }
        }

子组件代码 child.vue


<template>
    <Cascader v-model="itemValueCopy"></Cascader>
</template>
export default {
        name: 'PopTipTransfer',
        props: {
            itemDefaultValue: {
                type: Array,
                default () {
                    return [];
                }
            },
            items: {
                type: Array,
                default () {
                    return [];
                }
            },
            renderItem: {
                type: Function,
                default (item) {
                    return item.label || item.key;
                }
            }
        },
        data () {
            return {
                itemValueCopy: JSON.parse(JSON.stringify(this.itemDefaultValue))
            };
        },
        watch: {
            itemDefaultValue (val, oldval) {
                console.log(val);
            }
        }
    }

你期待的结果是什么?实际看到的错误信息又是什么?

当父组件 itemDefaultValue: this.defaultValue写成 [1], 效果如下(每次点击按钮watch都会调用):

clipboard.png

反之不修改的话就不会被调用

clipboard.png
求高手解惑!

阅读 9k
2 个回答

Q: 为什么子组件watch方法调用多次?

A:当 itemDefaultValue:[1] 是否对 watch 的值进行了修改?

Q: 当 itemDefaultValue:this.defaultValue,watch方法没有触发

A: 和 Vue 中不推荐 data 中直接使用 data:{} 的原因一样,直接调用了引用类型,watch 方法不会触发。

需要提供 Demo

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题