Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue组件中的data为什么是个函数? #102

Open
Cosen95 opened this issue Apr 25, 2020 · 1 comment
Open

Vue组件中的data为什么是个函数? #102

Cosen95 opened this issue Apr 25, 2020 · 1 comment
Labels

Comments

@Cosen95
Copy link
Owner

Cosen95 commented Apr 25, 2020

No description provided.

@Cosen95 Cosen95 added the vue label Apr 25, 2020
@Cosen95
Copy link
Owner Author

Cosen95 commented Apr 26, 2020

其实这个问题还有下半句:而 new Vue 实例里,data 可以直接是一个对象?

先来看下平时在组件和new Vue时使用data的场景:

// 组件
data() {
  return {
	  msg: "hello 森林",
  }
}

// new Vue
new Vue({
  data: {
    msg: 'hello jack-cool'
  },
  el: '#app',
  router,
  template: '<App/>',
  components: {
    App
  }
})

我们知道,Vue组件其实就是一个Vue实例。

JS中的实例是通过构造函数来创建的,每个构造函数可以new出很多个实例,那么每个实例都会继承原型上的方法或属性。

Vuedata数据其实是Vue原型上的属性,数据存在于内存当中

Vue为了保证每个实例上的data数据的独立性,规定了必须使用函数,而不是对象。

因为使用对象的话,每个实例(组件)上使用的data数据是相互影响的,这当然就不是我们想要的了。对象是对于内存地址的引用,直接定义个对象的话组件之间都会使用这个对象,这样会造成组件之间数据相互影响。

我们来看个示例:

// 创建一个简单的构建函数
var MyComponent = function() {
    // ...
}
// 原型链对象上设置data数据,data设为Object
MyComponent.prototype.data = {
  name: '森林',
  age: 20,
}
// 创建两个实例:春娇,志明
var chunjiao = new MyComponent()
var zhiming = new MyComponent()
// 默认状态下春娇和志明的年龄一样
console.log(chunjiao.data.age === zhiming.data.age) // true
// 改变春娇的年龄
chunjiao.data.age = 25;
// 打印志明的年龄,发现因为改变了春娇的年龄,结果造成志明的年龄也变了
console.log(chunjiao.data.age)// 25
console.log(zhiming.data.age) // 25

使用函数后,使用的是data()函数,data()函数中的this指向的是当前实例本身,就不会相互影响了。

总结一下,就是:

组件中的data是一个函数的原因在于:同一个组件被复用多次,会创建多个实例。这些实例用的是同一个构造函数,如果 data 是一个对象的话。那么所有组件都共享了同一个对象。为了保证组件的数据独立性要求每个组件必须通过 data 函数返回一个对象作为组件的状态。

new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant