Vue中關(guān)于重新渲染組件的方法及總結(jié)
重新渲染組件的方法總結(jié)
有時Vue的反應(yīng)性系統(tǒng)還不夠,您只需要重新渲染組件即可。
重新渲染組件有以下幾個辦法:
- 可怕的方法:重新加載整個頁面
- 可怕的方法:使用v-if
- 更好的方法:使用Vue的內(nèi)置forceUpdate方法
- 最好的方法:在組件上進行key更改
重新加載整個頁面
非常不建議這樣做,我們來看下一個辦法
v-if指令,該指令僅在組件為true時才渲染。 如果為false,則該組件在DOM中不存在。
下面我們設(shè)置它以使其v-if能夠正常工作的方式。
在您的template,您將添加v-if指令:
<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>
這里發(fā)生的事情:
- 最初renderComponent設(shè)置為true,因此my-component組件渲染
- 在forceRerender中我們立即設(shè)置renderComponent為false
- 停止渲染組件my-component,因為該v-if指令現(xiàn)在的值為false
- 在nextTick中將renderComponent上設(shè)置回true
- 現(xiàn)在該v-if結(jié)果為true,因此我們my-component再次開始渲染
我們必須等到nextTick,否則我們不會看到任何變化。
在Vue中,一個 nextTick 是一個DOM更新周期。Vue將收集在同一 nextTick 中進行的所有更新,在 nextTick 結(jié)束時,它將根據(jù)這些更新來渲染 DOM 中的內(nèi)容。如果我們不等到nextTick,我們對renderComponent的更新就會自動取消,什么也不會改變。
其次,當(dāng)我們第二次渲染時,Vue將創(chuàng)建一個全新的組件。 Vue 將銷毀第一個,并創(chuàng)建一個新的,這意味著我們的新my-component將像正常情況一樣經(jīng)歷其所有生命周期-created,mounted等。
不過,這并不是一個很好的解決方案,往下看
使用forceUpdate
方法解讀:
Vue中,$forceUpdate()的使用
方文檔中指出,$forceUpdate具有強制刷新的作用。那在vue框架中,如果data中有一個變量:age,修改他,頁面會自動更新。
但如果data中的變量為數(shù)組或?qū)ο螅覀冎苯尤ソo某個對象或數(shù)組添加屬性,頁面是識別不到的<template>
<p>{{userInfo.name}}</p> ? <button @click="updateName">修改userInfo</button> </template> <script> ? data(){ ? ? return{ ? ? ? userInfo:{name:'小明'} ? ? } ? }, ? methods:{ ? ? updateName(){ ? ? ? this.userInfo.name='小紅' ? ? } ? } </script>
在updateName函數(shù)中,我們嘗試給userInfo對象修改值,發(fā)現(xiàn)頁面其實并沒有變化
那這時候有兩種解決方法:
方法一:
methods:{ ? updateName(){ ? ? this.userInfo.name='小紅'//在此時,確實已經(jīng)將userInfo對象修改完成 ? ? console.log(this.userInfo.name);//輸出結(jié)果: 小紅 ? ? this.$forceUpdate();//在這里,強制刷新之后,頁面的結(jié)果變?yōu)?小紅' ? } }
$forceUpdate() 這個方法也可以處理 修改for循環(huán) 里面 item的屬性值,沒有渲染出來添加這個方法也生效
方法二:
methods:{ ? updateName(){ ? ? this.$set('userInfo',name,'小紅'); ? } }
這是解決此問題的兩種最佳方法之一,此方法得到Vue的官方支持。
下面是示例:
forceUpdate在組件實例本身以及全局實例上,可以通過兩種不同的方式調(diào)用
// 全局 import Vue from 'vue'; Vue.forceUpdate(); ? // 使用組件實例 export default { ? methods: { ? ? methodThatForcesUpdate() { ? ? ? // ... ? ? ? this.$forceUpdate(); ? ? ? // ... ? ? } ? } }
重要提示:這不會更新您擁有的任何計算屬性。調(diào)用forceUpdate只會強制重新渲染視圖
最好的方法:修改組件的key達到組件重新渲染
在許多情況下,我們需要重新渲染組件。
要正確地做到這一點,我們將提供一個key屬性,以便 Vue 知道特定的組件與特定的數(shù)據(jù)片段相關(guān)聯(lián)。如果key保持不變,則不會更改組件,但是如果key發(fā)生更改,Vue 就會知道應(yīng)該刪除舊組件并創(chuàng)建新組件。
我們可以采用這種將key分配給子組件的策略,但是每次想重新渲染組件時,只需更新該key即可。
<template> ? <component-to-re-render :key="componentKey" /> </template> ? export default { ? data() { ? ? return { ? ? ? componentKey: 0, ? ? }; ? }, ? methods: { ? ? forceRerender() { ? ? ? this.componentKey += 1; ? ? ? ? //this.componentKey += new Date(); ? ? } ? } }
每次 forceRerender被調(diào)用時,我們的componentKey都會改變。
當(dāng)這種情況發(fā)生時,Vue將知道它必須銷毀組件并創(chuàng)建一個新組件。
我們得到的是一個子組件,它將重新初始化自身并“重置”其狀態(tài)。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
elementUi vue el-radio 監(jiān)聽選中變化的實例代碼
這篇文章主要介紹了elementUi vue el-radio 監(jiān)聽選中變化,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06關(guān)于vue.js組件數(shù)據(jù)流的問題
本篇文章主要介紹了關(guān)于vue.js組件數(shù)據(jù)流的問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07