Analysis of Vue FAQ (2) Why is the data of the component defined as a function, while the data of the root instance is not limited?

Background: Vue componentization is its characteristic. We often define components and we will know that the data of the component is defined as a function, and we also know that it is to avoid data pollution, but the root instance is not mandatory (because the root instance is a singleton, don’t worry data pollution), what is the specific reason? Let's also analyze it from the source code. For details, see the source code: the initData() method in src/core/instance/state.js. Of course, we also use the demo to illustrate. The demo is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data</title>
</head>
<body>
    <div>vue组件data为什么必须是个函数而Vue的根实例则没有限制?源码中详见:src/core/instance/state.js中的initData()</div>


    <div id="demo">
       <div>vue组件data为什么必须是个函数?</div>
       <comp></comp>
       <comp></comp>
       <div>{
   
   {counter}}</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component('comp',{
            template:'<div @click="counter++">{
   
   {counter}}</div>',
            // data: {counter: 0}如果这么定义首先会报错,要求data为函数,原因是为了避免多个组件数据互相影响,造成数据污染,一会从源码中解释
            data () {
                return {
                    counter:1
                }
            }
        })
        //创建实例
        const app = new Vue({
            el: '#demo',
            data:{counter:1}
        });
        console.log(app.$options.render);
    </script>
</body>
</html>

1. The reason why the source code explains that component data must be a function is as follows:

It can be seen from the above that if the component does not use the function, the data will be shared and the data will be polluted.

2. I just said that there is no limit to the data of the root component. One is because const app = new Vue({el:'#demo'}) is a singleton. In addition, it can also be analyzed from the source code as follows: /src/core/instance/ init.js

By adding a breakpoint to mergeoptions, it is found that the custom build will be executed first, and then the root component will be executed. The source code location: /src/core/util/options.js. For details, see the merge strategy, as follows:

It can be seen from the above that when the vm does not exist when using the custom component, the judgment is made. If the root component instance is created, the condition detection will not be performed, so the data in the root component does not need to be defined as a function.

In summary, the following conclusions are drawn:

There may be multiple instances of Vue components, and defining data directly in the form of objects will cause components to share a data object, and state changes will affect all component instances, which is unreasonable. In the form of a function, it will be used as a factory function to return a brand new data object when initData, avoiding the problem of state pollution between instances. However, this limitation does not exist during the creation of the vue root instance, because there is only one root instance and there is no need to worry about this problem.

In summary, it explains why the data of vue's custom components needs to be defined as a function, but the root instance does not have this limitation. I hope it will be helpful to everyone. The above, thank you.

Guess you like

Origin blog.csdn.net/wh_xmy/article/details/109599347