成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

另辟蹊徑:vue單頁(yè)面,多路由,前進(jìn)刷新,后退不刷新

Ocean / 3517人閱讀

摘要:如何添加這個(gè)條件,判斷用戶(hù)是否刷新了頁(yè)面呢我們知道,當(dāng)使用后,只有第一次進(jìn)入后會(huì)觸發(fā)鉤子函數(shù),再次進(jìn)入就不再執(zhí)行了。

目的:vue-cli構(gòu)建的vue單頁(yè)面應(yīng)用,某些特定的頁(yè)面,實(shí)現(xiàn)前進(jìn)刷新,后退不刷新,類(lèi)似app般的用戶(hù)體驗(yàn)。
注: 此處的刷新特指當(dāng)進(jìn)入此頁(yè)面時(shí),觸發(fā)ajax請(qǐng)求,向服務(wù)器獲取數(shù)據(jù)。不刷新特指當(dāng)進(jìn)入此頁(yè)面時(shí),不觸發(fā)ajax請(qǐng)求,而是使用之前緩存的數(shù)據(jù),以便減少服務(wù)器請(qǐng)求,用戶(hù)體驗(yàn)更流暢。

項(xiàng)目需求:

任何技術(shù)的探索,都來(lái)自項(xiàng)目的需求。之前經(jīng)手的一個(gè)項(xiàng)目是微信端商城,使用的是傳統(tǒng)的mvc模式,利用的是jq+js,因此對(duì)于商城的項(xiàng)目需求比較熟悉。目前在學(xué)習(xí)vue,練手一個(gè)商城,遇到之前經(jīng)常提及而無(wú)法很好解決的需求。有些頁(yè)面需要前進(jìn)刷新,后退不刷新。比如,從商城的【首頁(yè)】-->【詳情頁(yè)】-->【訂單提交頁(yè)】,每次打開(kāi)新頁(yè)面都需要獲取新數(shù)據(jù),但是按下返回鍵后,就不需要再獲取新數(shù)據(jù)了,而滾動(dòng)條還保留在之前的位置。最常見(jiàn)的操作是從【首頁(yè)】-->【詳情頁(yè)】,然后在從【詳情頁(yè)】-->【首頁(yè)】,如此反復(fù)。
實(shí)例如圖:

前人經(jīng)驗(yàn):

前人栽樹(shù),后人好乘涼。技術(shù)圈的分享一直都在蓬勃發(fā)展。遇到問(wèn)題,我們可以盡情去搜索,去尋找大佬的足跡。針對(duì)上述需求,看到一個(gè)分享vue-router 之 keep-alive,比較符合我的需求,但是使用到我的項(xiàng)目上發(fā)現(xiàn),稍微有點(diǎn)不適合。此分享技術(shù)要點(diǎn),比較適合兩個(gè)頁(yè)面之前的跳轉(zhuǎn),返回。而我的頁(yè)面是多個(gè)路由(2+)之間的跳轉(zhuǎn),返回。無(wú)奈,只能去自己探索發(fā)現(xiàn)。不過(guò)此技術(shù)要點(diǎn)給了我很好的啟發(fā),特此感謝作者。@ RoamIn

實(shí)現(xiàn)思路:

注:demo中,index頁(yè)面包含三個(gè)鏈接導(dǎo)航。page1-->page2-->page3.依次前進(jìn),每次前進(jìn)到一個(gè)新頁(yè)面都需要獲取數(shù)據(jù),而按下后退鍵后,從page3返回到page2,page2不再獲取新數(shù)據(jù),而是使用之前緩存的數(shù)據(jù)。從page2返回到page1時(shí),page1不再獲取新數(shù)據(jù),而是使用之前的數(shù)據(jù)。所以,page1和page2需要緩存,page3不需要緩存。可以把page1想象成首頁(yè),page2想象成詳情頁(yè),page3想象成訂單提交頁(yè)。這樣方便理解。

利用keep-alive 緩存需要緩存的頁(yè)面

