vue中?$forceUpdate的使用解析
在vue的開發(fā)過(guò)程中,數(shù)據(jù)的綁定通常來(lái)說(shuō)都不用我們操心,例如在??data?
?中有一個(gè)??msg?
?的變量,只要修改它,那么在頁(yè)面上,??msg?
?的內(nèi)容就會(huì)自動(dòng)發(fā)生變化。但是如果對(duì)于一個(gè)復(fù)雜的對(duì)象,例如一個(gè)對(duì)象數(shù)組,直接去給數(shù)組上某一個(gè)元素增加屬性,或者直接把數(shù)組的??length?
?變成0,vue可能就無(wú)法知道發(fā)生了改變。這個(gè)其實(shí)就是考驗(yàn)對(duì)于雙向綁定的更進(jìn)一步的理解應(yīng)用了。
在Vue中,雙向綁定屬于自動(dòng)檔,然而在特定的情況下,需要手動(dòng)觸發(fā)“刷新”操作,目前有四種方案可以選擇:
- 刷新整個(gè)頁(yè)面
- 使用v-if標(biāo)記
- 使用內(nèi)置的forceUpdate方法
- 使用key-changing優(yōu)化組件
方案分析
本次文章主要重點(diǎn)在于分析??forceUpdate?
?這個(gè)方法,后續(xù)有機(jī)會(huì)再來(lái)分析??key-changing?
?。
forceUpdate
該方案是比較好的一種方式,比如說(shuō)我們嘗試直接給某個(gè)??object?
?增加一個(gè)屬性,發(fā)現(xiàn)頁(yè)面上沒(méi)有效果;直接將length變成0來(lái)清空數(shù)組,也沒(méi)有效果,
關(guān)鍵代碼如下:
change: function(index) { // 增加性格屬性 this.girls[idx].character = 'lovely'; }, clear: function() { // 清空數(shù)組 this.girls.length = 0; }
按照上面的寫法沒(méi)有產(chǎn)生想要的效果,是因?yàn)闆](méi)有按照vue的規(guī)范去寫,因?yàn)槲臋n里面寫了,對(duì)于深層的,最好用$set方法,這樣vue就可以知道發(fā)生了變化,同時(shí)vue也不建議直接修改length,而是給一個(gè)空數(shù)組來(lái)置空。
如果我們按照vue的規(guī)范去寫的,是可以實(shí)現(xiàn)變化的,
關(guān)鍵代碼如下:
change: function(index) { // 增加性格屬性 this.$set(this.girls[idx],'character','lovely') }, clear: function() { // 清空數(shù)組 this.girls = []; }
如果我們不想利用??$set?
?去設(shè)置,非要按照我們第一種方式去寫,可以實(shí)現(xiàn)么?可以的,就是利用??$forceUpdate?
?,此時(shí)修改了數(shù)據(jù),然而頁(yè)面層沒(méi)有變動(dòng),之后通過(guò)日志打印的方式確認(rèn)數(shù)據(jù)是否有修改過(guò),之后再確認(rèn)有沒(méi)有監(jiān)聽到,用??$forceUpdate?
?就相當(dāng)于按照最新數(shù)據(jù)給渲染一下。
關(guān)鍵代碼如下:
change: function(index) { this.girls[idx].character = '男'; this.$forceUpdate(); }, clear: function() { this.girls.length = 0; this.$forceUpdate(); }
這種做法實(shí)際上并不推薦,官方說(shuō)如果你現(xiàn)在的場(chǎng)景需要用??forceUpdate?
?方法 ,那么99%是你的操作有問(wèn)題,如上data里不顯示聲明對(duì)象的屬性,之后添加屬性時(shí)正確的做法時(shí)用 ??$set()?
?方法,所以??forceUpdate?
?請(qǐng)慎用。
該同等效果的:window.location.reload()
本質(zhì)
在vue的官方文檔中有說(shuō)明到這個(gè)是一個(gè)強(qiáng)制刷新的api,但很少用到,除非是遇到了需要實(shí)時(shí)響應(yīng)組件狀態(tài)的時(shí)候
Force the component instance to re-render.
This should be rarely needed given Vue's fully automatic reactivity system. The only cases where you may need it is when you have explicitly created non-reactive component state using advanced reactivity APIs.
實(shí)現(xiàn)原理
Vue.prototype.$forceUpdate = function () { const vm: Component = this if (vm._watcher) { vm._watcher.update() } }
實(shí)例需要重新渲染是在依賴發(fā)生變化的時(shí)候會(huì)通知??watcher?
?,然后通知??watcher?
?來(lái)調(diào)用??update?
?方法,就是這么簡(jiǎn)單。
分析
forceUpdate
就是重新render
- 有些變量不在?
? state?
?上,但是你又想達(dá)到這個(gè)變量更新的時(shí)候,重新(render),從而渲染虛擬DOM。
- 注意到這個(gè)時(shí)候并不是重新加載組件。
- 結(jié)合vue的生命周期,調(diào)用?
?$forceUpdate?
?后只會(huì)觸發(fā)??beforeUpdate?
?和??updated?
?這兩個(gè)鉤子函數(shù),不會(huì)觸發(fā)其他的鉤子函數(shù)。它僅僅影響實(shí)例本身和插入插槽內(nèi)容的子組件,而不是所有子組件,即強(qiáng)制更新因某些原因并未渲染到頁(yè)面的,已經(jīng)改變的,應(yīng)該被渲染到頁(yè)面的數(shù)據(jù)
- ?
?state?
?里的某個(gè)變量層次太深,更新的時(shí)候沒(méi)有自動(dòng)觸發(fā)?? render?
?。
這些時(shí)候都可以手動(dòng)調(diào)用 forceUpdate 自動(dòng)觸發(fā) render 。所以建議使用?? immutable?
?來(lái)操作?? state?
? ,??redux?
? 等?? flux?
? 架構(gòu)來(lái)管理?? state?
?。
刷新頁(yè)面
這個(gè)方案是挺low的,本質(zhì)上是刷新頁(yè)面
this.$router.go(0)
使用v-if標(biāo)記
如果是刷新某個(gè)子組件,則可以通過(guò)??v-if?
?指令實(shí)現(xiàn)。我們知道,當(dāng)??v-if?
?的值發(fā)生變化時(shí),組件都會(huì)被重新渲染一遍。因此,利用??v-if?
?指令的特性,可以達(dá)到強(qiáng)制刷新組件的目的。
<template> <compare v-if="refresh"></compare> <el-button @click="refreshComp()">刷新comp組件</el-button> </template> <script> import compare from '@/views/compare.vue' export default { name: 'parentComp', data() { return { refresh: true } }, methods: { refreshComp() { // 移除組件 this.refresh = false // 在組件移除后,重新渲染組件 // this.$nextTick可實(shí)現(xiàn)在DOM 狀態(tài)更新后,執(zhí)行傳入的方法。 this.$nextTick(() => { this.refresh = true }) } } } </script>
key-changing
原理很簡(jiǎn)單,vue使用key標(biāo)記組件身份,當(dāng)key改變時(shí)就是釋放原始組件,重新加載新的組件。
<template> <div> <span :key="key"></span> </div> </template> <script> export default { data() { return { key: 0 } }, methods: { handleUpdateClick() { this.key += 1 // 或者 this.key = new Date(); } } } </script>
到此這篇關(guān)于vue中 $forceUpdate的使用解析的文章就介紹到這了,更多相關(guān)$forceUpdate解析內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
element-plus結(jié)合sortablejs實(shí)現(xiàn)table行拖拽效果
使用element-plus的el-table組件創(chuàng)建出來(lái)的table,結(jié)合sortable.js實(shí)現(xiàn)table行拖動(dòng)排序,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,感興趣的同學(xué)可以自己動(dòng)手試一試2023-10-10VUE UPLOAD 通過(guò)ACTION返回上傳結(jié)果操作
這篇文章主要介紹了VUE UPLOAD 通過(guò)ACTION返回上傳結(jié)果操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09手寫vue無(wú)限滾動(dòng)指令的詳細(xì)過(guò)程
今天在移動(dòng)端項(xiàng)目中遇見一個(gè)需求,需要數(shù)據(jù)無(wú)限滾動(dòng),所以下面這篇文章主要給大家介紹了關(guān)于手寫vue無(wú)限滾動(dòng)指令的詳細(xì)過(guò)程,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09解決vue項(xiàng)目 build之后資源文件找不到的問(wèn)題
這篇文章主要介紹了解決vue項(xiàng)目 build之后資源文件找不到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09關(guān)于net?6+vue?插件axios?后端接收參數(shù)問(wèn)題
接到這樣一個(gè)項(xiàng)目需求是這樣的,前端vue?必須對(duì)象傳遞后端也必須對(duì)象接收,接下來(lái)通過(guò)本文給大家介紹下net?6+vue?插件axios?后端接收參數(shù)的問(wèn)題,需要的朋友可以參考下2022-01-01Vue在chrome44偶現(xiàn)點(diǎn)擊子元素事件無(wú)法冒泡的解決方法
這篇文章主要給大家介紹了關(guān)于Vue在chrome44偶現(xiàn)點(diǎn)擊子元素事件無(wú)法冒泡的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12