目次
1. Vue2 は Object.defineProperty を渡します
3. リアクティブ、ref、toRef、toRefs の違い
1. Vue2 は Object.defineProperty を渡します
1.1、単一の属性を監視する
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、オブジェクトを監視する
obj オブジェクトに値を代入する場合は、無限ループに注意してください。
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方法,相当于递归,会形成死循环
外部で定義できる set メソッドや get メソッドでの再帰を回避するための改善
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
2、プロキシ経由の vue3
vue3 の実装はよりエレガントです
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. リアクティブ、ref、toRef、toRefs の違い
公式ドキュメント: Refs | Vue.js
受け入れる | 戻る | |
---|---|---|
反応性 | オブジェクトタイプ | レスポンシブ オブジェクト(プロキシ オブジェクト) |
参照 | 基本データ型 (オブジェクト型の場合はリアクティブ関数が呼び出されます) |
.valueプロパティを持つレスポンシブで変更可能な ref オブジェクトを返します |
toRef と toRefs
同じ:
- toRef と toRefs は、レスポンシブ オブジェクトのプロパティをレスポンシブに変換します。
- ソース オブジェクトへのレスポンシブ リンクは失われません。つまり、ソース オブジェクトのプロパティ値が変更された場合、生成された新しいオブジェクトの対応するプロパティ値 (ref) も変更され、その逆も同様です。
違い:
- toRef: ソース オブジェクトと属性名の 2 つのパラメーターを受け取り、ref データを返します。
- toRefs: すべてのプロパティを一度にレスポンシブに変換します。レスポンシブ オブジェクトの分解によく使用されます。
注:
データに対して ref 操作のみを実行した場合、得られるのはデータのコピーです。結果データの値を変更してもソース オブジェクトの値は変更されませんが、toRef または toRefs を介して取得されるのはデータ参照です。