在app.vue中改寫(xiě)router-view


    
        
    



    

在router/index.js中添加路由元信息,設(shè)置需要緩存的頁(yè)面

routes: [{
        path: "/",
        name: "index",
        component: index,
        meta: {
            keepAlive: false, //此組件不需要被緩存
        }
    },
    {
        path: "/page1",
        name: "page1",
        component: page1,
        meta: {
            keepAlive: true, //此組件需要被緩存
            
        }
    },
    {
        path: "/page2",
        name: "page2",
        component: page2,
        meta: {
            keepAlive: true, // 此組件需要被緩存
           
        }
    },
    {
        path: "/page3",
        name: "page3",
        component: page3,
        meta: {
            keepAlive: false, // 此組件不需要被緩存
        }
    }
]

鉤子函數(shù)的執(zhí)行順序

不使用keep-alive
beforeRouteEnter --> created --> mounted --> destroyed

使用keep-alive
beforeRouteEnter --> created --> mounted --> activated --> deactivated
再次進(jìn)入緩存的頁(yè)面,只會(huì)觸發(fā)beforeRouteEnter -->activated --> deactivated 。created和mounted不會(huì)再執(zhí)行。我們可以利用不同的鉤子函數(shù),做不同的事。務(wù)必理解上述鉤子函數(shù)的執(zhí)行時(shí)機(jī)和執(zhí)行順序,本教程的核心就依賴(lài)于此鉤子函數(shù)
activated和deactivated是使用keep-alive后,vue中比較重要的兩個(gè)鉤子函數(shù),建議詳細(xì)了解下。

需緩存的頁(yè)面的寫(xiě)法

注:demo中的page1和page2,這兩個(gè)頁(yè)面都需要緩存,思路一樣,以下以page1為例,page2不再贅述。
示例文件:components/page1.vue

data中初始化一個(gè)str字符串,存放從后臺(tái)獲取的數(shù)據(jù)

     data() {
       return {
         msg: "我是第一個(gè)頁(yè)面",
         str: ""  // 加載頁(yè)面后執(zhí)行獲取數(shù)據(jù)的方法,插入到此
       };
     }

methods中創(chuàng)建一個(gè)方法,模擬從后臺(tái)獲取數(shù)據(jù)

     methods: {
       getData() {
         // getData方法,模擬從后臺(tái)請(qǐng)求數(shù)據(jù)
         this.str = "我是通過(guò)調(diào)用方法加載的數(shù)據(jù)。。。";
       }
     }

修改router/index.js中的配置

每次進(jìn)入頁(yè)面,我們都需要知曉是從哪個(gè)頁(yè)面進(jìn)來(lái)的,用以判斷是否需要獲取數(shù)據(jù)。以這個(gè)page1頁(yè)面為例,當(dāng)我們知曉是從page2過(guò)來(lái)的,我們就可以認(rèn)為是用戶(hù)操作了返回鍵,這時(shí)page1頁(yè)面就不需要再獲取新數(shù)據(jù)了,使用之前緩存的數(shù)據(jù)就可以了。如果是從別的頁(yè)面過(guò)來(lái)的,我們就需要獲取數(shù)據(jù)。

我們可以通過(guò)beforeRouteEnter這個(gè)鉤子函數(shù)中的from參數(shù)判斷是從哪個(gè)頁(yè)面過(guò)來(lái)的,這個(gè)參數(shù)執(zhí)行時(shí),組件實(shí)例還沒(méi)創(chuàng)建,所有不能在data中定義變量。我們可以在路由中定義一個(gè)變量,用來(lái)判斷。

在router/index.js的meta中添加isBack變量,默認(rèn)false

     {
          path: "/page1",
          name: "page1",
          component: page1,
          meta: {
              keepAlive: true, //此組件需要被緩存
              isBack:false, //用于判斷上一個(gè)頁(yè)面是哪個(gè)
          }
      },
      {
          path: "/page2",
          name: "page2",
          component: page2,
          meta: {
              keepAlive: true, // 此組件需要被緩存
              isBack:false, //用于判斷上一個(gè)頁(yè)面是哪個(gè)
          }
      },

