vue2.x の応答性
実装原則:
- オブジェクト タイプ: Object.defineProperty() (データ ハイジャック) を使用して、プロパティの読み取りと変更を傍受します。
- 配列タイプ: インターセプトは、配列を更新する一連のメソッドをオーバーライドすることによって実現されます。(配列の変更メソッドはラップされます)。
Object.defineProperty(data, 'count', {
get () {}, //对象有数据属性,和可隐藏的访问器属性
set () {} //访问器属性就是get(){}和set(){}
})
Object.defineProperty()
语法:Object.defineProperty(obj, prop, descriptor)
オブジェクト |
小道具 |
ディスクリプタ |
プロパティを定義するオブジェクト。 |
定義または変更するプロパティの名前またはシンボル。 |
定義または変更するプロパティ記述子。 |
例:
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false //属性值是否可以修改
});
object1.property1 =77;
// object1.property1值不变
console.log(object1.property1);
// expected output: 42
問題があります:
- 属性を追加または削除する場合、インターフェースは更新されません。
- 添字を使用して配列を直接変更すると、インターフェイスは自動的に更新されません。
<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>
図のように[性別の追加]と[年齢の削除]をクリックすると、データは変化していますが、ページは変化していません。
解決
Vue.set または this.$set を使用します
语法: Vue.set( target, key, value ) / this.$set( target, key, 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)
},
削除メソッドは delete と呼ばれ、その他の使用方法は同じです。好き
change(){
//this.person.sex = "女";
this.$delete(this.person,"sex","女")
console.log(this.person)
},
Vue3.0 の応答性
- プロキシ経由 (プロキシ): 属性値の読み取りと書き込み、属性の追加、属性の削除などを含む、オブジェクト内の任意の属性の変更を傍受します。
- Through Reflect (反射): ソース オブジェクトのプロパティを操作します。
- Proxy と Reflect は MDN ドキュメントで説明されています:
- プロキシ:プロキシ - JavaScript | MDN
- リフレクト:リフレクト - JavaScript | MDN
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'