一般刷新頁面可以用 location.reload(true),history.go(0) 等方法,但是這對vue項目很不友好,會使頁面重新加載出現暫時性的空白,而且耗費性能,所以vue項目最好不用這些方法。vue有this.$forceUpdate()可以強制更新,下面介紹其他更好的方法。
一、帶上當前頁面路由跳轉到一個重定向的頁面,重定向頁面再跳轉回來
// 1、新建refresh.vue
<script> export default { name: "refresh", beforeCreate(){ this.$router.push(this.$route.query.path) }, }; </script>
// 2、router.js配置一個refresh路由
import refresh from './components/refresh.vue' { path: '/refresh', name: 'refresh', component: refresh }, // 3、在要刷新的地方跳轉傳參即可
reflesh(){ this.$router.push({path:'/refresh',query:{path:this.$route.fullPath}}) },
有一個問題是點擊瀏覽器返回相當於沒點擊,因為跳轉的是refresh頁面,而refresh又會跳回原頁面。所以並不合適。
二、通過 provide 和 inject 結合 v-if 的功能觸發頁面刷新
這對選項需要一起使用,以允許一個根組件向其所有子組件注入一個依賴,實現原理就是通過控制router-view 的顯示與隱藏,來重渲染路由區域,重而達到頁面刷新的效果,show -> false -> show
1、修改app.vue,利用 v-if 可以刷新頁面的屬性,同時使用 provide 和 inject 將祖先節點的數據傳遞給子代節點
<template>
<div id="app">
<router-view v-if="isRouterAlive"></router-view>
</div>
</template>
<script> export default { name: 'App', provide (){ return { reload:this.reload } }, data(){ return { isRouterAlive:true } }, methods:{ reload (){ this.isRouterAlive = false this.$nextTick(function(){ this.isRouterAlive = true }) } }, components:{ } } </script>
2、在要刷新的子路由頁面引入inject,然后執行reload事件即可刷新頁面
export default { name: "demo", inject:['reload'], data() { return {} }, methods: { reflesh(){ this.reload() }, } }
三、使用內置的forceUpdate
方法(較好的)
組件內置$forceUpdate
方法,使用前需要在配置中啟用
import Vue from 'vue' Vue.forceUpdate() export default { methods: { handleUpdateClick() {
this.$forceUpdate() } } }
由於一些嵌套特別深的數據,導致數據更新了,但是頁面卻沒有重新渲染。我遇到的一個情況是,v-for遍歷數據渲染,當方法中處理相應數組數據時,數組改變了,但是頁面卻沒有重新渲染。
解決方法:運用 this.$forceUpdate()
強制刷新,解決v-for更新數據不重新渲染頁面。
官方解釋:迫使 Vue 實例重新渲染。注意它僅僅影響實例本身和插入插槽內容的子組件,而不是所有子組件。
四、使用key-changing
優化組件(最好的)
key-changing的原理很簡單,vue使用key
標記組件身份,當key
改變時就是釋放原始組件,重新加載新的組件。
<template>
<div>
<!-- 父組件 -->
<div>
<button @click="reLoad">點擊重新渲染子組件</button>
</div>
<!-- 內容庫子組件 -->
<lib-window :key="time" :channelCode="searchChannelCode"></lib-window>
</div>
</template>
<script> import children from '@/components/parent/children' export default { name: 'contentLib', components: { libWindow }, data () { return { time: '' } }, methods: { reLoad () { this.time = new Date().getTime() } } } </script>
我們通過 :key
實現,當key 值變更時,會自動的重新渲染,key的作用主要是為了高效的更新虛擬DOM。推薦使用這種。