爲什麼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知識示例二,這種連鎖反應一般在組件中很少應用到,因爲組件是複用的,自然就不希望數據共享,而是有自己的邏輯,保存自己數據的實例

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