做者:Michael Thiessen
譯者:前端小智
來源:hackernoon
點贊再看,養成習慣本文
GitHub
https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。前端
有時候,依賴 Vue 響應方式來更新數據是不夠的,相反,咱們須要手動從新渲染組件來更新數據。或者,咱們可能只想拋開當前的DOM,從新開始。那麼,如何讓Vue以正確的方式從新呈現組件呢?vue
強制 Vue 從新渲染組件的最佳方法是在組件上設置:key
。 當咱們須要從新渲染組件時,只需更 key
的值,Vue 就會從新渲染組件。git
這是一個很是簡單的解決方案。github
固然,你可能會對其餘方式會更感興趣:面試
v-if
forceUpdate
方法key
更改這至關於每次你想關閉應用程序時都要從新啓動你的電腦。segmentfault
這種方式或許有用,但這是一個很是糟糕的解決方案,不要這樣作,咱們來看看更好的方法。api
v-if
v-if
指令,該指令僅在組件爲true
時才渲染。 若是爲false
,則該組件在DOM中不存在。數組
來看看,v-if
是怎麼工做的,在template
中,添加v-if
指令:promise
<template> <my-component v-if="renderComponent" /> </template>
在script
中,使用nextTick
的方法工具
<script> export default { data() { return { renderComponent: true, }; }, methods: { forceRerender() { // 從 DOM 中刪除 my-component 組件 this.renderComponent = false; this.$nextTick(() => { // 在 DOM 中添加 my-component 組件 this.renderComponent = true; }); } } }; </script>
上面的過程大體以下:
renderComponent
設置爲true
,所以渲染 my-component
組件forceRerender
時,咱們當即將renderComponent
設置爲false
my-component
,由於v-if
指令如今計算結果爲false
nextTick
方法中將renderComponent
設置回true
v-if
指令的計算結果爲true
時,再次渲染my-component
在這個過程當中,有兩個部分比較重要
首先,咱們必須等到nextTick
,不然咱們不會看到任何變化。
在Vue中,一個 tick 是一個DOM更新週期。Vue將收集在同一 tick 中進行的全部更新,在 tick 結束時,它將根據這些更新來渲染 DOM 中的內容。若是咱們不等到next tick,咱們對renderComponent
的更新就會自動取消,什麼也不會改變。
其次,當咱們第二次渲染時,Vue將建立一個全新的組件。 Vue 將銷燬第一個,並建立一個新的,這意味着咱們的新my-component
將像正常狀況同樣經歷其全部生命週期-created
,mounted
等。
另外,nextTick
能夠與 promise 一塊兒使用:
forceRerender() { // 從 DOM 中刪除 my-component 組件 this.renderComponent = false; this.$nextTick().then(() => { this.renderComponent = true; }); }
不過,這並非一個很好的解決方案,因此,讓咱們作 Vue 想讓咱們作的
這是解決這個問題的兩種最佳方法之一,這兩種方法都獲得了Vue的官方支持。
一般狀況下,Vue 會經過更新視圖來響應依賴項中的更改。然而,當咱們調用forceUpdate
時,也能夠強制執行更新,即便全部依賴項實際上都沒有改變。
下面是大多數人使用這種方法時所犯的最大錯誤。
若是 Vue 在事情發生變化時自動更新,爲何咱們須要強制更新呢?
緣由是有時候 Vue 的響應系統會讓人感到困惑,咱們認爲Vue會對某個屬性或變量的變化作出響應,但實際上並非這樣。在某些狀況下,Vue的響應系統根本檢測不到任何變化。
因此就像上一個方法,若是你須要這個來從新渲染你的組件,可能有一個更好的方法。
有兩種不一樣的方法能夠在組件實例自己和全局調用forceUpdate
:
// 全局 import Vue from 'vue'; Vue.forceUpdate(); // 使用組件實例 export default { methods: { methodThatForcesUpdate() { // ... this.$forceUpdate(); // ... } } }
重要提示:這不會更新任何計算屬性,調用forceUpdate
僅僅強制從新渲染視圖。
key
更改在許多狀況下,咱們須要從新渲染組件。
要正確地作到這一點,咱們將提供一個key
屬性,以便 Vue 知道特定的組件與特定的數據片斷相關聯。若是key
保持不變,則不會更改組件,可是若是key
發生更改,Vue 就會知道應該刪除舊組件並建立新組件。
正是咱們須要的!
可是首先,咱們須要繞一小段路來理解爲何在Vue中使用key
。
一旦你理解了這一點,那麼這是瞭解如何以正確方式強制從新渲染的很小的一步。
假設咱們要渲染具備如下一項或多項內容的組件列表:
created
或mounted
鉤子中若是你對該列表進行排序或以任何其餘方式對其進行更新,則須要從新渲染列表的某些部分。 可是,不會但願從新渲染列表中的全部內容,而只是從新渲染已更改的內容。
爲了幫助 Vue 跟蹤已更改和未更改的內容,咱們提供了一個key
屬性。 在這裏使用數組的索引,由於索引沒有綁定到列表中的特定對象。
const people = [ { name: 'Evan', age: 34 }, { name: 'Sarah', age: 98 }, { name: 'James', age: 45 }, ];
若是咱們使用索引將其渲染出來,則會獲得如下結果:
<ul> <li v-for="(person, index) in people" :key="index"> {{ person.name }} - {{ index }} </li> </ul> // Outputs Evan - 0 Sarah - 1 James - 2
若是刪除Sarah
,獲得:
Evan - 0 James - 1
與James
關聯的索引被更改,即便James
仍然是James
。 James
會被從新渲染,這並非咱們但願的。
因此這裏,咱們可使用惟一的 id
來做爲 key
const people = [ { id: 'this-is-an-id', name: 'Evan', age: 34 }, { id: 'unique-id', name: 'Sarah', age: 98 }, { id: 'another-unique-id', name: 'James', age: 45 }, ]; <ul> <li v-for="person in people" :key="person.id"> {{ person.name }} - {{ person.id }} </li> </ul>
在咱們從列表中刪除Sarah
以前,Vue刪除了Sarah
和James
的組件,而後爲James
建立了一個新組件。如今,Vue知道它能夠爲Evan
和James
保留這兩個組件,它所要作的就是刪除Sarah
的。
若是咱們向列表中添加一個person
,Vue 還知道能夠保留全部現有的組件,而且只須要建立一個新組件並將其插入正確的位置。這是很是有用的,當咱們有更復雜的組件,它們有本身的狀態,有初始化邏輯,或者作任何類型的DOM操做時,這對咱們頗有幫助。
因此接下來看看,若是使用最好的方法來從新渲染組件。
最後,這是強制Vue從新渲染組件的最佳方法(我認爲)。
咱們能夠採用這種將key
分配給子組件的策略,可是每次想從新渲染組件時,只需更新該key
便可。
這是一個很是基本的方法
<template> <component-to-re-render :key="componentKey" /> </template> export default { data() { return { componentKey: 0, }; }, methods: { forceRerender() { this.componentKey += 1; } } }
每次forceRerender
被調用時,咱們的componentKey
都會改變。當這種狀況發生時,Vue將知道它必須銷燬組件並建立一個新組件。咱們獲得的是一個子組件,它將從新初始化自身並「重置」其狀態。
若是確實須要從新渲染某些內容,請選擇key
更改方法而不是其餘方法。
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
原文:https://hackernoon.com/the-co...
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
https://github.com/qq44924588...
我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!
關注公衆號,後臺回覆福利,便可看到福利,你懂的。