vue+elementUI如何实现顶部路由标签跳转
作者:写Bug的大雄
这篇文章主要介绍了vue+elementUI如何实现顶部路由标签跳转问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
引言
后台管理系统中,为了方便使用者跳转已经访问过的页面,需要实现顶部路由标签跳转到访问过页面的功能,因此封装成组件方便使用
封装组件
<!-- TagsView/levelScroll.vue --> <template> <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll" > <slot /> </el-scrollbar> </template>
<script lang="ts"> import Vue from 'vue'; export default Vue.extend({ data () { return { left: 0 }; }, computed: { scrollWrapper () { return (this.$refs as any).scrollContainer.$refs.wrap; } }, methods: { // 鼠标滑动事件 handleScroll (e: { wheelDelta: number; deltaY: number }) { const eventDelta = e.wheelDelta || -e.deltaY * 40; const $scrollWrapper = this.scrollWrapper; $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4; } } }); </script>
<style lang="less" scoped> .scroll-container { white-space: nowrap; position: relative; overflow: hidden; width: 100%; /deep/.el-scrollbar__bar { bottom: 0px; } /deep/.el-scrollbar__wrap { height: 49px; // margin-bottom: -17px !important; // margin-right: -17px !important; } } </style>
vuex 文件
// modules/tagsView.ts const state = { // 访问过的页面标签 visitedViews: [ { path: '/dashboard/index', meta: { title: '首页', affix: true } } ], // 访问过的页面的 name 值 cachedViews: [] }; const mutations = { // 添加访问过的路由 ADD_VISITED_VIEW: (state: { visitedViews: any[] }, view: any) => { if (state.visitedViews.some((v) => v.path === view.path)) return; state.visitedViews.push( Object.assign({}, view, { title: view.meta.title }) ); }, // 添加访问过的路由 name ADD_CACHED_VIEW: (state: { cachedViews: any[] }, view: { name: string }) => { if (state.cachedViews.includes(view.name)) return; state.cachedViews.push(view.name); }, // 删除当前路由 DEL_VISITED_VIEW: ( state: { visitedViews: any[] }, view: { path: string } ) => { for (const [i, v] of state.visitedViews.entries()) { if (v.path === view.path) { state.visitedViews.splice(i, 1); break; } } }, // 删除当前路由 name DEL_CACHED_VIEW: (state: { cachedViews: any[] }, view: { name: string }) => { const index = state.cachedViews.indexOf(view.name); index > -1 && state.cachedViews.splice(index, 1); }, // 删除当前路由之外的路由 DEL_OTHERS_VISITED_VIEWS: ( state: { visitedViews: any[] }, view: { path: string } ) => { state.visitedViews = state.visitedViews.filter((v) => { return v.meta.affix || v.path === view.path; }); }, // 删除当前路由之外的路由 name DEL_OTHERS_CACHED_VIEWS: ( state: { cachedViews: any[] }, view: { name: string } ) => { const index = state.cachedViews.indexOf(view.name); if (index > -1) { state.cachedViews = state.cachedViews.slice(index, index + 1); } else { state.cachedViews = []; } }, // 删除全部访问过的路由 DEL_ALL_VISITED_VIEWS: (state: { visitedViews: any[] }) => { const affixTags = state.visitedViews.filter((tag) => tag.meta.affix); state.visitedViews = affixTags; }, // 删除全部访问过的路由 name DEL_ALL_CACHED_VIEWS: (state: { cachedViews: any[] }) => { state.cachedViews = []; } }; const actions = { // 添加访问过的路由 addVisitedView ({ commit }: { commit: any }, view: any) { commit('ADD_VISITED_VIEW', view); }, // 添加访问过的路由 name addCachedView ({ commit }: { commit: any }, view: any) { commit('ADD_CACHED_VIEW', view); }, addView ({ dispatch }: { dispatch: any }, view: any) { dispatch('addVisitedView', view); dispatch('addCachedView', view); }, // 删除当前路由 delVisitedView ({ commit }: { commit: any }, view: any) { commit('DEL_VISITED_VIEW', view); }, // 删除当前路由 name delCachedView ({ commit }: { commit: any }, view: any) { commit('DEL_CACHED_VIEW', view); }, delView ({ dispatch }: { dispatch: any }, view: any) { dispatch('delVisitedView', view); dispatch('delCachedView', view); }, // 删除当前路由之外的路由 delOthersVisitedViews ({ commit }: { commit: any }, view: any) { commit('DEL_OTHERS_VISITED_VIEWS', view); }, // 删除当前路由之外的路由 namw delOthersCachedViews ({ commit }: { commit: any }, view: any) { commit('DEL_OTHERS_CACHED_VIEWS', view); }, delOthersViews ({ dispatch }: { dispatch: any }, view: any) { dispatch('delOthersVisitedViews', view); dispatch('delOthersCachedViews', view); }, // 删除全部访问过的路由 delAllVisitedViews ({ commit }: { commit: any }) { commit('DEL_ALL_VISITED_VIEWS'); }, // 删除全部访问过的路由 name delAllCachedViews ({ commit }: { commit: any }) { commit('DEL_ALL_CACHED_VIEWS'); }, delAllViews ({ dispatch }: { dispatch: any }, view: any) { dispatch('delAllVisitedViews', view); dispatch('delAllCachedViews', view); } }; export default { namespaced: true, state, mutations, actions };
// getters.ts const getters = { // 访问的页面标签 visitedViews: (state: any) => state.tagsView.visitedViews, // 访问的页面标签 name cachedViews: (state: any) => state.tagsView.cachedViews }; export default getters;
router 文件
import Vue from 'vue'; import VueRouter from 'vue-router'; import Login from '@/views/login/index.vue'; import Layout from '@/layout/index.vue'; Vue.use(VueRouter); /** * hidden 表示是否需要在侧边导航栏出现 ,true表示不需要 * isFirst 表示是否只有一级权限,只出现在只有一个子集,没有其他孙子集 * 当权限拥有多个子集或者孙子集,一级权限需要加上 meta * 二级权限拥有子集,也必须有 meta */ // 基础路由 export const constantRoutes = [ { path: '/redirect', component: Layout, hidden: true, children: [ { path: '/redirect/:path(.*)', component: () => import('@/views/redirect/index.vue') } ] }, { path: '/', redirect: '/dashboard', hidden: true }, { path: '/login', name: 'Login', component: Login, hidden: true }, { path: '/dashboard', component: Layout, redirect: '/dashboard/index', isFirst: true, children: [ { path: 'index', name: 'Dashboard', component: () => import('@/views/dashboard/index.vue'), meta: { title: '首页', icon: 'el-icon-location' } } ] } ]; // 动态路由 export const asyncRoutes = [ { path: '/form', component: Layout, redirect: '/form/index', isFirst: true, children: [ { path: 'index', name: 'Form', component: () => import('@/views/form/index.vue'), meta: { title: '表单', role: 'form', icon: 'el-icon-location' } } ] }, { path: '/editor', component: Layout, redirect: '/editor/index', meta: { role: 'editors', title: '总富文本', icon: 'el-icon-location' }, children: [ { path: 'index', name: 'Editor', component: () => import('@/views/editor/index.vue'), meta: { title: '富文本', role: 'editor', icon: 'el-icon-location' } }, { path: 'two', name: 'Two', redirect: '/editor/two/three', component: () => import('@/views/editor/two.vue'), meta: { title: '二级导航', role: 'two', icon: 'el-icon-location' }, children: [ { path: 'three', name: 'Three', component: () => import('@/views/editor/three.vue'), meta: { title: '三级导航', role: 'three', icon: 'el-icon-location' } }, { path: 'four', name: 'Four', component: () => import('@/views/editor/four.vue'), meta: { title: '三级导航2', role: 'four', icon: 'el-icon-location' } } ] } ] }, { path: '/tree', component: Layout, redirect: '/tree/index', isFirst: true, children: [ { path: 'index', name: 'Tree', component: () => import('@/views/tree/index.vue'), meta: { title: '树状图', role: 'tree', icon: 'el-icon-location' } } ] }, { path: '/excel', component: Layout, redirect: '/excel/index', isFirst: true, children: [ { path: 'index', name: 'Excel', component: () => import('@/views/excel/index.vue'), meta: { title: '导入导出', role: 'excel', icon: 'el-icon-location' } } ] } ]; // 出错跳转的路由 export const error = [ // 404 { path: '/404', component: () => import('@/views/error/index.vue'), hidden: true }, { path: '*', redirect: '/404', hidden: true } ]; const createRouter = () => new VueRouter({ scrollBehavior: () => ({ x: 0, y: 0 }), routes: constantRoutes }); const router = createRouter(); // 刷新路由 export function resetRouter () { const newRouter = createRouter(); (router as any).matcher = (newRouter as any).matcher; } export default router;
页面中使用
<!-- 一般在主体布局页面使用 --> <template> <div class="layout"> ...... <el-container :class="{ hideSidebar: isCollapse }"> ...... <!-- 主体内容 --> <el-main> <!-- 访问过的路由标签 --> <tags-view></tags-view> <keep-alive :include="cachedViews"> <router-view :key="$route.path" /> </keep-alive> </el-main> </el-container> </div> </template> <script lang="ts"> import Vue from 'vue'; import { mapGetters } from 'vuex'; import SubMenu from '@/components/SubMenu/index.vue'; import MyBreadcrumb from '@/components/Breadcrumb/index.vue'; import TagsView from '@/components/TagsView/index.vue'; import { resetRouter } from '@/router'; export default Vue.extend({ computed: { // 路由 ...mapGetters(['cachedViews']) }, components: { TagsView } }); </script>
总结
参考网上资料进行封装修改,具体需求可根据项目修改
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。