Table of contents
1. Vue2 passes Object.defineProperty
3. The difference between reactive, ref, toRef, and toRefs
1. Vue2 passes Object.defineProperty
1.1, monitor a single attribute
var obj={
a:1,
b:'字符串b'
}
var obj2
Object.defineProperty(obj,'a',{
get:()=>{
console.log('触发get')
return 'aaa'
},
set:(v)=>{
console.log("触发set")
obj2=v
}
})
console.log('obj2初始:',obj2) // obj2初始: undefined
obj.a // 触发get
obj.a = 3 // 触发set,
console.log('obj2现:',obj2) // obj2现: 3
console.log('obj.a:',obj.a) //触发get obj.a: aaa //set中无返回值,所以obj.a = 3 本质是对obj2 进行赋值
1.2, monitor the object
When you want to assign a value to the obj object, be careful of an infinite loop.
var obj={
a:1,
b:'字符串b'
}
var obj2
Object.keys(obj).forEach(k=>{
Object.defineProperty(obj,k,{
get:()=>{
console.log('触发get')
return 'aaa'
},
set:(v)=>{
console.log("触发set")
return obj[k]=v
}
})
})
obj.b = 'ss' //结果会重复打印“触发set” --由于set中也调用了 obj的set方法,相当于递归,会形成死循环
Improvement to avoid recursion in the set or get method, which can be defined externally
var obj={
a:1,
b:'字符串b',
c:[],
d:{
name:'eee'
}
}
function definePropertyFun(data,key,val){
if(Object.prototype.toString.call(val)==='[object Object]'){
observer(val)
return
}
Object.defineProperty(data,key,{
get:()=>{
console.log('触发get')
return val
},
set:(v)=>{
console.log("触发set")
return val=v
}
})
}
function observer(data){
if(Object.prototype.toString.call(data) !=='[object Object]'){
console.log('传参要是对象类型')
return
}
Object.keys(data).forEach( k => {
definePropertyFun(data,k,data[k])
})
}
observer(obj) //对对象进行监听
obj.a=5 // 触发set
console.log(obj.a); // 触发get 5
obj.c = [0,1] // 触发set
obj.c[1]=2 // 触发get 无法触发 set ,vue2中也无法触发set
obj.c.push(3) // 触发get vue2可以触发set,它对push进行了重写
obj.d.name = 's' // 触发set
Two, vue3 through Proxy
The implementation of vue3 is more elegant
var obj={
a:1,
b:'字符串b',
c:[],
d:{
name:'eee'
}
}
var obj2='d'
const newobj = new Proxy(obj,{
get:(data,val)=>{
console.log('触发get')
return data[val]
},
set:(data,key,val)=>{
console.log("触发set")
return data[key]=val
}
})
newobj.a //触发get
newobj.c.push(3) //触发get
newobj.d.name //触发get
newobj.p="ds" //触发set 原本不存在的属性也可以
3. The difference between reactive, ref, toRef, and toRefs
Official Documentation: Refs | Vue.js
accept | return | |
---|---|---|
reactive | object type | Responsive object (proxy object) |
ref | basic data type (If it is an object type, the reactive function will be called) |
Returns a responsive and mutable ref object with a .value property |
toRef and toRefs
same:
- toRef and toRefs convert the properties in the responsive object to responsive.
- The responsive link to the source object is not lost, that is, if the property value of the source object is modified, the corresponding property value (ref) of the generated new object will also be modified, and vice versa.
the difference:
- toRef: accepts two parameters, the source object and the attribute name, and returns a ref data
- toRefs: Convert all properties to responsive at one time. Often used for destructuring of responsive objects
Note :
If only the ref operation is performed on the data, what is obtained is a copy of the data. Changing the value of the result data will not change the value of the source object, but what is obtained through toRef or toRefs is the data reference