This is the 31st day of my participation in the August More Text Challenge

Question origin

In a recent production project, the parent component passed an Object to the child component. Because there was too much Object data in the child component, I “lazy” and wrote this in the child component’s data:

. data () {return {
    content: {}}}...Copy the code

Unexpectedly, this line of code spent an afternoon looking for a response question: why does the child component data not change after the data is updated?

This led me to re-understand the depth response principle of VUE. The original document is more detailed than I wrote. Here are some practical things — things you can use in the real world.

Now VUE3 is online, I haven’t learned VUE2 too, is not too dish.

So let’s take a look at Object and array listening in VUE.

The experiment

Object listening problem reappears

In the official VUE documentation:

Due to JavaScript limitations, Vue cannot detect array and object changes.

So, what does “undetectable” mean?

Take a look at the following experimental code:

<! DOCTYPEhtml>

<head>
    <script src="http://unpkg.com/vue/dist/vue.js"></script>
    <script src="http://unpkg.com/[email protected]/lib/index.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>

<body>
    <div id="app">
        <template>
            <div>
                {{message}}
            </div>
            <div>Object: {{obj}}</div>
            <div>
                computed: obj.a = {{objA}}
            </div>
            <div>
                computed: obj.c = {{objC}}
            </div>
            <el-button type="primary" @click="changeData">Update the data</el-button>
        </template>
    </div>
    <script>
        var Main = {
            data() {
                return {
                    message: 'Before data modification:'.obj: {
                        a: 1.b: 2}}},computed: {
                objA() {
                    return this.obj.a
                },
                objC() {
                    return this.obj.c
                }
            },
            methods: {
                changeData() {
                    this.obj.c = '2';
                    this.message = 'After data modification:'}}}var Ctor = Vue.extend(Main)
        new Ctor().$mount('#app')
    </script>
</body>

</html>
Copy the code

Let’s take a look at the effect:

As you can see, changes in attributes of obj. A affect computed objA, but assignment of obj. C does not.

Why?

When I define obj in data, I only give two attributes: A and B. When I click on the operation to update data, we set obj.c like this:

this.obj.c = '2'
Copy the code

There is no penalty for computed updates corresponding to objC values.

Let’s try another way to set it according to the official tip: change the above method of updating c value to:

this.$set(this.obj, 'c'.'cvalue')
Copy the code

Let’s see what it looks like:

You can obviously see that the corresponding objC also responds to the change.

For data, some methods trigger view listening: the VUE documentation is very detailed: push, etc., while modifying element values through list[I] does not trigger view listening, I won’t go into details here.