Vue parent-child component data interaction, why does the child component watch method call multiple times?

topic description

child.vue is a child component
parent.vue is a parent component

  1. the parent component iterates through a table to refer to child components
  2. the parent component passes the attribute itemDefaultValue to the child component through props, and the child component watch listens for the properties passed by the parent component. The child component uses a new value itemDefaultValueCopy to deeply copy the passed value and bind it to the child component v-model. Click the button to trigger the parent component to pass the value to the child component. The watch method is called multiple times (actually related to how many rows of data there are in the table)

sources of topics and their own ideas

the strangeness of calling multiple times:
when I itemDefaultValue: [1], the watch method triggers multiple times every time I click the button
when my itemDefaultValue:this.defaultValue,watch method is not triggered (this.defaultValue is the value of the vue data object)

related codes

parent component: 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"
                                        }
                                    }, "")
                                ])
                            ]);
                        }
                    }
                ]
            }
        }

Sub-component code 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);
            }
        }
    }

what result do you expect? What is the error message actually seen?

when the parent component itemDefaultValue: this.defaultValue is written as [1] , the effect is as follows (watch is called every time you click the button):

clipboard.png

clipboard.png
ask the master to solve the puzzle!

Mar.31,2021

Q: why is the subcomponent watch method called multiple times?

A: when itemDefaultValue: [1] has modified the value of watch?

Q: when the itemDefaultValue:this.defaultValue,watch method does not trigger

A: for the same reason that direct use of data: {} in data is not recommended in Vue, the reference type is called directly and the watch method is not triggered.

Demo is required


what is the reason why I also met and cried

Menu