会使用到Vue中的 provide/inject
1、首先在父组件设置 provide
<template> <div :class="classObj" class="app-wrapper"> <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> <!-- 顶部导航栏 --> <top-nav ref="topNavContainer" :style="{background:theme}" class="top-nav-container" @openTheme="openThemeHandler" /> <!-- 底部容器(左侧菜单栏+右侧内容) --> <div class="page-content-container clearfix"> <sidebar class="sidebar-container" /> <div :class="{hasTagsView:needTagsView}" class="main-container"> <div :class="{'fixed-header':fixedHeader}"> <!-- 隐藏全局导航栏 --> <!--<navbar />--> <tags-view v-if="needTagsView" /> </div> <app-main v-if="isRouterAlive" /> <!-- 回到顶部 --> <el-backtop target=".main-container"> <div class="my-backtop">UP</div> </el-backtop> <!-- --> <right-panel :is-show="isOpenTheme" @close="isOpenTheme = false"> <settings /> </right-panel> </div> </div> </div> </template> <script> import RightPanel from '@/components/RightPanel' import { AppMain, Navbar, Settings, Sidebar, TagsView, TopNav } from './components' import ResizeMixin from './mixin/ResizeHandler' import { mapState } from 'vuex' export default { name: 'Layout', components: { AppMain, Navbar, RightPanel, Settings, Sidebar, TagsView, TopNav }, mixins: [ResizeMixin], computed: { ...mapState({ sidebar: state => state.app.sidebar, device: state => state.app.device, showSettings: state => state.settings.showSettings, needTagsView: state => state.settings.tagsView, fixedHeader: state => state.settings.fixedHeader, theme: state => state.settings.theme }), classObj() { return { hideSidebar: !this.sidebar.opened, openSidebar: this.sidebar.opened, withoutAnimation: this.sidebar.withoutAnimation, mobile: this.device === 'mobile' } } }, data() { return { activeIndex2: '1', isOpenTheme: false, isRouterAlive: true } }, created() { }, provide() { return { reload: this.reload } }, methods: { reload() { this.isRouterAlive = false this.$nextTick(() => { this.isRouterAlive = true }) }, openThemeHandler() { console.log('打开主题') this.isOpenTheme = true }, handleClickOutside() { this.$store.dispatch('app/closeSideBar', { withoutAnimation: false }) }, handleSelect(key, keyPath) { console.log(key, keyPath) } } } </script> <style lang="scss" scoped> @import "~@/styles/mixin.scss"; @import "~@/styles/variables.scss"; .app-wrapper { @include clearfix; position: relative; height: 100%; width: 100%; &.mobile.openSidebar { position: fixed; top: 0; } .page-content-container { height: calc(100% - 50px); .my-backtop { height: 100%; width: 100%; background-color: #f2f5f6; box-shadow: 0 0 6px rgba(0,0,0, .12); text-align: center; line-height: 40px; color: #1989fa; } } } .drawer-bg { background: #000; opacity: 0.3; width: 100%; top: 0; height: 100%; position: absolute; z-index: 999; } .fixed-header { position: fixed; top: 50px; right: 0; z-index: 9; width: calc(100% - #{$sideBarWidth}); transition: width 0.28s; box-shadow: 0 2px 4px rgb(0 0 0 / 12%), 0 0 6px rgb(0 0 0 / 4%); } .hideSidebar .fixed-header { width: calc(100% - 54px) } .mobile .fixed-header { width: 100%; } </style>
然后再子组件中调用父组件中的reload函数
<template> <div :class="{'has-logo':showLogo}"> <!-- <logo v-if="showLogo" :collapse="isCollapse" />--> <el-scrollbar wrap-class="scrollbar-wrapper"> <!-- :default-openeds="['/example','/nested']" // 添加本行代码表示默认展开的菜单 :background-color="variables.menuBg" :text-color="variables.menuText" :active-text-color="variables.menuActiveText" $route.fullPath :default-active="activeMenu" --> <el-menu :default-active="activeMenu" :collapse="isCollapse" :unique-opened="true" :background-color="variables.menuBg" :text-color="variables.menuText" :collapse-transition="false" mode="vertical" router @select="handleSelect" > <!-- :key="route.path" --> <sidebar-item v-for="route in permissionRoutes.children" :key="'/'+permissionRoutes.path+'/'+route.path" :item="route" :base-path="'/'+permissionRoutes.path+'/'+route.path" /> <!--一级菜单 --> <!-- <el-submenu v-for="(item,index) in permissionRoutes.children" :key="index" :index="index+''">--> <!-- <!– 一级菜单模板 –>--> <!-- <template slot="title">--> <!-- <!– 一级菜单图标 –>--> <!-- <svg-icon class-name="search-icon" :icon-class="item.icon" />--> <!-- <!– 一级菜单标题 –>--> <!-- <span v-text="item.authName" />--> <!-- </template>--> <!-- <!–--> <!-- 二级菜单--> <!-- /campus/mechanism/base--> <!-- :index="'/'+childrenTtem.path" 表示以服务器返回的path 为 路由跳转路径--> <!-- 例如:childrenTtem.path 的值为 user, 然后加上 '/' 即为跳转路径--> <!-- –>--> <!-- <el-menu-item v-for="(childrenTtem,childrenIndex) in item.children" :key="childrenIndex" :index="'/'+permissionRoutes.path+'/'+item.path+'/'+childrenTtem.path">--> <!-- <!– 二级菜单模板 –>--> <!-- <template slot="title">--> <!-- <!– 二级菜单图标 –>--> <!-- <i class="el-icon-menu" />--> <!-- <!– 二级菜单标题 –>--> <!-- <span v-text="childrenTtem.authName" />--> <!-- </template>--> <!-- </el-menu-item>--> <!-- </el-submenu>--> <!--<div v-for="(menuItem,index) in permissionRoutes.children" :key="index"> <!– 一级菜单 –> <el-submenu v-if="menuItem.children.length>1" :index="index+''"> <!– 一级菜单模板 –> <template slot="title"> <!– 一级菜单图标 –> <svg-icon class-name="search-icon" :icon-class="menuItem.icon" /> <!– 一级菜单标题 –> <span v-text="menuItem.authName" /> </template> <!– 二级菜单 /campus/mechanism/base :index="'/'+childrenTtem.path" 表示以服务器返回的path 为 路由跳转路径 例如:childrenTtem.path 的值为 user, 然后加上 '/' 即为跳转路径 –> <el-menu-item v-for="(childrenTtem,childrenIndex) in menuItem.children" :key="childrenIndex" :index="'/'+permissionRoutes.path+'/'+menuItem.path+'/'+childrenTtem.path"> <!– 二级菜单模板 –> <template slot="title"> <!– 二级菜单图标 –> <i class="el-icon-menu" /> <!– 二级菜单标题 –> <span v-text="childrenTtem.authName" /> </template> </el-menu-item> </el-submenu> </div>--> </el-menu> </el-scrollbar> </div> </template> <script> import { mapGetters } from 'vuex' import Logo from './Logo' import SidebarItem from './SidebarItem' import variables from '@/styles/variables.scss' export default { components: { SidebarItem, Logo }, inject: ['reload'], computed: { ...mapGetters([ 'permission_routes', 'sidebar', 'permissionRoutes' ]), activeMenu() { const route = this.$route const { meta, path } = route console.log('Sidebar-meta', meta) console.log('Sidebar-path', path) // 如果设置路径,侧边栏将突出显示您设置的路径 if (meta.activeMenu) { return meta.activeMenu } return path }, showLogo() { return this.$store.state.settings.sidebarLogo }, variables() { return variables }, isCollapse() { return !this.sidebar.opened } }, watch: { $route(route) { console.log('Sidebar--', route) } }, created() { console.log('Sidebar-this.permission_routes', this.permission_routes) console.log('Sidebar-this.permissionRoutes', this.permissionRoutes) }, mounted() { }, methods: { handleSelect(key, keyPath) { const route = this.$route const { path } = route if (key === path) { this.reload() } } } } </script>