beforeRouteEnter中判斷是從哪個(gè)頁(yè)面過(guò)來(lái)的

判斷是從哪個(gè)路由過(guò)來(lái)的,如果是page2過(guò)來(lái)的,表明當(dāng)前頁(yè)面不需要刷新獲取新數(shù)據(jù),直接用之前緩存的數(shù)據(jù)即可

    beforeRouteEnter(to, from, next) {
      // 路由導(dǎo)航鉤子,此時(shí)還不能獲取組件實(shí)例 `this`,所以無(wú)法在data中定義變量(利用vm除外)
      // 參考 https://router.vuejs.org/zh-cn/advanced/navigation-guards.html
      // 所以,利用路由元信息中的meta字段設(shè)置變量,方便在各個(gè)位置獲取。這就是為什么在meta中定義isBack
      // 參考 https://router.vuejs.org/zh-cn/advanced/meta.html
      if(from.name=="page2"){
          to.meta.isBack=true;
          //判斷是從哪個(gè)路由過(guò)來(lái)的,
          //如果是page2過(guò)來(lái)的,表明當(dāng)前頁(yè)面不需要刷新獲取新數(shù)據(jù),直接用之前緩存的數(shù)據(jù)即可
      }
  
      next();
    },

activated中執(zhí)行g(shù)etData這個(gè)獲取數(shù)據(jù)的方法

因?yàn)檫@個(gè)頁(yè)面需要緩存。只有第一次進(jìn)入時(shí)才會(huì)執(zhí)行created和mounted方法,再次進(jìn)入就不執(zhí)行了。而activated每次進(jìn)入都執(zhí)行,所以在這個(gè)鉤子函數(shù)中獲取數(shù)據(jù)。

activated() {
  if(!this.$route.meta.isBack){
    // 如果isBack是false,表明需要獲取新數(shù)據(jù),否則就不再請(qǐng)求,直接使用緩存的數(shù)據(jù)
    this.getData();
  }
  // 恢復(fù)成默認(rèn)的false,避免isBack一直是true,導(dǎo)致下次無(wú)法獲取數(shù)據(jù)
  this.$route.meta.isBack=false

},

這樣就可以了?

當(dāng)這樣設(shè)置完畢后,你執(zhí)行起來(lái),貌似是可以了。第一次進(jìn)入page1,能獲取新數(shù)據(jù),從page2返回時(shí),不再獲取新數(shù)據(jù)了,而是使用之前緩存的數(shù)據(jù)。但這樣還有一個(gè)問(wèn)題,當(dāng)用戶(hù)從page1進(jìn)入page2后,因?yàn)槟撤N原因,手動(dòng)刷新了page2的頁(yè)面。這時(shí)再返回到page1,發(fā)現(xiàn)之前緩存的數(shù)據(jù)丟失了,而且也沒(méi)有再重新獲取。所以我們還需要再添加一個(gè)判斷條件,當(dāng)用戶(hù)手動(dòng)刷新頁(yè)面后,再返回時(shí)就需要重新獲取數(shù)據(jù)了。

如何添加這個(gè)條件,判斷用戶(hù)是否刷新了頁(yè)面呢?我們知道,當(dāng)使用keep-alive后,只有第一次進(jìn)入后會(huì)觸發(fā)created鉤子函數(shù),再次進(jìn)入就不再執(zhí)行了。當(dāng)用戶(hù)刷新了頁(yè)面,這個(gè)鉤子函數(shù)就會(huì)又執(zhí)行,所以,我們可以利用這個(gè)小技巧來(lái)做點(diǎn)文章。

