前言
使用vue更新data的时候,一般都是使用this.name='zzf'命令,但是为什么这么写会触发更新呢,一直不是很了解。今天阅读2.6.12版本源码,有对这个有进一步的理解,在此做个笔记。
更新name数据
分析this.name数据到底访问什么
在src/code/instance/state.js中有一个stateMixin,这个给出了问题的答案。
const dataDef = {}
dataDef.get = function () { return this._data }
Object.defineProperty(Vue.prototype, '$data', dataDef)
通过代码分析,访问this.name,实际上时访问this._data.name。
那this._data跟options的data函数又有什么关系呢?
在src/code/instance/state.js中有一个initData函数,里面有对this._data的一个操作。
function initData (vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {} // 核心就是这里,对options的data函数进行执行,返回的结果存放在vm._data上,后续再监听vm._data,这样子就可以触发更新了
if (!isPlainObject(data)) {
data = {}
}
// proxy data on instance
const keys = Object.keys(data)
const props = vm.$options.props
const methods = vm.$options.methods
let i = keys.length
while (i--) {
const key = keys[i]
if (props && hasOwn(props, key)) {
} else if (!isReserved(key)) {
proxy(vm, `_data`, key)
}
}
// observe data
observe(data, true /* asRootData */) // 监听data数据
}
一开始以为vm.$options.data跟vm._data是同一个对象,后来发现不是同一个对象,_data是options.data函数的执行结果;一开始以为就监听的是options.data对象,后来看到代码才反应过来,监听的是_data对象。(搞混淆了)
总结
所以更新this.name,实际上是更新this._data.name。