使用computed_《computed 與 watch的區別》
技術標籤:使用computed
computed
computed
是計算屬性的
它會根據所依賴的資料動態顯示新的計算結果,計算的結果會被快取起來
computed
的值在getter
執行後是會被快取的。如果所依賴的資料發生改變時候,就會重新呼叫getter
來計算最新的結果。
根據Vue文件例子來理解computed
的使用
computed
設計的初衷是為了使模板中的邏輯運算更簡單
<body> <div id="app"> {{ msg.split('').reverse().join('') }} </div> <script type="text/javascript"> new Vue({ el: '#app', data: { msg: 'hello' } }); </script> </body>
我們在vue模板中會對該資料值進行反轉操作後輸出資料, 因此在頁面上就會顯示 'olleh'
如果頁面中的運算比這個還更復雜的話, 這個時候我們可以使用computed來進行計算屬性值。把上面的程式碼改寫成下面如下程式碼:
<body> <div id="app"> <p>原來的資料: {{ msg }}</p> <p>反轉後的資料為: {{ reversedMsg }}</p> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { msg: 'hello' }, computed: { reversedMsg() { // this 指向 vm 例項 return this.msg.split('').reverse().join('') } } }); </script> </body>
如上程式碼, 我們在computed
中聲明瞭一個計算屬性reversedMsg
。我們提供的reversedMsg
函式, 將用作屬性 vm.reversedMsg
的getter
函式
我們也可以開啟控制檯, 當我們修改 vm.msg 的值後, vm.reversedMsg 的值也會發生改變,如下控制檯列印的資訊可知:
我們的vm.reversedMsg
的值依賴於vm.msg
的值,當vm.msg
的值發生改變時, vm.reversedMsg
的值也會得到更新
computed應用場景
1. 適用於一些重複使用資料或複雜及費時的運算。我們可以把它放入computed
computed
中快取起來, 下次就可以直接獲取了。
2. 如果我們需要的資料依賴於其他的資料的話, 我們可以把該資料設計為computed
中。
watch的用法
watch
用於偵聽data
的資料。
當data
資料發生變化,執行函式。在函式中會傳入newVal
和oldVal
兩個引數
watch
屬性可以是字串、函式、物件、陣列
擁有deep,immediate兩屬性
示例
new Vue({
data: {
n: 0,
obj: {
a: "a"
}
},
template: `
<div>
<button @click="n += 1">n+1</button>
<button @click="obj.a += 'hi'">obj.a + 'hi'</button>
<button @click="obj = {a:'a'}">obj = 新物件</button>
</div>
`,
watch: {
n() {
console.log("n 變了");
},
obj() {
console.log("obj 變了");
},
"obj.a": function() {
console.log("obj.a 變了");
}
}
}).$mount("#app");
點選n+1
: 打印出“n 變了”
點選obj.a + 'hi'
: 打印出“obj.a 變了”
,不列印"obj 變了"
不點選obj.a + 'hi'
, 點選obj = 新物件
: 打印出"obj 變了"
,不列印"obj 變了"
說明watch的監聽方式是:簡單資料型別看值,複雜資料型別(物件)看地址
那我想通過監聽obj
也能obj.a
變化可以嗎?
答:請使用deep
使用deep
屬性
watch: {
n() {
console.log("n 變了")
},
obj() {
console.log("obj 變了")
deep: ture // 可以監聽到obj物件的所有內部屬性
},
"obj.a": function() {
console.log("obj.a 變了")
}
}
點選obj.a + 'hi'
: 打印出“obj.a 變了”
和 "obj 變了"
當deep:true 會監聽到obj物件的所有內部屬性,預設值為false
immediate屬性
new Vue({
data: {
firstName: 'Jacky',
lastName: 'Lee',
fullName: ''
},
watch: {
firstName: {
handler: 'change'
}
},
template: `
<div>
{{fullName}}
<button @click="firstName='John'">改名字</button>
</div>
`,
methods: {
change() {
this.fullName = this.firstName + ' ' + this.lastName
}
}
}).$mount("#app");
執行上面程式碼,頁面啥也沒有,然後點選“改名字”,頁面顯示 John Lee
這因為watch不會監聽第一次變化
改造一下
watch: {
firstName: {
handler: 'change',
immediate: ture
}
}
當 immediate:true 時,回撥函式會在監聽開始後立刻執行,可以監聽到到第一次變化。
總結:
- computed是用來計算一個值的,使用時不需要加括號,可以直接當屬性使用。computed擁有依賴快取特性,如果依賴值不變,computed不會重新計算
- watch是用來監聽的,有兩個選項,immediate 和 deep,當immediate: true時,表示會在第一次執行是執行這個函式,當 deep:true時,如果監聽一個物件,會同時監聽其內部屬性。watch沒有依賴快取特性。