data中定義變量isFirstEnter用來(lái)判斷是否第一次進(jìn)入,或是否刷新了頁(yè)面,默認(rèn)false

   data() {
     return {
       msg: "我是第一個(gè)頁(yè)面",
       str: "",  // 加載頁(yè)面后執(zhí)行獲取數(shù)據(jù)的方法,插入到此
       isFirstEnter:false // 是否第一次進(jìn)入,默認(rèn)false
     };
   },

created中把isFirstEnter變?yōu)閠rue,說(shuō)明是第一次進(jìn)入或刷新了頁(yè)面

   created() {
     this.isFirstEnter=true;
     // 只有第一次進(jìn)入或者刷新頁(yè)面后才會(huì)執(zhí)行此鉤子函數(shù)
     // 使用keep-alive后(2+次)進(jìn)入不會(huì)再執(zhí)行此鉤子函數(shù)
   },

activated中增加判斷條件

   activated() {
     if(!this.$route.meta.isBack || this.isFirstEnter){
         // 如果isBack是false,表明需要獲取新數(shù)據(jù),否則就不再請(qǐng)求,直接使用緩存的數(shù)據(jù)
         // 如果isFirstEnter是true,表明是第一次進(jìn)入此頁(yè)面或用戶(hù)刷新了頁(yè)面,需獲取新數(shù)據(jù)
         this.str=""http:// 把數(shù)據(jù)清空,可以稍微避免讓用戶(hù)看到之前緩存的數(shù)據(jù)
         this.getData();
     }
     // 恢復(fù)成默認(rèn)的false,避免isBack一直是true,導(dǎo)致下次無(wú)法獲取數(shù)據(jù)
     this.$route.meta.isBack=false
     // 恢復(fù)成默認(rèn)的false,避免isBack一直是true,導(dǎo)致每次都獲取新數(shù)據(jù)
     this.isFirstEnter=false;
 
   },

這樣應(yīng)該就可以了

不需要緩存頁(yè)面的寫(xiě)法

注:demo中的page3,這個(gè)頁(yè)面不需要緩存,該怎么寫(xiě)就怎么寫(xiě),不需要做特別的設(shè)置。

其它設(shè)置:

使用keep-alive后,可能有點(diǎn)小問(wèn)題:第二個(gè)頁(yè)面可能繼承第一個(gè)頁(yè)面的滾動(dòng)條的高度。(在我項(xiàng)目中遇到的)
比如:page1向下滾動(dòng)后,再進(jìn)入page2,這時(shí)page2的滾動(dòng)條可能是之前的高度,可能不會(huì)在頂部。

解決方法一
每次離開(kāi)記錄滾動(dòng)條的高度,再次進(jìn)入時(shí)根據(jù)項(xiàng)目需要再恢復(fù)之前的高度,或者置頂。

解決方法二(推薦)
router/index.js中添加如下代碼(如不理解,請(qǐng)看參考鏈接)
參考:HTML5 History 模式     滾動(dòng)行為

  mode: "history",
  scrollBehavior(to, from, savedPosition) {
      if (savedPosition) {
          return savedPosition
      } else {
          return {
              x: 0,
              y: 0
          }
      }
  }

疑問(wèn)點(diǎn):

在此次demo練習(xí)中,打印了一下鉤子函數(shù)的執(zhí)行順序,發(fā)現(xiàn)一個(gè)疑問(wèn)點(diǎn)(我對(duì)鉤子函數(shù)理解也很淺顯):
從page1進(jìn)入page2時(shí),先執(zhí)行了page2的beforeRouteEnter和created方法,然后才執(zhí)行page1的deactivated方法。
所以我把這兩個(gè)初始化設(shè)置,放在了activated里面,而沒(méi)有放在deactivated中

    this.$route.meta.isBack=false;
    this.isFirstEnter=false;

結(jié)束語(yǔ):

為了解決這個(gè)前進(jìn)刷新后退不刷新問(wèn)題,讓我整整苦惱了一周時(shí)間,想了很多方法,也沒(méi)能解決。最后綜合各個(gè)大佬經(jīng)驗(yàn),試驗(yàn)了很多次,才歸結(jié)出這個(gè)比較‘low’的方法。
目前,我也是vue小白,也在探索著前進(jìn),如果這個(gè)方法能解決你遇到的難題,我很高興。如果你認(rèn)為的確很low,求輕噴。
demo在下方的GitHub中,歡迎star。
也歡迎大家提供意見(jiàn)和建議,謝謝大家

