
*****
## 計算屬性和監聽器
一般情況下屬性都是放到`data`中的,但是有些屬性可能是需要經過一些邏輯計算后才能得出來,那么我們可以把這類屬性變成計算屬性。比如以下:
~~~
<div id="app">
<label for="length">長:</label>
<input type="number" name="length" v-model:value="length">
<label for="width">寬:</label>
<input type="number" name="width" v-model:value="width">
<label for="area">面積:</label>
<input type="number" name="area" v-bind:value="area" readonly>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
length: 0,
width: 0,
},
computed: {
area: function(){
return this.length*this.width;
}
}
});
</script>
~~~
可能有的小伙伴會覺得這個計算屬性跟我們之前學過的函數好像有點重復。實際上,計算屬性更加智能,他是基于它們的響應式依賴進行緩存的。也就是說只要相關依賴(比如以上例子中的`area`)沒有發生改變,那么這個計算屬性的函數不會重新執行,而是直接返回之前的值。這個緩存功能讓計算屬性訪問更加高效。
## 計算屬性的`set`:
計算屬性默認只有`get`,不過在需要時你也可以提供一個`set`,但是提供了`set`就必須要提供`get`方法。示例代碼如下:
~~~
<div id="app">
<div>
<label>省:</label>
<input type="text" name="province" v-model:value="province">
</div>
<div>
<label>市:</label>
<input type="text" name="city" v-model:value="city">
</div>
<div>
<label>區:</label>
<input type="text" name="district" v-model:value="district">
</div>
<div>
<label>詳細地址:</label>
<input type="text" name="address" v-model:value="address">
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
district: "",
city: "",
province: ""
},
computed: {
address: {
get: function(){
let result = "";
if(this.province){
result = this.province + "省";
}
if(this.city){
result += this.city + "市";
}
if(this.district){
result += this.district + "區";
}
return result;
},
set: function(newValue){
let result = newValue.split(/省|市|區/)
if(result && result.length > 0){
this.province = result[0];
}
if (result && result.length > 1){
this.city = result[1];
}
if(result && result.length > 2){
this.district = result[2];
}
}
}
}
});
</script>
~~~
## 監聽屬性:
監聽屬性可以針對某個屬性進行監聽,只要這個屬性的值發生改變了,那么就會執行相應的函數。示例代碼如下:
~~~
<div id="app">
<div>
<label>搜索:</label>
<input type="text" name="keyword" v-model:value="keyword">
</div>
<div>
<p>結果:</p>
<p>{{answer}}</p>
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
keyword: "",
answer: ""
},
watch: {
keyword: function(newKeyword,oldKeyword){
this.answer = '加載中...';
let that = this;
setTimeout(function(){
that.answer = that.keyword;
},Math.random()*5*1000);
}
}
});
</script>
~~~