做(zuò)自(zì)由與創造的先行(xíng)者

計算屬性

Vue.js中文手冊

基礎示例

模闆中的表達式雖然方便,但(dàn)也隻能(néng)用來做(zuò)簡單的操作(zuò)。如(rú)果在模闆中寫太多邏輯,會讓模闆變得臃腫,難以維護。比如(rú)說,我們有這(zhè)樣一(yī)個包含嵌套數(shù)組的對象: js export default { data() { return { author: { name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery' ] } } } } 我們想根據 author 是否已有一(yī)些書(shū)籍來展示不同的信息: template <p>Has published books:</p> <span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span> 這(zhè)裏的模闆看(kàn)起來有些複雜(zá)。我們必須認真看(kàn)好一(yī)會兒才能(néng)明(míng)白它的計算依賴于 author.books。更重要(yào)的是,如(rú)果在模闆中需要(yào)不止一(yī)次這(zhè)樣的計算,我們可(kě)不想将這(zhè)樣的代碼在模闆裏重複好多遍。 因此我們推薦使用計算屬性來描述依賴響應式狀态的複雜(zá)邏輯。這(zhè)是重構後的示例: js export default { data() { return { author: { name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery' ] } } }, computed: { // 一(yī)個計算屬性的 getter publishedBooksMessage() { // `this` 指向當前組件實例 return this.author.books.length > 0 ? 'Yes' : 'No' } } } template <p>Has published books:</p> <span>{{ publishedBooksMessage }}</span> 我們在這(zhè)裏定義了(le)一(yī)個計算屬性 publishedBooksMessage。 更改此應用的 data 中 books 數(shù)組的值後,可(kě)以看(kàn)到 publishedBooksMessage 也會随之改變。 在模闆中使用計算屬性的方式和(hé)一(yī)般的屬性并無二緻。Vue 會檢測到 this.publishedBooksMessage 依賴于 this.author.books,所以當 this.author.books 改變時(shí),任何依賴于 this.publishedBooksMessage 的綁定都(dōu)将同時(shí)更新。 計算屬性緩存 vs 方法

你可(kě)能(néng)注意到我們在表達式中像這(zhè)樣調用一(yī)個函數(shù)也會獲得和(hé)計算屬性相同的結果: template <p>{{ calculateBooksMessage() }}</p> js // 組件中 methods: { calculateBooksMessage() { return this.author.books.length > 0 ? 'Yes' : 'No' } } 若我們将同樣的函數(shù)定義為(wèi)一(yī)個方法而不是計算屬性,兩種方式在結果上(shàng)确實是完全相同的,然而,不同之處在于計算屬性值會基于其響應式依賴被緩存。一(yī)個計算屬性僅會在其響應式依賴更新時(shí)才重新計算。這(zhè)意味着隻要(yào) author.books 不改變,無論多少(shǎo)次訪問(wèn) publishedBooksMessage 都(dōu)會立即返回先前的計算結果,而不用重複執行(xíng) getter 函數(shù)。 這(zhè)也解釋了(le)為(wèi)什麽下(xià)面的計算屬性永遠不會更新,因為(wèi) Date.now() 并不是一(yī)個響應式依賴: js computed: { now() { return Date.now() } } 相比之下(xià),方法調用總是會在重渲染發生時(shí)再次執行(xíng)函數(shù)。 為(wèi)什麽需要(yào)緩存呢?想象一(yī)下(xià)我們有一(yī)個非常耗性能(néng)的計算屬性 list,需要(yào)循環一(yī)個巨大的數(shù)組并做(zuò)許多計算邏輯,并且可(kě)能(néng)也有其他(tā)計算屬性依賴于 list。沒有緩存的話,我們會重複執行(xíng)非常多次 list 的 getter,然而這(zhè)實際上(shàng)沒有必要(yào)!如(rú)果你确定不需要(yào)緩存,那(nà)麽也可(kě)以使用方法調用。 可(kě)寫計算屬性

計算屬性默認是隻讀的。當你嘗試修改一(yī)個計算屬性時(shí),你會收到一(yī)個運行(xíng)時(shí)警告。隻在某些特殊場景中你可(kě)能(néng)才需要(yào)用到“可(kě)寫”的屬性,你可(kě)以通(tōng)過同時(shí)提供 getter 和(hé) setter 來創建: js export default { data() { return { firstName: 'John', lastName: 'Doe' } }, computed: { fullName: { // getter get() { return this.firstName + ' ' + this.lastName }, // setter set(newValue) { // 注意:我們這(zhè)裏使用的是解構賦值語法 [this.firstName, this.lastName] = newValue.split(' ') } } } } 現在當你再運行(xíng) this.fullName = 'John Doe' 時(shí),setter 會被調用而 this.firstName 和(hé) this.lastName 會随之更新。 最佳實踐

Getter 不應有副作(zuò)用

計算屬性的 getter 應隻做(zuò)計算而沒有任何其他(tā)的副作(zuò)用,這(zhè)一(yī)點非常重要(yào),請(qǐng)務必牢記。舉例來說,不要(yào)在 getter 中做(zuò)異步請(qǐng)求或者更改 DOM!一(yī)個計算屬性的聲明(míng)中描述的是如(rú)何根據其他(tā)值派生一(yī)個值。因此 getter 的職責應該僅為(wèi)計算和(hé)返回該值。在之後的指引中我們會讨論如(rú)何使用監聽器根據其他(tā)響應式狀态的變更來創建副作(zuò)用。 避免直接修改計算屬性值

從(cóng)計算屬性返回的值是派生狀态。可(kě)以把它看(kàn)作(zuò)是一(yī)個“臨時(shí)快(kuài)照”,每當源狀态發生變化時(shí),就會創建一(yī)個新的快(kuài)照。更改快(kuài)照是沒有意義的,因此計算屬性的返回值應該被視(shì)為(wèi)隻讀的,并且永遠不應該被更改——應該更新它所依賴的源狀态以觸發新的計算。

網站建設開(kāi)發|APP設計開(kāi)發|小程序建設開(kāi)發
下(xià)一(yī)篇:Class 與 Style 綁定
上(shàng)一(yī)篇:響應式基礎