GitHub

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89913.html

相關(guān)文章

  • 架構(gòu)師之路

    摘要:因?yàn)橛脩?hù)不用在第一次進(jìn)入應(yīng)用時(shí)下載所有代碼,用戶(hù)能更快的看到頁(yè)面并與之交互。譯高階函數(shù)利用和來(lái)編寫(xiě)更易維護(hù)的代碼高階函數(shù)可以幫助你增強(qiáng)你的,讓你的代碼更具有聲明性。知道什么時(shí)候和怎樣使用高階函數(shù)是至關(guān)重要的。 Vue 折騰記 - (10) 給axios做個(gè)挺靠譜的封裝(報(bào)錯(cuò),鑒權(quán),跳轉(zhuǎn),攔截,提示) 稍微改改都能直接拿來(lái)用~~~喲吼吼,喲吼吼..... 如何無(wú)痛降低 if else 面...

    NikoManiac 評(píng)論0 收藏0
  • 再談vue前進(jìn)刷新,后退刷新,include實(shí)現(xiàn)方法。

    摘要:并設(shè)置后退頁(yè)面數(shù)組。跳轉(zhuǎn)到或頁(yè)面,返回后回到緩存頁(yè)面,不刷新。由其他頁(yè)面進(jìn)入則刷新。反正目前可以實(shí)現(xiàn)想要的效果。 關(guān)于填坑vue的前進(jìn)刷新與后退不刷新,網(wǎng)上有很多方法,基本都是利用 keep-alive,但是試了好多種方法都不盡人意,后來(lái)有人提示說(shuō)基于keepalive include,試驗(yàn)了一下找到了些思路,暫時(shí)實(shí)驗(yàn)可行,分享下共同探討學(xué)習(xí),也許不是最佳解決方案,但確實(shí)有效。這里需要...

    layman 評(píng)論0 收藏0
  • 實(shí)現(xiàn)一個(gè)前端路由,如何實(shí)現(xiàn)瀏覽器的前進(jìn)后退 ?

    摘要:執(zhí)行過(guò)程如下實(shí)現(xiàn)瀏覽器的前進(jìn)后退第二個(gè)方法就是用兩個(gè)棧實(shí)現(xiàn)瀏覽器的前進(jìn)后退功能。我們使用兩個(gè)棧,和,我們把首次瀏覽的頁(yè)面依次壓入棧,當(dāng)點(diǎn)擊后退按鈕時(shí),再依次從棧中出棧,并將出棧的數(shù)據(jù)依次放入棧。 showImg(https://segmentfault.com/img/bVbtK6U?w=1280&h=910); 如果要你實(shí)現(xiàn)一個(gè)前端路由,應(yīng)該如何實(shí)現(xiàn)瀏覽器的前進(jìn)與后退 ? 2. 問(wèn)題...

    劉東 評(píng)論0 收藏0
  • 徹底理清前端頁(yè)面應(yīng)用(SPA)的實(shí)現(xiàn)原理 【精讀源碼】

    showImg(https://segmentfault.com/img/bVbvOmp?w=1612&h=888); 隨著React Vue前端框架的興起,出現(xiàn)了Vue-router,react-router-dom等前端路由管理庫(kù),利用他們構(gòu)建出來(lái)的單頁(yè)面應(yīng)用,也是越來(lái)越接近原生的體驗(yàn),再也不是以前的點(diǎn)擊標(biāo)簽跳轉(zhuǎn)頁(yè)面,刷新整個(gè)頁(yè)面了,那么他們的原理是什么呢? 優(yōu)質(zhì)gitHub開(kāi)源練手項(xiàng)目: ...

    xiaodao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<