推薦:Vue彙總
Vue - 偵聽器 watch 和計算屬性 computed
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>computed</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
{{firstName + " " + lastName}}
</div>
</body>
</html>
<script>
var vue = new Vue({
el: '#div',
data: {
firstName: 'Li',
lastName: 'Kaven'
}
})
</script>
效果:
模闆内的表達式非常便利,但是設計它們的初衷是用于簡單運算的。在模闆中放入太多的邏輯會讓模闆過重且難以維護。
使用
methods
自定義方法進行改造:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>computed</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
{{fullName()}}
</div>
</body>
</html>
<script>
var vue = new Vue({
el: '#div',
data: {
firstName: 'Li',
lastName: 'Kaven'
},
methods:{
fullName(){
return this.firstName + " " + this.lastName;
}
}
})
</script>
效果:
但這個還是不夠完美,每次渲染頁面時,這個方法都會被調用一次,這樣會造成性能的損失。
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>computed</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
{{fullName()}}
{{count}}
</div>
</body>
</html>
<script>
var vue = new Vue({
el: '#div',
data: {
firstName: 'Li',
lastName: 'Kaven',
count: 1
},
methods:{
fullName(){
console.log('重新計算');
return this.firstName + " " + this.lastName;
}
}
})
</script>
效果:
改變
count
時,
fullName()
也會被調用一次。
Vue提供了一種通用的方式來觀察和響應Vue執行個體上的資料變動:偵聽屬性。當你有一些資料需要随着其它資料變動而變動時,可以使用
watch
。
使用
watch
進行改造:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>computed</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
{{fullName}}
{{count}}
</div>
</body>
</html>
<script>
var vue = new Vue({
el: '#div',
data: {
firstName: 'Li',
lastName: 'Kaven',
fullName: 'Li Kaven',
count: 1
},
watch:{
firstName: function (val) {
console.log('重新計算');
this.fullName = val + " " + this.lastName;
},
lastName: function (val) {
console.log('重新計算');
this.fullName = this.firstName + " " + val;
}
}
})
</script>
效果:
但現在還不夠完美,這樣偵聽屬性太麻煩了,如果屬性比較多,就會很繁瑣。
接下來就使用計算屬性
computed
來進行改造:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>computed</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
{{fullName}}
{{count}}
</div>
</body>
</html>
<script>
var vue = new Vue({
el: '#div',
data: {
firstName: 'Li',
lastName: 'Kaven',
count: 1
},
computed: {
fullName: function () {
console.log('重新計算');
return this.firstName + " " +this.lastName;
}
}
})
</script>
效果:
這裡我們聲明了一個計算屬性
fullName
。我們提供的函數将用作
property vue.fullName
的
getter
函數。
你可以打開浏覽器的控制台,自行修改例子中的
vue
。
vue.fullName
的值始終取決于
vue.firstName
和
vue.lastName
的值。
你可以像綁定普通
property
一樣在模闆中綁定計算屬性。Vue知道
vue.fullName
依賴于
vue.firstName
和
vue.lastName
,是以當
vue.firstName
或
vue.lastName
發生改變時,所有依賴
vue.fullName
的綁定也會更新。而且最妙的是我們已經以聲明的方式建立了這種依賴關系:計算屬性的
getter
函數是沒有副作用的,這使它更易于測試和了解。計算屬性是基于它們的響應式依賴進行緩存的。隻在相關響應式依賴發生改變時它們才會重新求值
我們為什麼需要緩存?假設我們有一個性能開銷比較大的計算屬性 A,它需要周遊一個巨大的數組并做大量的計算。然後我們可能有其他的計算屬性依賴于 A。如果沒有緩存,我們将不可避免的多次執行 A 的
getter
!如果你不希望有緩存,請用方法來替代。
當你有一些資料需要随着其它資料變動而變動時,你很容易濫用
watch
。然而,通常更好的做法是使用計算屬性而不是指令式的
watch
回調。
如果隻是偵聽屬性就可以使用
watch
。
計算屬性的 setter
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>computed</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
{{fullName}}
{{count}}
</div>
</body>
</html>
<script>
var vue = new Vue({
el: '#div',
data: {
firstName: 'Li',
lastName: 'Kaven',
count: 1
},
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
})
</script>
效果:
vue.fullName
改變了,
vue.lastName
也相應跟着變了(
vue.firstName
也是一樣)。