vue学习日志(1)数据代理
1、Javascripts中的数据代理:Object.defineProperty
1-1、Object.defineProperty作用
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。1-2、Object.defineProperty的常用属性设置
在默认情况下,通过Object.defineProperty()方法添加的属性值无法遍历(for...in...或Objects.keys()等方法)、修改(immutable)或者删除(delete)。但Object.defineProperty()方法允许精确地添加或修改对象的属性,以下案例将具体展示各个特性的修改方式。<script>
let number = 18
let person = {
name: 'john',
sex: 'man',
// age: 18 //对象中定义的原生属性可遍历、可修改、可删除
}
//Object.defineProperty()方法生成的属性在默认情况下不可遍历,不可修改,不可删除
Object.defineProperty(person, 'age', {
// value: 18,
// enumerable: true, //赋予可遍历特性,默认为false
// writable: true, //赋予可修改特性,默认为false
// configurable: true, //赋予可删除特性,默认为false
//读取person的age属性时,get函数就会被调用,返回值就是age的值
get: function () {
return number
},
//读取person的age属性时,set函数就会被调用,收到修改的值
set(value) {
console.log('age have been changed')
number = value;
}
})
</script>
1-3、Object.defineProperty的数据代理案例
案例中,定义了obj和obj2两个对象,基于Object.defineProperty方法,可以通过obj2获取、修改obj中的属性。<script>
let obj = { x: 100 }
let obj2 = { y: 200 }
Object.defineProperty(obj2, 'x', {
get() {
return obj.x
},
set(value) {
obj.x = value
}
})
</script>
2、数据代理在vue中的体现
通过以下代码可以看出,当修改vue模板的name属性时,vue._data中的name属性也相应发生改变。我们并没有直接修改vue._data中的name值,可见其中发生了数据代理的修改过程(setter函数)。<body>
<div id="root">
<h2>Name:{{name}}</h2>
<h2>Location{{address}}</h2>
</div>
</body>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data: {
name: 'john',
address: 'Chicago'
}
})
</script>
观察vm属性发现,确实存在类似于Object.defineProperty方法的数据代理过程存在,分别为address和name属性。
3、vue模型下的数据代理关系
通过简单梳理vue模型的运作流程,我们可以发现vm._data与vm本身的属性之间存在数据代理(也称数据劫持)关系,这一步操作主要是为了在vue模板中更加方便的调用属性。假设vm中没有name属性,或者vm._data中不存在复杂的get和set方法,我们仅能在模板中通过{{_data.name}}调用,这显然更麻烦。同样的,当我们写语句 vm.xxx的时候(而不是vm._data.xxx),就会去调用到get方法,当我们给vm.xxx赋值的时候,就会去调用set方法。参考网站:
1、MDN官网:Object.defineProperty()简介2、视频:vue中的数据代理