Vue 動態控制某個組件的緩存

live example: https://cc.czcczc.cc/20180703/javascript

定義下角色html

列表頁:A.vue  能夠理解爲,後臺數據管理頁面的數據列表頁vue

編輯頁:B.vue  能夠理解爲,後臺數據管理頁面的單條數據編輯頁java

編輯選項頁:C.vue 能夠理解爲,由單條數據編輯頁跳轉到的一個單列表頁,選了以後帶參跳回B(自行腦補TB_APP中的選擇收貨地址)vue-router

先描述下需求,緩存

一、列表頁A,顯示N條數據項,單擊其中一項跳轉到編輯頁Bapp

二、固然,點擊A當中的不一樣數據項,B的呈現確定是不同的,A>B1>A>B2時候,B2頁面裏面不能顯示B1的內容(看到這裏,就以爲,不必設置緩存,對吧,且看下面)this

三、在編輯頁中,我須要觸發一個事件跳轉到C頁面,例如選擇收貨地址,選擇一個以後,跳回編輯頁面B,並傳遞選擇項的參數(如index)過來,頁面B根據傳遞過來的參數,進行頁面內容變化呈現。那麼必需要保證以前編輯頁的輸入項還存在(總不能選個收貨地址,填好的電話號碼姓名其餘信息都扔掉吧),也就是指望B1.1>B1.2>C>B1.3時候,不會出現B1.1>B1.2>C>B1.1,因此,編輯頁面B必須得緩存,spa

四、那麼,問題來了。    編輯頁面B要保證從A跳到B時候,B頁面都要從新加載,C回到A的時候,B顯示以前的頁面
 code

 

問題一個個解決,先解決第一個,

一、如何使用頁面緩存功能?

    1.1App.vue文件中必需要把<router-view>包裹起來
    1.2index.js中配置路由時候,設置路由meta屬性中的keepAlive子屬性爲true

走完這一步,全部的頁面都會被緩存,如今解決第二個問題

二、如何在B到C,而後C到B的時候,從C中把參數傳遞到B中

     詳見B.vue中設置監聽事件,以及C.vue中的emit動做。C中發指令,B中執行對應操做

走完這一步,會發現A>B>A>B>C>B時候,bus.on裏面對應的事件會觸發兩次,那麼

三、如何移除事件,確保不要重複註冊

    詳見B.vue中beforeDestroy事件,當頁面被移除時候,就移除該事件

如今就剩最後一步了。

四、如何確保A>B的時候,B都是從新加載?

    修改index.js中 A.vue中的meta.keepAlive = false

按理來講,應該在A跳到B以前。name:"B"的router的meta.keepAlive = false便可。可是後續第一次B>C>B的時候,頁面仍是從新加載了。可是按照上面設置就沒有問題了。感受這個需求是「誤打正着」「試錯」實現出來的

需求是實現了,那麼最後一個問題

五、4中的怪異現象究竟是爲何,你找出來了嗎?

<template>
  <div id="app">
//吐槽下,網上有個範例keepAlive寫的是keep-alive,很迷糊
    <keep-alive v-if="$route.meta.keepAlive">
      <router-view></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>

/router/index.js 注意註釋的地方,【注意這裏,整個教程這裏是最關鍵的地方】

import Vue from 'vue'
import Router from 'vue-router'
import A from '@/components/A'
import B from '@/components/B'
import C from '@/components/C'

Vue.use(Router)

export default new Router({
  routes: [{
      path: '/',
      redirect: {
        name: 'A'
      }
    },
    {
      path: '/A',
      name: 'A',
      component: A,
      meta: {
        keepAlive: false//【注意這裏,我設置的是!!!!false,整個教程這裏是最關鍵的】
      }
    },
    {
      path: '/B',
      name: 'B',
      component: B,
      meta: {
        keepAlive: true
      }
    },
    {
      path: '/C',
      name: 'C',
      component: C,
      meta: {
        keepAlive: true
      }
    }
  ]
})

 

A.vue

<template>
  <div class="hello">
    這是大列表頁
    <router-link :to="{name: 'B'}">到B</router-link>
  </div>
  
</template>

<script>
export default {
  name: "B",
  data() {
    return {};
  }
};
</script>

B.vue

<template>
  <div class="hello">
    這是詳情頁,裏面有一個input
    <div @click="bchange">{{myText}}</div>
    <router-link :to="{name: 'A'}">到A</router-link>
    <router-link :to="{name: 'C'}">到C</router-link>
  </div>
</template>

<script>
import bus from "../common/eventBus";
export default {
  name: "A",
  data() {
    return {
      myText: "點我變換"
    };
  },
  mounted: function() {//掛載的時候設置監聽
    var _this = this;
    console.log("B的監聽事件被註冊");
    bus.$on("C_Change_B", function(res) {
      console.log("接收到通知了", res);
      _this.myText = res;
    });
  },
  beforeDestroy() {//確保不會重複註冊該類型事件
    console.log("移除事件註冊");
    bus.$off("C_Change_B");
  },
  methods: {
    bchange() {
      this.myText = "點擊以後,B自身修改的";
    }
  }
};
</script>

C.vue

<template>
  <div class="hello">
    子列表頁,這邊點了,詳情頁就變了
    <div @click="change(1)">
      把輸入框的變成1
    </div>
    <div @click="change(2)">
      把輸入框的變成2
    </div>
    <div @click="change(3)">
      把輸入框的變成3
    </div>

  </div>
</template>

<script>
import bus from "../common/eventBus";
export default {
  name: "C",
  data() {
    return {};
  },
  methods: {
    change(res) {
      bus.$emit("C_Change_B", "C端提出修改的" + res);
      this.$router.go(-1)
    }
  }
};
</script>

common/eventBus.js

import Vue from 'vue';
export default new Vue();
相關文章
相關標籤/搜索