vue+element-ui实现侧边菜单栏与标签页联动
使用vue+element-ui实现侧边栏菜单el-menu与el-tabs标签页联动效果先看实现效果实现思路el-menu使用vue-router的模式,以index进行路由跳转,当前激活菜单:default-active="$route.path",这样就会默认以当前路由路径高亮菜单选项,解决刷新等情况的高亮问题,主要代码<el-menu :default-active="$route.
·
使用vue+element-ui实现侧边栏菜单
el-menu
与el-tabs
标签页联动效果
先看实现效果
实现思路
el-menu
使用vue-router
的模式,以index进行路由跳转,当前激活菜单:default-active="$route.path"
,这样就会默认以当前路由路径高亮菜单选项,解决刷新等情况的高亮问题,主要代码
<el-menu :default-active="$route.path"
class="el-menu-vertical-demo"
background-color="#2f3640"
text-color="#fff"
:style="{width:asideBarWidth}"
:width="asideBarWidth"
:collapse="$store.state.isCollapse"
:unique-opened="true"
:router="true"
active-text-color="#409EFF">
<menu-item v-for="item in menuData"
:key="item.path"
:item="item" />
</el-menu>
el-tabs
的:value
(选中选项卡的name
)也是由$route.path
进行控制,el-tabs
的数据结构是这样的:[{title: '首页',path: '/home',name: 'Home'}]
(vuex管理),当点击的通过path进行路由跳转,删除时,如果是删除当前页,则需要获取下一个标签页的路径,再进行跳转。
<template>
<el-tabs type="card"
:value="$route.path"
@tab-click="tabClick"
closable
class="my-tabs"
@edit="handleTabsEdit">
<el-tab-pane :key="item.path"
v-for="(item) in tabsValue"
:label="item.title"
:name="item.path">
</el-tab-pane>
</el-tabs>
</template>
<script>
import { mapState } from 'vuex'
import { setSessionTabsValue } from '@/utils/storage'
export default {
name: 'TabsNav',
data () {
return {
}
},
created () {
},
watch: {
},
mounted () {
// 监听刷新,将数据保存到sessionStorage里
window.addEventListener('beforeunload', this.setStorage)
},
destroyed () {
window.removeEventListener('beforeunload', this.setStorage)
},
computed: {
...mapState({
tabsValue: state => state.tabsNav.tabsValue
})
},
methods: {
setStorage () {
console.log('setStorage')
setSessionTabsValue(this.tabsValue)
},
handleTabsEdit (targetPath, action) {
// 删除选项卡
if (action === 'remove') {
if (targetPath === '/home') return
let nextTab = {}
// 找到下一个路由
this.tabsValue.forEach((item, index) => {
if (item.path === targetPath) {
nextTab = this.tabsValue[index + 1] || this.tabsValue[index - 1]
}
})
this.$store.commit('REMOVE_TABS_VALUE', targetPath)
// 如果删除的是当前页,则进行跳转
targetPath === this.$route.path && this.$router.push(nextTab.path)
}
},
tabClick ({ name }) {
if (name === this.$route.path) return
this.$router.push(name)
}
}
}
</script>
- 使用
vuex
管理标签页的状态
import {
getSessionTabsValue
} from '@/utils/storage'
// 初始化
const initTabValue = getSessionTabsValue() || {
tabsValue: [{
title: '首页',
path: '/home',
name: 'Home'
}]
}
const tabsNav = {
state: () => (initTabValue),
mutations: {
/**
* 删除标签页
* @param {*} state
* @param {*} targetPath
*/
REMOVE_TABS_VALUE(state, targetPath) {
state.tabsValue = state.tabsValue.filter(item => item.path !== targetPath)
},
/**
* 添加标签页,在MenuItem组件触发
* @param {*} state
* @param {*} data
*/
ADD_TABS_VALUE(state, data) {
// 判断是否已经存在
const isExist = state.tabsValue.some(item => item.path === data.path)
// 如果不存在添加
if (!isExist) {
state.tabsValue.push(data)
}
},
/**
* 初始化数据,在注销时调用,不然切换用户后还是旧标签数据
* @param {*} state
*/
RESET_TABS_VALUE(state) {
state = initTabValue
}
},
actions: {},
getters: {}
}
export default tabsNav
- 监听路由跳转,即路由跳转时,判断是否使用标签页管理,如果是,再判断当前路由是否已经加入
tabsValue
(在mutations的ADD_TABS_VALUE判断)
// 路由对象数据结构
{
path: '/home',
name: 'Home',
component: Home,
meta: {
title: '首页',
isTabsPage: true
}
}
router.beforeEach((to, from, next) => {
if (to.meta.title) { // 如果设置标题,拦截后设置标题
document.title = to.meta.title
}
if (to.path !== '/login') {
if (!store.getters.isLogin) {
Message.error('请先登录')
next('/login')
return
}
// 判断是否需要添加到tabs标签
if (to.meta.isTabsPage) {
const tabsItem = {
name: to.name,
title: to.meta.title,
path: to.path
}
store.commit('ADD_TABS_VALUE', tabsItem)
}
}
next()
})
- 使用
keep-alive
对在标签页的页面进行缓存
<el-main>
<transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews">
<router-view></router-view>
</keep-alive>
</transition>
</el-main>
cachedViews () {
return this.$store.state.tabsNav.tabsValue.map(item => item.name)
}
这样就实现了上面的效果,但是还有许多地方可以优化,并且耦合性有点高…
更多推荐
已为社区贡献1条内容
所有评论(0)