Responsive principle in Vue3.0
Responsiveness of vue2.x
1. Implementation principle:
-
- Object type: Intercept the reading and modification of properties through Object.defineProperty() (data hijacking).
- Array type: interception is achieved by overriding a series of methods for updating the array. (The change method of the array is wrapped).
Object.defineProperty(data, 'count', {
get () {}, //对象有数据属性,和可隐藏的访问器属性
set () {} //访问器属性就是get(){}和set(){}
})
Object.defineProperty()
语法:Object.defineProperty(obj, prop, descriptor)
obj | prop | descriptor |
---|---|---|
The object on which to define properties. | The name or Symbol of the property to define or modify . | The property descriptor to define or modify. |
Example:
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false //属性值是否可以修改
});
object1.property1 =77;
// object1.property1值不变
console.log(object1.property1);
// expected output: 42
2. There are problems:
-
- When adding or deleting attributes, the interface will not be updated.
- Modify the array directly through the subscript, and the interface will not be automatically updated.
<template>
<div>
<div>{
{person.name}} </div>
<div>{
{person.age}} </div>
<div v-if="person.sex">{
{person.sex}} </div>
<button @click="change()">增加性别</button>
<button @click="del()">删除年龄</button>
</div>
</template>
<script>
export default {
data(){
return {
person:{name:"gcshi",age:"8"}
}
},
methods:{
change(){
this.person.sex = "女";
console.log(this.person)
},
del(){
delete this.person.age
console.log(this.person)
}
}
}
</script>
As shown in the figure, when you click [Add Gender] and [Delete Age], the data has changed, but the page has not changed
2. Solution:
Use Vue.set or this.$set
语法: Vue.set( target, key, value ) / this.$set( target, key, value )
target | key | value |
---|---|---|
The data source to change (can be an object or an array) | The specific data to be changed | reassigned value |
change(){
//this.person.sex = "女";
this.$set(this.person,"sex","女")
console.log(this.person)
},
//或
import Vue from "vue"
change(){
//this.person.sex = "女";
Vue.set(this.person,"sex","女")
console.log(this.person)
},
The delete method is named delete, and other usages are the same. like
change(){
//this.person.sex = "女";
this.$delete(this.person,"sex","女")
console.log(this.person)
},
Responsiveness of Vue3.0
- Realization principle:
-
- Through Proxy (proxy): Intercept the change of any attribute in the object, including: reading and writing attribute values, adding attributes, deleting attributes, etc.
- Through Reflect (reflection): operate on the properties of the source object.
- Proxy and Reflect described in the MDN document:
- Proxy:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
- Reflect:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
new Proxy(data, {
// 拦截读取属性值
get (target, prop) {
return Reflect.get(target, prop)
},
// 拦截设置属性值或添加新属性
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
// 拦截删除属性
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
proxy.name = 'tom'