1. 程式人生 > >vue項目實現列表頁-詳情頁返回不刷新,再點其他菜單項返回刷新的需求

vue項目實現列表頁-詳情頁返回不刷新,再點其他菜單項返回刷新的需求

通用 png 解決 效果 需要 lse 情況 ner 發現

  問題背景:有時候一些列表會有一些跳轉的需求,比如跳到詳情頁、或者是其他相關的頁面(比如跳到用戶列表去查看用戶的相關信息)等,此時再返回列表頁,列表頁會刷新重置。目前需求就是需要改成如下情況:

  問題1、列表 - 詳情頁,返回,不刷新重置;

  問題2、再點其他菜單,再返回,需要刷新重置。

  解決思路:

  解決需求自然是想到vue的keep-alive去緩存組件,但是緩存組件有個不好的弊端,就是以後再進入頁面也一直保持著上一次瀏覽的狀態,那麽如果我們有很多查詢條件的情況,或者比如 route/:id 這種動態路由匹配的情況,那麽頁面就不會重新加載。

  對於這個需求,組裏人員意願傾向於全部緩存頁面,利用 keep-alive 的include、exclude屬性去緩存需要緩存的頁面;然後對於如果有特殊需要刷新頁面的查詢參數,比如動態路由的那種情況,就利用watch去解決。個人認為這種解決方案既繁瑣,又不易維護,不易測試。

  所以一直再想一個通用的方案。我一直的思路就是:

  1、利用路由的meta信息增加:meta: {keepAlive: true}

  2、利用路由的beforeRouteLeave,如果跳出去的頁面是需要返回不刷新頁面的路由(如詳情、用戶列表),那麽就給當前路由meta.keepAlive = true,否則設為false

beforRouteLeave (to, from, next) {
  if ([orderDetaiInfo].includes(to.name)) {
    from.meta.keepAlive = true
  } else {
    
from.meta.keepAlive = false } next() }

  3、然後在app.vue裏面去控制

<el-container class="app app_console" v-else-if="$route.fullPath != ‘/‘">
    <WHeader></WHeader>
    <el-container class="forIE">
      <WMenu></WMenu>
      <keep-alive>
        <router-view v-if="$route.meta.keepAlive"></router-view>
        <router-view v-else :key="activeQuery"></router-view>
      </keep-alive>
<img class="material" src="./assets/commonImages/pattern.png" height="240"> </el-container> </el-container>

  當時想的也比較簡單,需要緩存的時候就走的keepAlive為true的view,再回來就會緩存不刷新了。當跳至其他菜單後,其keepAlive就置為false了,那麽再返回時就走的下面有key值刷新的view了。

  問題完成一半,測試發現一個問題:

  上面問題背景的1、2是可以很好的解決了,但是卻出現第3個問題:

  問題3:問題1、2之後再點擊詳情,再返回,卻不是剛剛那個頁面,而是之前緩存的頁面。

  原因:問題3的此時,該頁面比如order頁的meta的keepAlive此時是false的,那我在order當前頁面進入的時候去改變為true,依然不會有效果,原因就是我們上面是形成了2個view,我們緩存的是上面那個view,就算改成true了,再返回時也是去的上面那個view,所以是返回之前緩存的頁面,很惆悵。

  解決方案其實也很簡單,那麽就是想法讓從其他菜單,再進入當前order時,讓進入的view變成keepAlive的就行了。

  當時一直沒想到一個好的方案,就只想到利用go(0),讓頁面重進一次,這樣確實解決了問題3,但是體驗不好。一度妥協去用watch,但是今天突然想到我可以利用一個blank空的頁面去承接一下keepAlive的false的情況,相當於利用blank頁面去達到go(0),讓頁面重進的目的,但是體驗又不會刷新,由於是空頁面,所以幾乎看不出問題。

  就寫下簡單方案:keep-alive,beforeRouteLeave,vuex,blank.vue

  1、vuex存一個keepAlive控制什麽情況進入blank頁面

  什麽情況呢?(1)keepAlive為false;(2)需為那些需要緩存的頁面,也就是加了meta.keepAlive為true的路由。否則沒加的那些路由也都會走進blank頁,影響結果。

<el-container class="app app_console" v-else-if="$route.fullPath != ‘/‘">
    <WHeader></WHeader>
    <Blank v-if="!keepAlive && [‘orderList‘].includes($route.name)"></Blank>
    <el-container v-else class="forIE">
      <WMenu></WMenu>
      <keep-alive>
        <router-view v-if="$route.meta.keepAlive"></router-view>
        <router-view v-else :key="activeQuery"></router-view>
      </keep-alive>
      <img class="material" src="./assets/commonImages/pattern.png" height="240">
    </el-container>
  </el-container>

  2、beforeRouteLeave的時候,如果調整其他菜單項,那麽就給vuex的keepAlive置為false,讓下次再進入order的時候,進入blank頁面

  3、在blank頁面進行處理:(1)修改當前order頁面meta.keepAlive為true;(2)修改vuex的keepAlive為true,促使重新進入下面的緩存頁面。

  這樣就大功告成了。只是自己大致測了一下,優化暫未考慮。

vue項目實現列表頁-詳情頁返回不刷新,再點其他菜單項返回刷新的需求