模板內的表達式很是便利,可是設計它們的初衷是用於簡單運算的。在模板中放入太多的邏輯會讓模板太重且難以維護。例如:html
<div id="example"> {{ message.split('').reverse().join('') }} </div>
在這個地方,模板再也不是簡單的聲明式邏輯。你必須看一段時間才能意識到,這裏是想要顯示變量 message 的翻轉字符串。當你想要在模板中屢次引用此處的翻轉字符串時,就會更加難以處理。vue
因此,對於任何複雜邏輯,你都應當使用計算屬性
簡單的理解爲:數組
1.計算屬性其實就是 Vue 實例的一個屬性
2.計算屬性通常依賴傳統的 Vue 實例屬性
3.計算屬性通常是經過運算獲得的屬性
緩存
簡單的寫法app
computed: { reversedMessage() { return this.message.split('').reverse().join('') } }
完整版寫法異步
computed: { reversedMessage: { get() { //獲取值 return this.message.split('').reverse().join('') }, set(val) { // set方法:設置值 this.message = val.split('').reverse().join('') } } }
HTMLide
<p>Reversed message: "{{ reversedMessage() }}"</p>
JS函數
// 在組件中 methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
計算屬性是基於它們的依賴進行緩存的,只有在它相關的依賴發生改變時纔會從新求值,即計算屬性會對計算出來的結果進行緩存,
這就意味着只要 message
尚未發生改變,屢次訪問 reversedMessage
計算屬性會當即返回以前的計算結果,而沒必要再次執行函數
性能
方法是每次從新渲染時,調用方法將總會再次執行函數,開銷比較大ui
咱們爲何須要緩存?
假設咱們有一個性能開銷比較大的計算屬性 A,它須要遍歷一個巨大的數組並作大量的計算。而後咱們可能有其餘的計算屬性依賴於 A 。若是沒有緩存,咱們將不可避免的屢次執行 A 的 getter!若是你不但願有緩存,請用方法來替代
watch
放在 data 中的對象,一旦發生改變就會執行相應的操做,當須要在數據變化時執行異步或開銷較大的操做時,這個方式是最有用的
<div> <p>FullName: {{fullName}}</p> <p>FirstName: <input type="text" v-model="firstName"></p> </div> new Vue({ el: '#root', data: { firstName: 'Joy', lastName: 'lqy', fullName: '' }, watch: { firstName(newName, oldName) { this.fullName = newName + ' ' + this.lastName; } } })
watch 中的對象在 data 中已經定義了,當咱們輸入firstName
後, watch
監聽每次修改變化的新值,而後計算輸出fullName
。也就是上面的代碼中,fullName
一開始被渲染出來的時候是空值,以下所示:
如上所述,一開始被渲染出來的時候,fullName是空值,若是想要一開始就讓最初綁定的值執行該怎麼辦尼?別急,咱們只須要給firstName
綁定一個handler方法,以前咱們寫的watch方法其實默認寫的就是這個handler,Vue.js會去處理這個邏輯,最終編譯出來其實就只這個handler,設置immediate:true表明若是在 wacth 裏聲明瞭 firstName
以後,就會當即先去執行裏面的handler
方法,若是爲 false就跟咱們之前的效果同樣,不會在綁定的時候就執行
修改後的代碼以下:
watch: { firstName: { handler(newName, oldName) { this.fullName = newName + ' ' + this.lastName; }, // 表明在wacth裏聲明瞭firstName這個方法以後當即先去執行handler方法 immediate: true } }
結果以下:
deep,默認值爲false,表明是否深度監聽,
總的來講,計算屬性傾向于格式化/處理當前的數據,而 watch 傾向於執行數據變化須要進行的操做
爲何要註銷 watch?
由於咱們的組件是常常要被銷燬的,好比咱們跳一個路由,從一個頁面跳到另一個頁面,那麼原來的頁面的 watch
其實就沒用了,這時候咱們應該註銷掉原來頁面的 watch 的,否則的話可能會致使內置溢出。好在咱們平時 watch
都是寫在組件的選項中的,他會隨着組件的銷燬而銷燬。
const app = new Vue({ template: '<div id="root">{{text}}</div>', data: { text: 0 }, watch: { text(newVal, oldVal){ console.log(`${newVal} : ${oldVal}`); } } });
可是,若是咱們使用下面這樣的方式寫 watch,那麼就要手動註銷了,這種註銷其實也很簡單
const unWatch = app.$watch('text', (newVal, oldVal) => { console.log(`${newVal} : ${oldVal}`); }) unWatch(); // 手動註銷watch
app.$watch
調用後會返回一個值,就是unWatch
方法,你要註銷 watch
只要調用unWatch方法就能夠了。