vue组件的data为什么是一个函数(代码演示和讲解)

问题描述

  • 通过 new Vue 创建的根 Vue 实例中的 data 是一个对象,用来保存数据,那么组件有没有 data 呢?
  • 组件不能直接访问Vue实例中的data,所以组件应该有自己保存数据的地方
  • 组件对象也有一个data属性(也可以有methods等属性),只是组件的data属性必须是一个函数,而且这个函数返回一个对象,对象内部保存着数据

那么我们创建的vue组件中的 data 为什么要是一个函数呢?因为这样每个组件实例就可以维护一份【被返回对象】的独立的拷贝!!

首先,最明显的感知,如果我们手动把组件中的data赋值为一个对象,运行代码的时候会报错,报错信息提示我们 data 应该是一个函数,如图:
在这里插入图片描述
其次,原因是在于Vue让每个组件对象都返回一个新的对象,因为如果是同一个对象,组件在多次使用后会相互影响。


代码演示

演示1:组件的 data 是一个函数,返回一个新对象

<div id="app">
  <!--两个组件实例-->
  <cpn></cpn>
  <hr>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>计数器:{
   
   {counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
   //创建注册一个计数器组件
  Vue.component('cpn', {
     
     
    template: '#cpn',
    //组件的data属性是一个函数,函数返回一个对象,该对象内部保存着组件实例的数据
    data: function () {
     
      
      return {
     
     
        counter: 0
      }
    },
    methods: {
     
     
      increment() {
     
     
        this.counter++;
      },
      decrement() {
     
     
        this.counter--;
      }
    }
  })
  let vm = new Vue({
     
     
    el: "#app",
    data: {
     
     }
  });
</script>

上边代码的效果:每一个组件实例都维护者各自的数据对象,互不干扰。
在这里插入图片描述


演示2:组件的 data 是一个函数,返回一个固定的对象

我们看最终的结果就可以明白为什么要把这个函数设计成每次返回一个新对象了。

<div id="app">
  <!--两个组件实例-->
  <cpn></cpn>
  <hr>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>计数器:{
   
   {counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  //提前定义一个对象
  let obj = {
     
     
    counter: 0
  };
  Vue.component('cpn', {
     
     
    template: '#cpn',
    data: function () {
     
     
      //返回提前定义好的obj对象
      return obj;
    },
    methods: {
     
     
      increment() {
     
     
        this.counter++;
      },
      decrement() {
     
     
        this.counter--;
      }
    }
  })
  let vm = new Vue({
     
     
    el: "#app",
    data: {
     
     }
  });
</script>

效果如图所示,两个计数器互相影响,这不是我们想要的结果。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43974265/article/details/112630275
今日推荐