Vue 中合理應用計算屬性computed和偵聽器watch;
什麼是計算屬性:
計算屬性可以理解為:可以用來寫一些邏輯的屬性;
複製程式碼
作用:
1.通常用來減少模板中計算邏輯;
2.幫助我們做一些資料的快取;當我們的依賴資料沒有變化的時候,不會執行邏輯程式碼;當邏輯計算的比較複雜的時候,可以幫助我們提供效能;因為它只會在依賴資料變化的時候才會計算;
3.依賴固定的資料型別(響應式資料型別)
複製程式碼
引用唐老師的示例程式碼: 通過斷點程式碼,理解計算屬性computed:
在以下computed.vue 中;在data中初始化message;通過點選button,執行this.$forceUpdate(),強制重新整理;我們可以發現:
在計算屬性reversedMessage1中邏輯程式碼的log;並咩有更新;reversedMessage2 中邏輯程式碼的log 一直有列印;這就是通過computed 屬性的優點;
<template>
<div>
<p>Reversed message1: "{{ reversedMessage1 }}"</p>
<p>Reversed message2: "{{ reversedMessage2() }}"</p>
<p>{{ now }}</p>
<button @click="() => $forceUpdate()">forceUpdate</button>
<br />
<input v-model="message" />
</div>
</template>
<script>
export default {
data() {
return {
message: "hello vue"
};
},
computed: {
// 計算屬性的 getter
reversedMessage1: function() {
console.log("執行reversedMessage1");
return this.message
.split("")
.reverse()
.join("");
},
now: function() {
return Date.now();
}
},
methods: {
reversedMessage2: function() {
console.log("執行reversedMessage2");
return this.message
.split("")
.reverse()
.join("");
}
}
};
</script>
複製程式碼
什麼是偵聽器watch:
**偵聽器**:可以去監聽任何資料;當資料變化的時候,去執行一些邏輯程式碼;
在watch中可以執行任何程式碼邏輯,如函式節流、ajax非同步獲取資料;甚至操作Dom;
複製程式碼
偵聽器的作用:更加靈活,通用;
引用唐老師的程式碼示例: 通過程式碼理解偵聽器:
在watch.vue程式碼示例中,
-
在{{}}模板中通過$data 引用data中的所有資料;
-
通過button 來改變a的值;
-
在watch中,通過監聽多層巢狀資料,當a發生變化的時候,執行對應邏輯程式碼;
-
在e 中,執行深度監聽,deep:true;當e:中的任何資料發生改變的時候,不論是f 還是g 發生改變,都將執行e的handler 函式;
{{ $data }}
計算屬性computed VS 偵聽器watch;
計算屬性computed 能夠做的,watch 都可以做,反之不行; 能用computed做的事情,儘量使用computed;
通過程式碼理解兩者:
computedFullName.vue中;通過計算屬性fullName;只需要一段邏輯程式碼,便可以完成Fullname的監聽;
<template>
<div>
{{ fullName }}
<div>firstName: <input v-model="firstName" /></div>
<div>lastName: <input v-model="lastName" /></div>
</div>
</template>
<script>
export default {
data: function() {
return {
firstName: "Foo",
lastName: "Bar"
};
},
computed: {
fullName: function() {
return this.firstName + " " + this.lastName;
}
},
watch: {
fullName: function(val, oldVal) {
console.log("new: %s, old: %s", val, oldVal);
}
}
};
</script>
複製程式碼
watchFullName.vue 中;顯示fullName的改變需要;同時監聽firstName 和lastName;分別執行兩段邏輯程式碼;
<template>
<div>
{{ fullName }}
<div>firstName: <input v-model="firstName" /></div>
<div>lastName: <input v-model="lastName" /></div>
</div>
</template>
<script>
export default {
data: function() {
return {
firstName: "Foo",
lastName: "Bar",
fullName: "Foo Bar"
};
},
watch: {
firstName: function(val) {
this.fullName = val + " " + this.lastName;
},
lastName: function(val) {
this.fullName = this.firstName + " " + val;
}
}
};
</script>
複製程式碼
在這種情況下,程式碼量上來講,通過computed 計算屬性更加簡潔;computed 可以做的通過watch屬性也可以進行實現;
**擴充套件:**對以上watchFullName.vue 進行防抖改造,當使用者輸入超過500毫秒後,才進行更新fullname;
**分析:**通過程式碼分析可以看出,防抖策略:
就是通過 clearTimeout(timer);let timer=setTimeout(()=>{}); 當使用者一直輸入新的資料的時候,清除當前定時器,如果500ms內,監聽的依賴資料沒有新的資料更新, 在執行setTimeout(()=>{})的回撥函式;
<template>
<div>
{{ fullName }}
<div>firstName: <input v-model="firstName" /></div>
<div>lastName: <input v-model="lastName" /></div>
</div>
</template>
<script>
export default {
data: function() {
return {
firstName: "Foo",
lastName: "Bar",
fullName: "Foo Bar"
};
},
watch: {
firstName: function(val) {
clearTimeout(this.firstTimeout);
this.firstTimeout = setTimeout(() => {
this.fullName = val + " " + this.lastName;
}, 500);
},
lastName: function(val) {
clearTimeout(this.lastTimeout);
this.lastTimeout = setTimeout(() => {
this.fullName = this.firstName + " " + val;
}, 500);
}
}
};
</script>
複製程式碼