vue項目刷新當前頁面的幾種解決方案對比:如何優雅的強制重新渲染子組件


  一般刷新頁面可以用 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。推薦使用這種。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM