一.計算屬性和偵聽器
模板表達式提供給我們處理簡單的邏輯,對於更復雜的邏輯,我們應該使用計算屬性。來看兩個示例的對比:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- 引入vue.js開發版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>mustache</title>
</head>
<body>
<div id="app">
<span>{{ message.split('').reverse().join('') }}</span>
</div>
<script>
//這裏寫JavaScript代碼
</script>
</body>
</html>
js代碼:
var obj = {
message:"hello,vue.js!"
}
var vm = new Vue({
data:obj
})
vm.$mount(document.querySelector('#app'))
第二個示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- 引入vue.js開發版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>mustache</title>
</head>
<body>
<div id="app">
<span>{{ reverseMessage }}</span>
</div>
<script>
//這裏寫JavaScript代碼
</script>
</body>
</html>
js代碼:
var obj = {
message:"hello,vue.js!"
}
var vm = new Vue({
data:obj,
computed:{
reverseMessage:function(){
return this.message.split('').reverse().join('');
}
}
})
vm.$mount(document.querySelector('#app'))
與第一個示例有所不同的就是在這個示例當中,我們申明瞭一個計算屬性reverseMessage
,並且提供了一個getter
函數將這個計算屬性同數據屬性message
綁定在一起,也許有人會有疑問getter
函數到底在哪裏呢?
如果我們將以上示例修改一下:
var obj = {
message:"hello,vue.js!"
}
var vm = new Vue({
data:obj,
computed:{
reverseMessage:{
get:function(){
return this.message.split('').reverse().join('');
}
}
}
})
vm.$mount(document.querySelector('#app'))
相信如此一來,就能明白了。你可以狠狠點擊此處具體示例。你可以通過控制檯修改message
的值,只要message
的值發生改變,那麼綁定的計算屬性就會發生改變。事實上,在使用reverseMessage
綁定的時候,我們還可以寫成調用方法一樣的方式,如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- 引入vue.js開發版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>mustache</title>
</head>
<body>
<div id="app">
<span>{{ reverseMessage() }}</span>
</div>
<script>
//這裏寫JavaScript代碼
</script>
</body>
</html>
js代碼:
var obj = {
message:"hello,vue.js!"
}
var vm = new Vue({
data:obj,
computed:{
reverseMessage:function(){
return this.message.split('').reverse().join('');
}
}
})
vm.$mount(document.querySelector('#app'))
那麼這兩者有何區別呢?雖然兩者的結果都一樣,但計算屬性是根據依賴進行緩存的,只有相關依賴發生改變時它們纔會重新求值。比如這裏計算屬性綁定的依賴就是message
屬性,一旦message
屬性發生改變時,那麼計算屬性就會重新求值,如果沒有改變,那麼計算屬性將會緩存上一次的求值。這也意味着,如果計算屬性綁定的是方法,那麼計算屬性不是響應式的。如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- 引入vue.js開發版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>mustache</title>
</head>
<body>
<div id="app">
<span>{{ date }}</span>
</div>
<script>
//這裏寫JavaScript代碼
</script>
</body>
</html>
js代碼:
var vm = new Vue({
data:obj,
computed:{
reverseMessage:function(){
return Date.now();
}
}
})
vm.$mount(document.querySelector('#app'))
與調用方法相比,調用方法總會在頁面重新渲染之後再次調用方法。我們爲什麼需要緩存,假設你要計算一個性能開銷比較大的數組,而且如果其它頁面也會依賴於這個計算屬性,如果沒有緩存,那麼無論是讀取還是修改都會去多次修改它的getter
函數,這並不是我們想要的。