鍍金池/ 問答/Java  HTML/ vue父子組件數(shù)據(jù)交互,為什么子組件watch方法調(diào)用多次?

vue父子組件數(shù)據(jù)交互,為什么子組件watch方法調(diào)用多次?

題目描述

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

  1. 父組件在一個table中循環(huán)引用子組件
  2. 父組件通過props傳遞屬性 itemDefaultValue 給子組件,子組件watch監(jiān)聽父組件傳遞過來的屬性,子組件使用一個新值itemDefaultValueCopy 深拷貝傳遞過來的值并和子組件v-model綁定,點擊按鈕觸發(fā)父組件向子組件傳值,watch方法被調(diào)用多次(其實是和表格有多少行數(shù)據(jù)有關(guān))

題目來源及自己的思路

調(diào)用多次的問題奇怪之處:
當我 itemDefaultValue:[1],這種情況下每次點擊按鈕,watch方法都會觸發(fā)多次
當我 itemDefaultValue:this.defaultValue,watch方法沒有觸發(fā)(this.defaultValue是vue data對象的值)

相關(guān)代碼

父組件: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);
            }
        }
    }

你期待的結(jié)果是什么?實際看到的錯誤信息又是什么?

當父組件 itemDefaultValue: this.defaultValue寫成 [1], 效果如下(每次點擊按鈕watch都會調(diào)用):

clipboard.png

反之不修改的話就不會被調(diào)用

clipboard.png
求高手解惑!

回答
編輯回答
失魂人

Q: 為什么子組件watch方法調(diào)用多次?

A:當 itemDefaultValue:[1] 是否對 watch 的值進行了修改?

Q: 當 itemDefaultValue:this.defaultValue,watch方法沒有觸發(fā)

A: 和 Vue 中不推薦 data 中直接使用 data:{} 的原因一樣,直接調(diào)用了引用類型,watch 方法不會觸發(fā)。

需要提供 Demo

2017年4月5日 20:55