最近做用vue做後端管理頁面的時候遇到一個問題:需要刷新子路由的頁面
背景:
傳統嵌套iframe的頁面實現實現特別簡單,只需要給替換iframe的鏈接就可以了
vue可以考慮通過更新:key來觸發更新(適用所有組件)
`key 的特殊屬性主要用在 Vue 的虛擬 DOM 算法,在新舊 nodes 對比時辨識 VNodes`
<router-view :key=“$store.app.state.upDate”></router-view>
添加一個key,因爲涉及跨組件操作,所以可以通過vuex來管理它
一般情況下,這樣處理可以解決這個需求。
暫時這裏稱爲方法①
方法③:this.$router.push
下面展示另外一種方法(方法②)會比較複雜,它會使用到的API有:
- 1.vm.$forceUpdate()
- 2.vm.watch
- 3.mixins
- 4.vuex
詳細:
- 1.vm.$forceUpdate() 這個函數是專門用
來刷新組件的(更新於2018/11/02 :這個只能更新當前組件本身和slot子組件),可以理解爲重置vm本身的狀態,讓程序重新走一遍生命週期 - 2.vm.watch是監聽某個data、computed裏面的屬性,當出現變動的時候執行對應的回調
- 3.mixins 是一種用來給VUE組件混入配置的API,如果原來組件已經存在對應的同名配置,會會執行2個同名配置裏面的程序
- 4.vuex一個狀態管理的vue工具,設計多個同級子組件數據通訊的時候常用
程序流程:
- 在vuex裏面加一個state
- 在程序根組件的【文件】裏面加一個JSON配置Config,
- Config的computed加一個變量A,讓A依賴vuex的state,
- 同時Config加watch,watch變量A,如果A發生變動就執行watch對應的函數this.$forceUpdate()[注意不要用箭頭函數]
- 通過給根組件mixins,這樣就可以給每個組件添加監聽和刷新
警告:`也可以全局註冊混入對象。注意使用! 一旦使用全局混入對象,將會影響到 所有 之後創建的 Vue 實例`
官網:https://cn.vuejs.org/v2/guide/mixins.html#%E5%85%A8%E5%B1%80%E6%B7%B7%E5%85%A5
注意:如果你的路由是用keep-live包裹的話,這個方法將會無效,例如:
<keep-alive >router-view ></router-view></keep-alive>
keep-alive是個特殊的標籤,你設置了key並不會刷新裏面的內容,涉及動態更新keep-alive可以瞭解下官網
如果你遇到這種情況,可以嘗試另外一種方法。它是一種暴力、帶有副作用、很取巧的一種處理方式(方法③)
通過最添加自定義query或減少之定義query來刷新!
如果你的頁面狀態都用vuex來控制的話,使用這個方法特別方便並且不會出現頁面閃動的情況
if(this.$route.query.keepalivekeepalive){
let tmp=Object.assign({},this.$route,{query:{}});
this.$router.push(tmp);
}
else{
let tmp=Object.assign({},this.$route,{query:{"keepalivekeepalive":true}});
this.$router.push(tmp);
}
更新(18/07/25)
如果使用了keepAlive的話,不得不說下keepAlive的include(動態管理緩存內容)屬性,用法大概如下:
<!-- 一個include解決了,不需要多寫一個標籤,也不需要在路由元中添加keepAlive了 -->
<keep-alive include='a'>
<router-view></router-view>
</keeo-alive>
vue 2.1.0之後你可以這樣使用include可以是個數組,如果你的router-view裏面切換的單頁面組件沒有寫name它將會無效。
更新(19/05/04)
方法③最簡單時候不考慮keeplive,這種操作方式之前就應該知道有這回事,但是不確定爲什麼沒有加上去,
// tabs, 刷新當前
tabsRefreshCurrentHandle () {
var tab = this.$route
this.removeTabHandle(tab.name)
this.$nextTick(() => {
this.$router.push({ name: tab.name, query: tab.query, params: tab.params })
})
}