为什么vue中data必须是一个函数

为什么vue中data必须是一个函数

类比引用数据类型
  • Object是引用数据类型,如果不用function 返回,每个组件的data 都是内存的同一个地址,一个数据改变了其他也改变了;

  • javascipt只有函数构成作用域(注意理解作用域,只有函数的{}构成作用域,对象的{}以及if(){}都不构成作用域),data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响

  • 如果 data 是个对象,那么整个vue实例将共享一份数据,也就是各个组件实例间可以随意修改其他组件的任意值,这就有坑了【原型继承的槽点:指向相同,所有实例都会改变】。

  • 但是 data 定义成一个函数,将会 return 出一个唯一的对象,不会和其他组件共享一个对象。

我们注册组件的时候实际上是建立了一个组件构造器的引用,只有使用组件的时候才会真正创建一个组件实例。

  1. 指向同一个对象/属性问题
    function Person () {}
    Person.prototype.data = {
      a:1,
      b:2
    }
    let p1 = new Person();
    let p2 = new Person();
   
    p1.data.a= 'A';
    console.log(p2.data.a); // 'A'
  1. 解决:每一个实例化Vue组件对象下都有一个单独的data方法
    function Person2 () {
        this.data = this.data();
    }
    Person2.prototype.data = function () {
        return {
            a: 1,
            b: 2
        }
    }
    let p4 = new Person2();
    let p5 = new Person2();
    p4.data.a = 'A';
    console.log(p5.data.a); // 1

Vue源码:

    function initData (vm: Component) {
      let data = vm.$options.data 
      data = vm._data = typeof data === 'function' ? getData(data, vm): data || {}
    }
    export function getData (data: Function, vm: Component): any {
      pushTarget()
      try {
        return data.call(vm, vm)
      } catch (e) {
        handleError(e, vm, `data()`)
        return {}
      } finally {
        popTarget()
      }
    }

你可能感兴趣的:(为什么vue中data必须是一个函数)