前言
Day02 主要複習計算屬性(computed
)、監聽器(watch
)和事件處理(methods
)。
對於他們的認識:methods
還好不難理解;計算屬性和監聽器我比較沒弄懂(゚д⊙)
今天將這三個擺在一起做個了結比較,觀察他們之間不同處,
搞懂每個的使用時機及用法。
計算屬性
computed
模板裡也可以寫JS的表達式,像是:
<div id="app">
{{ msg.split('').reverse().join('') }}
</div>
但表達式太長會讓人頭痛不好讀,未來也難維護。😥
這時候就可以用計算屬性-computed
了!
computed
屬性隨著來源data變化而更動。它可以讀取(getter
)和設值(setter
)
在預設情況下是只有getter
而已。
getter
用computed
試試看獲取名字
var vm = new Vue({
el: '#app',
data: {
firstName: 'chihuahua',
lastName: 'warrior',
},
computed: {
fullName(){
return `${this.firstName} ${this.lastName}`
}
}
})
<div id="app">
{{ fullName }}
</div>
💡 computed預設是用getter,所以可省略getter不寫。
⚠️ 如果在模板中未使用{{fullName}},如有更動firstName或lastName的值computed雖然會更新但不會呈現結果!
setter
把上面的例子再修改一下,setter
到底是什麼呢?
<div id="app">
firstName <input type="text" v-model="firstName">
<p/> lastName <input type="text" v-model="lastName">
<p/> fullName <input type="text" v-model="fullName">
</div>
computed: {
fullName: {
// getter
get() {
console.log('getter')
return `${this.firstName} ${this.lastName}`
},
// setter
set(newVal) {
console.log('setter', newVal)
}
}
}
▲ 修改firstName或lastName的值,會觸發getter
,進而更改fullName;
直接更動fullName,會觸發setter
,使得firstName或lastName的值也會跟著變化!
💡 我覺得可以這樣理解:
getter
:獲取值(且會緩存),computed的值是怎麼來的。setter
:設置值,給computed賦值,參數就是接收的值。
監聽器
watch
剛學的時候,覺得computed
就做得到的工作,為何還需要watch
?
而且看起來沒什麼差別啊,有種既生瑜何生亮的概念
等學到比較多東西之後回頭看,才發現自己錯得超大啊QQ!!
watch
:是一個物件,其屬性是需要觀察的表達式,值是對應回調函數。
值也可以是方法名或者包含選項的物件。
當資料發生變化時,執行非同步或開銷較大的動作時會執行的函數。
把上面computed
的例子改寫成watch
看看
watch: {
firstName(val) {
this.fullName = `val ${this.lastName}`
},
lastName(val) {
this.fullName = `${this.firstName} val`
}
我要一個fullName需要把firstName和lastName的值都做觀察,
如果今天資料很大我會眼睛痛rrrrrr!
這時用computed
可以比較快完成和易讀。
非同步用watch
可以參考官方的例子。
才不是因為太懶有現成的才不寫例子(◔౪◔)
$watch
剛走一個watch
,又來一個$watch
!這兩個又有什麼差別?
Vue實例將會在實例化時調用$watch()
,遍歷watch
物件的每一個屬性。
▲ 翻譯翻譯,什麼是$watch啊!! 圖源網易
$watch
是註冊監聽器的函數
watch
是為了開發者方便在實體上設置監聽器而提供的
其實watch
本身也是使用$watch
註冊監聽器。
📢 上文引用自Peter Chen大大的勇者鬥Vue龍
我覺得這個說法很容易理解watch
和$watch
的關係!
詳細用法像是deep
、immediate
可以看官方的API文件。
事件處理
監聽事件
可以用v-on
指令監聽DOM事件,在觸發時運行JavaScript程式。
<div id="app">
<span>覺得吉娃娃可愛的人有 {{ count }} 人</span>
<button @click="count += 1"> +1 </button>
</div>
var vm = new Vue({
el: '#app',
data: {
count: 999,
},
})
▲ 按下之後執行count+=1
事件方法
如果程式碼太長太複雜,都寫在v-on
裡是不可行的!
所以就有了methods
幫助我們解決這個問題。
把上面的東西修改一些,再包到methods裡面:
⚠️ methods中多個function都要用逗點(,)隔開,不然會報錯喔!
<button @click="sub" class="btn btn-danger"> -1 </button>
<span>覺得吉娃娃可愛的人有 {{ count }} 人</span>
<button @click="add" class="btn btn-info"> +1 </button>
data: {
count: 0,
},
methods: {
sub(){
// 如果小於0就return,為了讓人數不為負
if (this.count <= 0) return;
this.count--;
},
add(){
this.count++;
}
}
▲ 出來的結果是這樣子~樣式部分用bootstrap快速又美觀(?) 可惜不能用Vuetify
🤔 如果不是要傳參數進去,在v-on調用方法的地方加括號會怎麼樣呢?
<button @click="question"> question </button>
<button @click="question()"> question() </button>
methods: {
question() {
console.log(this, arguments);
}
}
所有在methods
屬性中的函數,無論如何調用,this
都指向當前Vue實例化。
要在事件響應函數中獲得event
,那麼事件綁定時不能加括號。
當然也可以使用Vue的$event
來顯示的傳遞event
,以保證function寫在任何位置都可以正常使用this
和event
。
有點重要的補充⭐⭐⭐
computed
vs. watch
vs. methods
作用
computed
和watch
:都是當某一個依賴資料發生變化時,自動調用相關函數去實現資料的變動。methods
:methods
是用來定義函數的,它需要調用才能執行。
區分
computed
:一個資料受多個資料影響。
(例如上面例子fullName是由firstName和lastName組成)watch
:一個資料影響多個資料。methods
:不處理資料邏輯關係,只提供可調用的函數。
💣地雷誤區要小心💣
一開始也因為有些觀念不太清楚而踩雷。
找了很多資料複習,發現很多是原生JS的觀念!
尤其是ES6,雖然讓撰寫起來超~方~便~但有些地方真的...⚡⚡
深感學一個框架最重要的是基本底子要好,學Vue的話必備ES6知識。
地基都打不穩了蓋什麼房子不倒才怪484
缺 "this
" 不可
看到上面事件方法中的例子,如果我們在sub / add函數中直接寫 count-- / count++,
不加this
的結果會發生什麼事呢?
▲ 奇怪ㄟ怎麼不會動! :(
為什麼會這樣?如果不懂this
一定要先搞懂!
📢 讀this必看this!閱讀Kuro大大的 What is This in JavaScript
搞懂this了嗎?再來看為什麼會這樣呢~
Vue的實例創建時是new出來的,所以this指向這個Vue實例。
要使用Vue裡data的資料就是用this.count囉!
箭頭函數的地雷
ES6推出的箭頭函數可以把function簡化不少,但是在Vue要小心使用。
來試試寫一個按鈕,按了會console出現Hello 參數
的函式:
<button @click="greeting('hello!')"> say HI! </button>
原本一般的function是這樣的
methods: {
greeting: function(msg){
console.log(`Hello ${this.msg}`)
}
}
用箭頭函數把他簡化成醬子
methods: {
greeting(msg) => {
console.log(`Hello ${this.msg}`)
}
}
▲ 為什麼是Hello undefined?
嗯?不在實例中,那麼這個this.msg
到底跑哪去了?
我們在Vue的外部(也就是var vm = new Vue({ ... })
外面)定義宣告msg:
var msg = "out side msg"
由此可知,在Vue中使用箭頭函數是不可靠的:(
💡 箭頭函數它沒有自己的 this,它綁定到其定義時所在的物件,而不是使用時所在的物件。
所以this不會指向Vue實例。
小小心得
若觀念或內容有誤請不吝指教,謝謝您( ᐛ)パァ
今天複習了我區分不太出來的computed和watch,
發現了以前真的很混啊啊啊啊都沒認真(๑•́ ₃ •̀๑)
現在才發現這些其實不難,用心整理、實際體會過一次就知道了。
還剩5天,加油!(๑•̀ㅂ•́)و✧