Vueプロジェクトでは、データの変更に対処する必要があることがよくあります。現時点では、監視と計算の2つの属性を使用する必要があります。それらはすべて値の変更をトリガーする属性であるため、それらの類似点と相違点は何ですか?
1.計算された属性
特徴:
- 依存データが変更された場合にのみ、キャッシュをサポートし、計算が再計算されます。
- 非同期はサポートされていません。計算に非同期操作がある場合は無効であり、データの変更を監視することはできません。
- 計算された属性値はデフォルトでキャッシュされ、計算された属性は応答する依存関係に基づいてキャッシュされます。つまり、データで宣言された、または親コンポーネントによって渡された小道具のデータに基づいて計算された値。
- 属性が他の属性から計算される場合、この属性は他の属性に依存して、一般的に計算される多対1または1対1になります。
- 計算されたプロパティ値が関数の場合、デフォルトでgetメソッドが使用され、関数の戻り値はプロパティのプロパティ値です。計算されたプロパティでは、プロパティにgetメソッドとsetメソッドがあります。データが変更されると、setメソッドが呼び出されます。
<template>
<div>
<el-input v-model="firstText"></el-input>
<el-input v-model="lastText"></el-input>
<el-input v-model="mergeText1"></el-input>
<el-input v-model="mergeText2"></el-input>
</div>
</template>
<script>
export default {
data() {
return {
firstText:'hello',
lastText:'world',
};
},
computed:{
mergeText1(){
return this.firstText + ' ' + this.lastText;
},
mergeText2:{
/* 通过mergeText2反向赋值给 firstText和lastText */
// getter
get() {
// 回调函数 当需要读取当前属性值是执行,根据相关数据计算并返回当前属性的值
return `${
this.firstText} ${
this.lastText}`;
},
// setter
set(val) {
//监视当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据,val就是fullName的最新属性值
const names = val.split(' ');
console.log(names);
this.firstText = names[0];
this.lastText = names[names.length - 1];
}
}
},
};
</script>
利点:
- データ変数の値が変更されると、アプリケーション全体が再レンダリングされ、Vueはデータによってdomに再レンダリングされます。このとき、名前を使用すると、メソッドはレンダリングで呼び出され、計算は再計算されないため、パフォーマンスのオーバーヘッドは比較的小さくなります。新しい値を取得するために多くの計算が必要な場合、キャッシュの意味は非常に大きくなります。
- 計算されたデータが変更された場合、計算されたプロパティは再計算されてキャッシュされます。他のデータが変更された場合、計算されたプロパティは再計算されないため、パフォーマンスが向上します。
- 得られた値を処理して使用する必要がある場合は、computedを使用できます。
アプリケーションシナリオ:
2.リスナー属性ウォッチ
特徴:
- キャッシュをサポートしていません。データの変更により、対応する操作が直接トリガーされます。
- 時計は非同期操作をサポートしています。
- リスニング関数は2つのパラメーターを受け取ります。最初のパラメーターは最新の値、2番目のパラメーターは入力前の値です。
- 属性が変更された場合、対応する操作を1対多で実行する必要があります。
- 監視データは、データで宣言されているか、親コンポーネントから渡された小道具のデータである必要があります。データが変更されて他の操作がトリガーされる場合、関数には2つのパラメーターがあります。
即時:コンポーネントの読み込みによりコールバック関数の実行が即座にトリガーされます
。deep:詳細な監視。オブジェクトの内部値の変更を見つけるために、次の場合に使用されます。配列内のオブジェクトなどの複雑なタイプのデータコンテンツの変更については、注:配列内の変更を監視するためにこれを行う必要はありません。注:Deepは、配列の変更とオブジェクトの追加を監視できません。Vue配列の変更を参照してください。応答する方法でトリガーされた場合にのみ、監視されます。
注:この方法は、データが変更されたときに非同期操作またはコストのかかる操作を実行する必要がある場合に最も役立ちます。これは、計算との最大の違いです。
2.1一般的な使用法、単一の変数または配列を監視する
<template>
<div>
<el-input v-model="firstText"></el-input>
<el-input v-model="lastText"></el-input>
<el-input v-model="mergeText"></el-input>
</div>
</template>
<script>
export default {
data() {
return {
firstText:'hello',
lastText:'world',
mergeText:'',
};
},
watch:{
// 监听当firstText的值变化,触发此事件,改变mergeText的值
firstText(newText,oldText){
console.log(newText, oldText);
this.mergeText = newText + ' ' + this.lastText;
}
},
};
</script>
2.2単純なデータ型の監視
<template>
<div>
<el-input v-model="mergeText"></el-input>
</div>
</template>
<script>
export default {
data() {
return {
mergeText:'',
};
},
watch:{
// mergeText值变化即触发
mergeText(newval,oldVal){
console.log(this.mergeText,newval,oldVal);
}
},
};
</script>
2.3複雑なデータの監視(詳細な監視)
deepを使用しない場合、obj.aの値を変更すると、watchはデータの変更を監視できません。デフォルトでは、ハンドラーは属性参照の変更のみを監視します。つまり、1つのレイヤーのみが監視されますが、オブジェクトが変更されました。
immerdiate属性:immediateオプションをtrueとして宣言することにより、ハンドラーをすぐに実行できます。
<template>
<div>
<el-input v-model="obj.text"></el-input>
</div>
</template>
<script>
export default {
data() {
return {
obj:{
text:'hello'
}
};
},
watch:{
// 监听对象obj的变化
obj:{
handler (newVal,oldval) {
console.log(newVal,oldval)
},
deep: true,
immediate: true
}
},
};
</script>
deep:trueを使用して詳細な観察を行い、objをリッスンし、objの下のレイヤーごとに属性をトラバースし、監視イベントを追加します。これにより、パフォーマンスのオーバーヘッドが増加します。objの属性値が変更されている限り、ハンドラーがトリガーされます。では、パフォーマンスを最適化する方法は?オブジェクト
を直接使用できます。プロパティメソッドを使用してプロパティを取得します
<template>
<div>
<el-input v-model="obj.text"></el-input>
</div>
</template>
<script>
export default {
data() {
return {
obj:{
text:'hello',
}
};
},
watch:{
// 监听对象单个属性text
'obj.text':{
handler (newVal,oldval) {
console.log(newVal,oldval)
},
immediate: true, // 该属性会先执行一次handler
}
},
};
</script>
予防:
- watchの関数名は、依存データの属性名である必要があります。
- 関数が依存する属性が変更されている限り、watch内の関数を呼び出す必要はなく、対応する関数が実行されます。
- watchの関数には、2つのパラメーターがあります。1つは新しい値で、もう1つは古い値です。
- デフォルトでは、watchはオブジェクトの変更を監視できません。監視する必要がある場合は、深く監視する必要があります。ハンドラー関数を構成し、deepをtrueに設定する必要があります。(オブジェクトのアドレスが変更されたかどうかのみを監視し、値は監視されないため)。
- デフォルトでは、watchは初めて監視しません。最初のロードを監視する必要がある場合は、immediate:true;を設定する必要があります。
- 特別な場合、watchは配列の変更を監視できません。
添え字を使用して配列内のデータを変更します。lengthを使用して配列の
長さを変更します。
解決策:
通过 Vue 实例方法 set 进行设置 $set( target, propertyName/index, value);
参数:target {
Object | Array} , propertyName/index {
string | number}, value {
any}
this.$set(this.arr,0,100);
通过 splice 来数组清空 $delete( target, propertyName/index )
参数:target {
Object | Array} , propertyName/index {
string | number}
this.$delete(this.arr,0)
- 詳細な監視に対応する関数名はハンドラーである必要があります。そうでない場合、ウォッチャーはハンドラーの呼び出しに対応するため、効果はありません。
アプリケーションシナリオ:
3.方法
メソッドは以前のものとは異なります。通常はここにメソッドを記述します。メソッドが呼び出される限り、再度実行されます。それに応じて、いくつかのトリガー条件があります。場合によっては、メソッドと計算の特定の違いができない場合があります。見られますが、計算量が増えると、より複雑なページは違いを反映します。
注:Computedはキャッシュされます。つまり、計算された属性の依存関係が対応するデータを更新しない限り、計算された値はキャッシュから直接取得され、複数回アクセスすると前の計算結果が返されます。
4.まとめ
計算と監視の観点から、1つは計算であり、もう1つは観測であり、意味的に異なります。
計算とは変数計算でデータを取得することであり、観察とは特定の値を観察し、観察者の変化に応じて対応する変更を加えることです。特定のシナリオでは混合できないため、注意が必要です。 apiの使用の合理性とセマンティクスに。