We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
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 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
// 我们的数据对象 var data = { a: 1 } // 该对象被加入到一个 Vue 实例中 var vm = new Vue({ data: data }) // 获得这个实例上的属性 // 返回源数据中对应的字段 vm.a == data.a // => true // 设置属性也会影响到原始数据 vm.a = 2 data.a // => 2 // ……反之亦然 data.a = 3 vm.a // => 3
vm.$options.data.a
vm.a
其实我们知道,为new Vue({data: ...})的时候,会进行mergeOptions,也就是吧所有的参数挂载到vm.$options中,我们定义的data也是会被挂载进去,那么,为什么我们可以通过vm.a来取到我们想要的值呢?我们来看一下源码的实现:
new Vue({data: ...})
mergeOptions
vm.$options
data
// core/instance/state.js function initData (vm: Component) { let data = vm.$options.data data = vm._data = typeof data === 'function' ? getData(data, vm) : data || {} ... }
Vue通过initData函数,为实例vm定义了一个_data属性,他的值等于我们的vm.$options.data。并做了函数处理,因为有可能我们是通过一个function去return一个data。那到这一步,我们顶多可以通过this._data.xx来访问属性,那如何实现this.xx来访问呢?我们接着来看:
initData
vm
_data
vm.$options.data
function
return
this._data.xx
this.xx
... const keys = Object.keys(data) let i = keys.length while (i--) { ... proxy(vm, `_data`, key) } ...
我们省略了一些代码,主要来看核心的实现。首先我们会遍历data中定义的属性,然后有一个proxy这样的东西
proxy
const sharedPropertyDefinition = { enumerable: true, configurable: true, get: noop, set: noop } 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) }
这里用了一个Object.defineProperty函数来定义了target = vm,sourceKey = _data,key = xx。并改写了target.key的get和set方法。 到这里我们就明白了,当我们访问this.xx的时候,其实是被Object.defineProperty拦截了,代理到this._data.xx上面。
Object.defineProperty
target = vm
sourceKey = _data
key = xx
target.key
get
set
The text was updated successfully, but these errors were encountered:
No branches or pull requests
为什么不是访问
vm.$options.data.a
而是vm.a
?其实我们知道,为
new Vue({data: ...})
的时候,会进行mergeOptions
,也就是吧所有的参数挂载到vm.$options
中,我们定义的data
也是会被挂载进去,那么,为什么我们可以通过vm.a
来取到我们想要的值呢?我们来看一下源码的实现:Vue通过
initData
函数,为实例vm
定义了一个_data
属性,他的值等于我们的vm.$options.data
。并做了函数处理,因为有可能我们是通过一个function
去return
一个data
。那到这一步,我们顶多可以通过this._data.xx
来访问属性,那如何实现this.xx
来访问呢?我们接着来看:我们省略了一些代码,主要来看核心的实现。首先我们会遍历
data
中定义的属性,然后有一个proxy
这样的东西这里用了一个
Object.defineProperty
函数来定义了target = vm
,sourceKey = _data
,key = xx
。并改写了target.key
的get
和set
方法。到这里我们就明白了,当我们访问
this.xx
的时候,其实是被Object.defineProperty
拦截了,代理到this._data.xx
上面。The text was updated successfully, but these errors were encountered: