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();