vue-element-admin clicks on the sidebar to refresh the current page
Write the directory title here
- Vue-element-admin clicks on the sidebar to refresh the current page
-
- foreword
- 1. Refresh the entire routing page
- 2. Only refresh the nested routing page
Foreword
Before using the spa (single-page application) development model, users would re-request this page every time they clicked on the sidebar. Users gradually developed the habit of clicking the current route on the sidebar to refresh the view Habit. But now the spa is different, the user clicks the currently highlighted route and will not refresh the view, because vue-router will intercept your route, it judges that your url has not changed, so it will not trigger any hooks or view changes.
(Reference article: vue-elemnt-admin documentation)
1. Refresh the entire routing page
Use $nextTick and v-if to refresh the current route after clicking
Configure the corresponding configuration in the app.vue file, configure v-if and refresh method
<template> <div id="app"> <router-view v-if="isRouterAlive" /> </div> </template> <script> export default {<!-- --> name: 'App', provide() {<!-- --> return {<!-- --> reload: this.reload }; }, data() {<!-- --> return {<!-- --> isRouterAlive: true }; }, methods: {<!-- --> reload() {<!-- --> console.log('Trigger reload function') this.isRouterAlive = false; this.$nextTick(function () {<!-- --> this.isRouterAlive = true; }); } } } </script>
Then in the src/layout/components/sidebar/index.vue folder, we first receive the function, then check whether there is a change according to the routing address, and call the reload refresh function if there is a change.
<template> <div :class="{ 'has-logo': showLogo }"> <logo v-if="showLogo" :collapse="isCollapse" /> <el-scrollbar wrap-class="scrollbar-wrapper"> <el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="variables.menuBg" :text-color="variables.menuText" :unique-opened="false" :active-text-color="variables.menuActiveText" :collapse-transition="false" mode="vertical" @select="handleSelect"> <sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" /> </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 {<!-- --> inject: ['reload'], components: {<!-- --> SidebarItem, Logo }, computed: {<!-- --> ...mapGetters([ 'sidebar' ]), routes() {<!-- --> return this.$router.options.routes }, activeMenu() {<!-- --> const route = this. $route const {<!-- --> meta, path } = route // if set path, the sidebar will highlight the path you set if (meta. activeMenu) {<!-- --> return meta. activeMenu } return path }, showLogo() {<!-- --> return this.$store.state.settings.sidebarLogo }, variables() {<!-- --> return variables }, isCollapse() {<!-- --> return !this.sidebar.opened } }, methods: {<!-- --> handleSelect(index) {<!-- --> console. log(index) const route = this. $route const {<!-- --> path } = route if (index === path) {<!-- --> this. reload() } } } } </script>
2. Only refresh the nested routing page
The logic is roughly the same. You only need to change the reload and v-if judgments to the nested routing vue file.
The main file path of the nested route is src/layout/index.vue
<template> <div :class="classObj" class="app-wrapper"> <div v-if="device === 'mobile' & amp; & amp; sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> <sidebar class="sidebar-container" /> <div class="main-container"> <div :class="{ 'fixed-header': fixedHeader }"> <navbar /> </div> <app-main v-if="isRouterAlive" /> </div> </div> </template> <script> import {<!-- --> Navbar, Sidebar, AppMain } from './components' import ResizeMixin from './mixin/ResizeHandler' export default {<!-- --> name: 'Layout', components: {<!-- --> Navbar, Sidebar, AppMain }, provide() {<!-- --> return {<!-- --> reloadMain: this.reloadMain }; }, data() {<!-- --> return {<!-- --> isRouterAlive: true }; }, mixins: [ResizeMixin], computed: {<!-- --> sidebar() {<!-- --> return this.$store.state.app.sidebar }, device() {<!-- --> return this.$store.state.app.device }, fixedHeader() {<!-- --> return this.$store.state.settings.fixedHeader }, classObj() {<!-- --> return {<!-- --> hideSidebar: !this.sidebar.opened, openSidebar: this.sidebar.opened, withoutAnimation: this.sidebar.withoutAnimation, mobile: this.device === 'mobile' } } }, methods: {<!-- --> handleClickOutside() {<!-- --> this.$store.dispatch('app/closeSideBar', {<!-- --> withoutAnimation: false }) }, reloadMain() {<!-- --> this.isRouterAlive = false; this.$nextTick(function () {<!-- --> this.isRouterAlive = true; }); } } } </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; } } .drawer-bg {<!-- --> background: #000; opacity: 0.3; width: 100%; top: 0; height: 100%; position: absolute; z-index: 999; } .fixed-header {<!-- --> position: fixed; top: 0; right: 0; z-index: 9; width: calc(100% - #{<!-- -->$sideBarWidth}); transition: width 0.28s; } .hideSidebar .fixed-header {<!-- --> width: calc(100% - 54px) } .mobile.fixed-header {<!-- --> width: 100%; } </style>