为什么Vue组件中的data是一个函数原理(详细易懂)

组件中的data

组件是一个具有单独自身功能模块的封装,这个模块有属于自己的HTML模板,也应该有属于自己的数据data,组件也有自己的方法methods
注意:组件不能直接访问Vue实例中定义的数据。就算可以访问,若将所有的数据都放在Vue实例中,Vue实例就会变得非常臃肿(数据很多),所以组件应该有自己保存数据的地方
因此,data属性必须是一个函数,并且这个函数返回一个对象在对象内部保存数据

实例

<body>
  <div id="app">
    <cpn1></cpn1>
  </div> 

<template id="cpn">
  <div>
    <h2>{{message}}</h2>
    //不会渲染,控制台报错
     <h2>{{title}}</h2>
  </div>
</template>

<script src="../vue.js"></script>
<script>   
 const app = new Vue({
    el:'#app',
    data:{
      title:"Vue"
    },
    components:{
      "cpn1":{
        template:"#cpn",
        //data位一个函数返回对象
        data(){
          return {
            message:"hello vue"
          }
        }
      }  
    }
  })
</script>
</body>

在这里插入图片描述

data是函数----原理

function知识

在解释原理之前先来看两个个有关函数的例子
示例一:

<script>
    function person() {
        return {
            name:"a",
            age:22
        }
    };

    var obj1 = person();
    var obj2 = person();
    obj1.name = 'b';
    console.log(obj1);
    console.log(obj2);
    
</script>

在这里插入图片描述
示例二:

<script>
    const obj = {
        name:"a",
        age:22
    }
    function person() {
        return obj;
    };

    var obj1 = person();
    var obj2 = person();
    
    obj1.name = 'b';
    console.log(obj1);
    console.log(obj2);
    
</script>

在这里插入图片描述
总结:第一个示例中每调用一次函数都返回一个新的对象,而在第二个示例中所共用一个对象。所以,在改变其中一个对象某一属性的值时,第一个示例中的两个对象不会相互影响,而第二个示例中则是相互影响的。
在这里插入图片描述
在这里插入图片描述

data是函数的原理

有了上面知识的基础,就很好理解原理了。还是用实例来解释,该实例中是用组件实现多个计数器功能

<body>
<div id="app"> 
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

  <template id="cpn">
    <div>
      <h2>当前计数:{{count}}</h2>
      <button @click="sub">-</button>
      <button @click="add">+</button>
    </div>
  </template> 


<script src="../vue.js"></script>
<script>
  Vue.component('cpn',{
    template:"#cpn",
    //调用data函数,每次调用都返回一个新的对象
    data(){
      return {
        count:0
      }
    },
    //组件中的methods
    methods:{
      add() {
        this.count++;
      },
      sub() {
        this.count--;
      }
    }
  })
  const app = new Vue({
    el:'#app',
  })
</script>
</body>

在这里插入图片描述

案例总结

创建了三个组件实例计数器,每个计数器可以完成自己的计数功能,互不影响。即实例中的data对象都是不同的(没有共享data对象),可以参考function知识中的示例一

举一反三

还是以上面这个计数器的例子,对代码稍作更改(更改部分已作注释),也会有不一样的效果。

<body>
<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

  <template id="cpn">
    <div>
      <h2>当前计数:{{count}}</h2>
      <button @click="sub">-</button>
      <button @click="add">+</button>

    </div>
  </template> 


<script src="../vue.js"></script>
<script>
//更改部分
  const counter = {
    count:0
  };
  Vue.component('cpn',{
    template:"#cpn",
    //更改部分
    data(){
      return counter 
    },
    methods:{
      add() {
        this.count++;
      },
      sub() {
        this.count--;
      }
    }
  })
  const app = new Vue({
    el:'#app',
  })
</script>
</body>

在这里插入图片描述
总结:这一个例子共用了一个对象,可以参考function知识示例二,这种连锁反应一般在组件中很少应用到,因为组件是复用的,自然就不希望数据共享,而是有自己的逻辑,保存自己数据的实例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章