vue

Vue为什么可以通过this直接访问data的值

Posted by weite122 on 2019-07-01

为什么可以直接通过this 访问到data的值

  • Vue 一开始会调用_init方法进行初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Vue (options) {
if (process.env.NODE_ENV !== 'production' && // 非生产模式
!(this instanceof Vue)// 判断 this 对象的 prototype 是否存在于构造函数 Vue 的原型链上
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options) //传入options
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
  • 在init.js文件中找到initState,跳转到initState函数定义,可以找到initDate(vm)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function initState (vm) {
vm._watchers = [];
var opts = vm.$options;
if (opts.props) { initProps(vm, opts.props); }
if (opts.methods) { initMethods(vm, opts.methods); }
if (opts.data) {
initData(vm);//这里初始化Data
} else {
observe(vm._data = {}, true /* asRootData */);
}
if (opts.computed) { initComputed(vm, opts.computed); }
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch);
}
}
  • initData 的定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function initData (vm) {
var data = vm.$options.data; //获取到data的值,vm就是一个Component,在最开始的init赋予了this的值
data = vm._data = typeof data === 'function' //vm._data是一个私有变量,也可以通过this._data.xxx访问data的值
? getData(data, vm) //判断data是否为一个函数,vue在定义组件的时候,data必须是一个函数
: data || {};
if (!isPlainObject(data)) {
data = {};
warn(
'data functions should return an object:\n' +
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
vm
);
}
// proxy data on instance
var keys = Object.keys(data);
var props = vm.$options.props;
var methods = vm.$options.methods;
var i = keys.length;
while (i--) {
var key = keys[i];
{
if (methods && hasOwn(methods, key)) {//函数名不能和data的值冲突
warn(
("Method \"" + key + "\" has already been defined as a data property."),
vm
);
}
}
if (props && hasOwn(props, key)) {//在props上定义的值不能再data定义,如果定义,会覆盖
warn(
"The data property \"" + key + "\" is already declared as a prop. " +
"Use prop default value instead.",
vm
);
} else if (!isReserved(key)) {
proxy(vm, "_data", key); //proxy是代理
}
}
// observe data
observe(data, true /* asRootData */); //监听data的值
}
  • proxy 的定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var sharedPropertyDefinition = {
enumerable: true,//可枚举
configurable: true,//可配置
get: noop,
set: noop
};

function proxy (target, sourceKey, key) { //调用时参数为 {vm, "_data", key}
sharedPropertyDefinition.get = function proxyGetter () {
return this[sourceKey][key]
};
sharedPropertyDefinition.set = function proxySetter (val) {
this[sourceKey][key] = val;
};
Object.defineProperty(target, key, sharedPropertyDefinition); //在vm上添加key属性,比如访问vm.message即访问this._data.message, vm就是this的值
}