Vue 理解之白话理解之白话 getter/setter详解详解
主要介绍了Vue getter setter,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
价值,需要的朋友们下面随着小编来一起学习学习吧
当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty
把这些属性全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是为什么 Vue 不支持 IE8
以及更低版本浏览器
以上摘自 深入响应式原理
那么,把这些属性全部转为 getter/setter 具体是怎样一个过程呢?本文不深入具体,简单大致了解其过程,旨在整体把握,理
解其主要思路
假设代码如下:
const vm = new Vue({
el: '#app',
data: {
msg: 'hello world'
}
})
data 选项可以接收一个对象或者方法,这里以对象为例(其实最后都会转为对象)
首先,这个对象的所有键值对都会被挂载在 vm._data 上(此外 vm._data 对象上还有个 __ob__ key,暂时可以忽视),这样
我们便能用 vm._data.msg 访问到数据
但是通常我们是用 vm.msg 这样访问数据,如何做到的呢?其实就是做了个代理,将 data 键值对中的 vm[key] 的访问都代理
到 vm._data[key] 上
proxy(vm, `_data`, key)
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)
}
通常 vm._data (下划线变量)用作内部程序,对外暴露的 API 是 vm.$data,其实这两者也是一个东西,也是做了个代理,
代码大概这样:
const dataDef = {}
dataDef.get = function () { return this._data }
Object.defineProperty(Vue.prototype, '$data', dataDef)
if (process.env.NODE_ENV !== 'production') {
dataDef.set = function () {
warn(
'Avoid replacing instance root $data. ' +
'Use nested data properties instead.',
this
)
}
}
简单理解就是访问 vm.data.msg 其实就是访问 vm._data.msg。如果直接在开发环境对 vm.data = xxx这样的赋值,而不是
vm.$data.msg = xxx` 这样的赋值,后者是没问题的)
至此,我们理解了为什么能用 vm.msg、vm._data.msg 以及 vm.$data.msg 三种方式获取/改变数据,最原始的数据是
vm._data.msg,而另外两者即代理了 _data 的数据,vm.$data.msg 即为 Vue 向外提供的 API,一般情况下开发我们直接用
vm.msg 这样比较多,也方便,如果要获取整个 data,程序中需要用 this.$data,而不是 this.data
接下来说 getter/setter
将 demo 稍微添点东西:
const vm = new Vue({
评论0