嗨啊!大家好!經過昨天耍了一天廢後,今天繼續闖蕩Vue世界吧!
孔子說「溫故而知新」所以在進入正文之前我們先簡單複習一下資料綁定,看能不能因此獲得新的知識XD
HTML
<div id="baseVue">
{{text}}
</div>
JavaScript
let textData = {
text:'Hello!World!'
}
let showText = new Vue({
el:'#baseVue',
data:textData
})
OK!不管有看前幾篇,或是沒看過的大大們,應該都知道textData.text
的資料會綁定到HTML
的{{text}}
上面,這叫做單向綁定,雙向綁定小弟在此就不說了,其實包著text
的兩個括號內,是可以寫下JavaScript
的表達式的,什麼是表達式呢?讓我們在不動到JavaScript
的狀態下看一下HTML
的改變:
<div id="baseVue">{{ '這是加在前面的文字' + text}}</div>
看(我不是在罵髒話XD)!畫面上除了原本繫結的Hello!World!外又多了前面加上去的字串,這時候你可能會想說,我是在裝笑維嗎?要這樣寫不如直接寫成這是加在前面的文字{{text}}
,還可以不用單引號和加號!沒錯!如果你心中有閃過一絲這樣子的想法就對了,不過這只是個小例子嘛!再給我一次機會吧!一樣在修改一下HTML
:
<div id="baseVue">
{{text.split('').reverse().join('')}}
</div>
貼心PS時間:
str.split(s)
:把字串str用s分隔成一個陣列,空字串就是每個字元都放一個位置。arr.reverse()
:把陣列中的內容反轉,[1,2,3]變[3,2,1]。arr.join(s)
:把陣列內的所有內容串成字串,每個索引間都穿插字元s,空字串就是不穿插。好的,結束PS時間,結果如下:
沒看錯!在Vue.js的{{}}
中可以使用任何函式,就算我把他切割成陣列,再反轉,再組合成字串,只要確定該行是一個表達式,那我保證Vue.js不會讓你失望。
好的,那就繼續...什麼?你說表達式到底是什麼?簡單來說,就是可以產生出一個值的句子,就叫做表達式,但是別想在{{}}
中宣告變數哦!那個就做敘述句而不是表達式。
那接下來我們就會想,可是如果把處理資料的邏輯寫在前面的繫結,這邊一塊那邊一塊,也太不方便了吧!而且如果以後要改一個地方,又要去找哪邊有這些表達式去一個一個改...所以!我們就有了一個救星!
這個計算屬性是繼el
、data
、methods
之後出現的第四個團員,官方直接翻譯他叫計算屬性,如果有需要像上面那樣把data
的資料放在畫面上的許多地方,又必須做一些處理後再綁定,那就可以直接把處理資料的邏輯寫在計算屬性中,例如我將上一個例子修改一下:
HTML
<div id="baseVue">
<!--這裡改成繫結computed內的屬性名稱-->
{{reText}}
</div>
JavaScript
let textData = {
text:'Hello!World!'
}
let showText = new Vue({
el:'#baseVue',
data:textData,
computed:{
//在computed中創建一個reText屬性來放剛剛的表達式
reText:function(){
/*這裡的this指向showText這個實體
可以從實體物件去取我們放在data中的資料
也可以直接透過textData去取值*/
return this.text.split('').reverse().join('')
}
}
})
我可沒有用同一張圖,是得出來的結果真的和上方一模一樣,所以把邏輯整理在computed
,HTML
就輕鬆的綁定資料,如果以後要改直接從computed
中去修改,而且上述例子的reText
因為有使用到textData
中text
的資料,所以當textData.text
的資料發生改變了,computed
就會重新計算新值並綁定到畫面上:
但是相反的,如果值沒有發生改變computed
是不會重新計算值綁定到畫面上的,他會把第一次的值存在緩存中,一直到資料改變了,才會重新計算並寫入新值到緩存裡,所以官方舉了下面的例子:
HTML
<div id="timeVue">
{{now}}
</div>
JavaScript
let timeVue = new Vue({
el:'#timeVue',
computed:{
now:() => Date()
}
})
他會讓剎那變永恆,因為沒有他並沒有使用到data
中的任何資料(當然上面的例子也沒有data
),所以沒有使用的data
發生改變,那computed
就不會重新計算新值!
這樣看起來computed
不只會讓HTML
更乾淨,還可以把整理好的邏輯整理在物件中,但是更想不到的是我們剛剛做的只是一半而已,上半段使用的名字是耳熟能詳的getter
;既然有getter
那絕對也少不了setter
!
等等,雖然功能是一樣的,但為什麼剛剛都沒去指定getter
屬性?好的,這個問題非常容易,因為getter
在computed
的屬性中是預設的!如果需要用到setter
的話就必須像下方的例子一樣,好好寫清楚才行!
HTML
<div id="nameVue">
{{name}}
</div>
JavaScript
let nameData = {
//這邊如果有打反了還請留言告訴我XD,我再修正
firstName : 'Tom',
lastName : 'Cruise',
}
//把計算屬性拆出來
let nameComputed = {
name:{
//取值,把姓氏和名字加起來回傳
get:() => nameData.firstName + ' ' + nameData.lastName,
//設值,這裡的val是指定給name的值
set:(val) => {
//把val用一個空格分割成陣列,因為姓和名中間通常有空白
let name = val.split(' ')
//給值,姓給firstName,名字給lastName
nameData.firstName = name[0]
nameData.lastName = name[1]
}
}
}
let nameVue = new Vue({
el:'#nameVue',
data:nameData,
computed:nameComputed,
})
getter
的結果:setter
的結果:
上面例子的nameComputed
是我把資料邏輯的物件拆出來,之後再指定給nameVue
的computed
屬性,可以看到和之前不一樣的是,我在name
裡面又放了兩個屬性「get
和set
」,分別區分取值的時候執行什麼,設值的時候又執行什麼,而set
的function
有一個參數,那裡是我們賦予他的新值,所以可以直接拿來處理寫入的部分!
小小題外話,不知道有沒有人注意到在最後一個例子的computed
中,我是直接對nameData
做操作和取值,並沒有使用this
,因為在JavaScript
的ES6
語法,箭頭函式是依照定義函式時的物件去指定this
,而不是使用時的物件,這點是我剛剛不小心踩到的雷點,想說怎麼值都跑不出來XD,和大家分享一下!
連存取器都可以用上,是不是覺得computed
是個好東西XD,就算我現在還沒在實務中使用到他,光想著就對他愛不釋手了!文章的最後還是感謝各位大大的觀看!如果內容有任何觀念錯誤或解釋不清楚的地方,再麻煩留言告訴我,我會盡快修正的!謝謝大家
挖!! computed
真不錯,像可快取的 method,在 ng1 通常會用函數處理,
感覺 Vue 很多特性都解決了 ng1 會碰到的問題,難怪大家會喜歡。
還以為 ES6 的 lambda 和一般函數一樣,原來有差異。
GitHub上Vue的星數也比NG2高
NG2上手難度有點高,變成只適合大型專案
還有那叫箭頭函式不叫lambda啊
NG2 會花很多時間在架構上,開發小專案不太適合。
哈哈哈,原來是這樣,C# 習慣看到箭頭函式就等於 Lambda,而 JS 一般的匿名函數就是 Lambda。
這章 講到了
分開資料跟處理過的資料
讓其更好管理
在computed裏頭
有預設的存取器
預設是get 只要取用就可以顯示
也就是不需要另外再寫get
接著講到set的概念
關於這個set 跟中間有張圖 也看了好久一直搞不懂
一直以為要name.set('Vim Diesel') 這樣設定
後來才理解
nameVue.name = 'Vim Diesel'
這個其實就是set的概念
把'Vim Diesel' 帶進val這個參數
去函數處理這個字串
藉由set修改nameData的資料
進而改變畫面的繪製
謝謝超人你第五天的教學
哈哈,謝謝你一直發漏我的學習歷程,也感受到你認真的態度!
雖然我已經不在 Vue 世界了,但還是很開心之前留下來的東西可以在陪著同時期的人一起成長:)