先来一段vue代码
import Vue from 'vue' new Vue({ el: '#app', data: { message: 'hello world' }, mounted() { console.log(this.message) } })
从源码理解
function Vue (options) { ··· this._init(options) 2、new Vue实例时,执行_init方法 } ··· initMixin(Vue) 1、Vue方法方法创建时,执行initMixin 给原型上绑定了_init方法 ··· ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— Vue.prototype._init = function (options?: Object) { const vm: Component = this ··· initState(vm) 3、执行_init方法,执行initState }
_________________________________________________________________________________________________________________________________
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {
initData(vm) 4、如果实例化Vue时,data存在,执行initData方法
} else {
observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
function initData (vm: Component) {
let data = vm.$options.data data = vm._data = typeof data === 'function' ? getData(data, vm) : data || {} ···省略代码 : 如果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] ······methods中不能存在和data中相同属性的一些判断提示······ if (props && hasOwn(props, key)) { ········props中不能存在和data中相同属性的一些判断提示······· } else if (!isReserved(key)) { proxy(vm, `_data`, key) 5、代理,给vm.key 做一层代理,返回实际vm['_data'][key] } } // observe data observe(data, true /* asRootData */) }
———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
export function proxy (target: Object, sourceKey: string, key: string) {
sharedPropertyDefinition.get = function proxyGetter () { return this[sourceKey][key] } sharedPropertyDefinition.set = function proxySetter (val) { this[sourceKey][key] = val } Object.defineProperty(target, key, sharedPropertyDefinition) // 6、访问vm.key 时 返回了 vm['_data'][key] }
所以在vue中通过this. 方式访问data中的数据时,实际上是返回了this._data中的数据