推薦一個摸手的大神:
https://github.com/PanJiaChen/vue-element-admin
思路:
在點擊跳轉時,記錄路由信息到state的一個數組里,
這個數組的數據被拿來渲染tagview,
同時對路由渲染處的router-view進行緩存(<keep-alive>)
剩下的就是對state路由數組的操作。
貼上關鍵代碼
home.vue
<template>
<el-container class="box">
<el-aside class="lef_nav_box" width="200px">
<leftNav></leftNav>
</el-aside>
<el-container>
<el-header>
<topHeader></topHeader>
</el-header>
<el-main v-if='isHome'>主頁喲</el-main>
<el-main v-if='!isHome'>
<crumbs class="mb20"></crumbs>
<tagViews></tagViews>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</el-main>
<el-footer>Footer</el-footer>
</el-container>
</el-container>
</template>
export default { components: { HelloWorld, leftNav, topHeader, tabNav, tagViews, crumbs }, data(){ return { isHome:true } }, created(){ this.routeIsHome(); }, methods:{ routeIsHome(){//首頁判斷 let self = this; let isHome = true; if(this.$route.meta.pageName =='首頁' && this.$route.meta.parentPageName ==''){ isHome = true }else{ isHome = false; } this.$nextTick(()=>{ self.isHome = isHome; }) } }, watch: { '$route' (to, from) { let self = this; let isHome = true; if(to.meta.pageName =='首頁' && to.meta.parentPageName ==''){ isHome = true; }else{ isHome = false; } this.$nextTick(()=>{ self.isHome = isHome; }) } } }
left.vue
<div v-if="item.children.length>0" v-for="(tmp,idx) in item.children"> <el-menu-item :index="(index+1)+'-'+idx"> <div @click="goPage(tmp.text,tmp.url)">{{tmp.text}}{{tmp.url}}</div> </el-menu-item> </div>
goPage(nameZh,nameE){
var obj = {
nameZh:nameZh,
nameE:nameE
}
this.$store.commit('addPageCache', obj);//記錄路由
this.$router.push('/'+nameE)//頁面跳轉
}
sotre.js
export default new Vuex.Store({
state: {
pageCache:[],//緩存路由,制作tag—view
curPage:'',//當前頁
crumbs:{firstPage:'首頁',parentPage:'',curPage:''}//面包屑
},
mutations: {
addPageCache(state,obj){//添加緩存頁面
let isTrue = state.pageCache.some((cur,index,arr)=>{
return cur['nameE'] && cur['nameE'] == obj['nameE'];//避免重復添加
})
if (isTrue) return;
state.pageCache.push({
nameE:obj.nameE,
nameZh:obj.nameZh,
paratNameZh:obj.paratNameZh
})
},
removePageCache(state,obj){//清除頁面緩存
var pageCache = state.pageCache.filter((cur,index,arr)=>{
if(cur['nameE'] && cur['nameE'] != obj['nameE']){
return cur;
}
})
if(pageCache.length != state.pageCache.length){//刪除成功
state.pageCache = pageCache;
if(pageCache.length > 0){//存在多的tagview情況下
obj.router.go(-1);
}
}
},
setCurPage(state,name){//設置當前頁
console.log(name)
state.curPage = name;
},
clearPageCache(state){//清空tagview
state.pageCache = [];
}
}
})
tag_view.vue
<template>
<ul class="tag_views" v-if="$store.state.pageCache.length>0">
<li :t="$store.state.curPage" :class="{active: $store.state.curPage == item.nameE }" v-for="(item,index) in $store.state.pageCache" @click.stop="goPage(item.nameZh,item.nameE)">
<div>{{item.nameZh}}<i class="el-icon-close" @click.stop="removeTab(item.nameZh,item.nameE)"></i></div>
</li>
</ul>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
goPage(nameZh,nameE){
this.$router.push('/'+nameE)
},
removeTab(nameZh,nameE){//移除tab
var obj = {
nameZh:nameZh,
nameE:nameE,
router:this.$router
}
this.$store.commit('removePageCache', obj);
}
}
}
</script>
router.js
//路由攔截器
router.beforeEach((to, from, next) => {
//根據字段判斷是否路由過濾
if(to.meta.requireAuth) { // 判斷該路由是否需要登錄權限
if(localStorage.getItem('sid')) { //身份信息獲取
if(to.meta.pageName =='首頁'){
router.app.$options.store.commit('clearPageCache');//清空tagview
}else if(to.name != ''){//顯示當前tagview
router.app.$options.store.commit('setCurPage',to.name);
}
next();
} else {
next({
path: '/login'
})
}
} else {
next();
}
});
下面是廢話(坑自己系列),可以跳過:
開始想的是用elementUI的tabs做這個東西。tabs有自定義刪除標簽頁的功能,點擊可以切換。那把頁面都渲染在tabs里進行切換,想干掉點小叉叉就好了,簡直完美。
於是渲染左側導航欄后,點擊時把需要的信息傳給state記錄,tabs通過拿state數據來渲染。
有個字段content:‘’即tab內容數據。改怎么把頁面渲染進去呢?
於是我給內容里放router-view ,然后加上name做成命名視圖。通過名字去匹配路由
在路由里一通配置,渲染時得到一條閃亮的字符串router-view。該如何讓它重新渲染呢?
網上搜來搜去有一個解決視圖不渲染的辦法,加一個動態key,那就加吧。
F5 F5 F5 CTRL+F5 F5 F5 F5 CTRL+F5 唉!!。
有人這么干成功過的私我QQ953708317
