• ruoyi菜单折叠,菜单收缩


      问题描述

    VUE菜单有一个BUG,当我们点击其它按钮或者首页的时候,已经展示的一级菜单是不会自动收缩的。这个问题也导致很多开发者把一级菜单都换成了二级菜单。

    错误展示

    错误的效果请看下图。

     解决方法

    1、寻找菜单文件

    因为我使用的是ruoyi的前端框架,所以菜单文件的路径是src/layout/components/Sidebar/index.vue文件,如果大家使用的是其他的框架或者自己写的去全局搜索关键字【el-menu】就能找到菜单页面。文件路径如下图

    2、添加以下代码

    1. // el-menu菜单中添加ref和open事件
    2. <el-menu ref="menu" @open="handleOpen">el-menu>
    3. data() {
    4. return {
    5. // 记录用户上次点击的菜单索引
    6. keyIndex:0,
    7. };
    8. },
    9. watch: {
    10. $route () {
    11. // 监控用户点击的菜单,如果是首页或者个人详情页面都要把上次打开的页面收缩起来。
    12. if (this.$route.path === '/index' ||this.$route.path === "/user/profile") {
    13. this.$refs.menu.close(this.keyIndex);
    14. }
    15. }
    16. },
    17. methods: {
    18. handleOpen (key) {
    19. this.keyIndex = key;
    20. }
    21. },

     3、完整的代码

    1. <template>
    2. <div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
    3. <logo v-if="showLogo" :collapse="isCollapse" />
    4. <el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
    5. <el-menu
    6. ref="menu"
    7. @open="handleOpen"
    8. :default-active="activeMenu"
    9. :collapse="isCollapse"
    10. :background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
    11. :text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
    12. :unique-opened="true"
    13. :active-text-color="settings.theme"
    14. :collapse-transition="false"
    15. mode="vertical"
    16. >
    17. <sidebar-item
    18. v-for="(route, index) in sidebarRouters"
    19. :key="route.path + index"
    20. :item="route"
    21. :base-path="route.path"
    22. />
    23. el-menu>
    24. el-scrollbar>
    25. div>
    26. template>
    27. <script>
    28. import { mapGetters, mapState } from "vuex";
    29. import Logo from "./Logo";
    30. import SidebarItem from "./SidebarItem";
    31. import variables from "@/assets/styles/variables.scss";
    32. export default {
    33. components: { SidebarItem, Logo },
    34. data() {
    35. return {
    36. keyIndex:0,
    37. };
    38. },
    39. watch: {
    40. $route () {
    41. if (this.$route.path === '/index' ||this.$route.path === "/user/profile") {
    42. this.$refs.menu.close(this.keyIndex);
    43. }
    44. }
    45. },
    46. methods: {
    47. handleOpen (key) {
    48. this.keyIndex = key;
    49. }
    50. },
    51. computed: {
    52. ...mapState(["settings"]),
    53. ...mapGetters(["sidebarRouters", "sidebar"]),
    54. activeMenu() {
    55. const route = this.$route;
    56. const { meta, path } = route;
    57. // if set path, the sidebar will highlight the path you set
    58. if (meta.activeMenu) {
    59. return meta.activeMenu;
    60. }
    61. return path;
    62. },
    63. showLogo() {
    64. return this.$store.state.settings.sidebarLogo;
    65. },
    66. variables() {
    67. return variables;
    68. },
    69. isCollapse() {
    70. return !this.sidebar.opened;
    71. }
    72. }
    73. };
    74. script>

    4、修改后的效果

    5、到此功能完成


    -----华丽的分割线,以下是凑字数,大家不用花时间看,快去改代码-----

    -----华丽的分割线,以下是凑字数,大家不用花时间看,快去改代码-----

    -----华丽的分割线,以下是凑字数,大家不用花时间看,快去改代码-----

    1. <template>
    2. <div v-if="!item.hidden">
    3. <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
    4. <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
    5. <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
    6. <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="$t(onlyOneChild.meta.title)" />
    7. el-menu-item>
    8. app-link>
    9. template>
    10. <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
    11. <template slot="title">
    12. <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
    13. template>
    14. <sidebar-item
    15. v-for="child in item.children"
    16. :key="child.path"
    17. :is-nest="true"
    18. :item="child"
    19. :base-path="resolvePath(child.path)"
    20. class="nest-menu"
    21. />
    22. el-submenu>
    23. div>
    24. template>
    25. <script>
    26. import path from 'path'
    27. import { isExternal } from '@/utils/validate'
    28. import Item from './Item'
    29. import AppLink from './Link'
    30. import FixiOSBug from './FixiOSBug'
    31. export default {
    32. name: 'SidebarItem',
    33. components: { Item, AppLink },
    34. mixins: [FixiOSBug],
    35. props: {
    36. // route object
    37. item: {
    38. type: Object,
    39. required: true
    40. },
    41. isNest: {
    42. type: Boolean,
    43. default: false
    44. },
    45. basePath: {
    46. type: String,
    47. default: ''
    48. }
    49. },
    50. data() {
    51. this.onlyOneChild = null
    52. return {}
    53. },
    54. methods: {
    55. hasOneShowingChild(children = [], parent) {
    56. if (!children) {
    57. children = [];
    58. }
    59. const showingChildren = children.filter(item => {
    60. if (item.hidden) {
    61. return false
    62. } else {
    63. // Temp set(will be used if only has one showing child)
    64. this.onlyOneChild = item
    65. return true
    66. }
    67. })
    68. // When there is only one child router, the child router is displayed by default
    69. if (showingChildren.length === 1) {
    70. return true
    71. }
    72. // Show parent if there are no child router to display
    73. if (showingChildren.length === 0) {
    74. this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
    75. return true
    76. }
    77. return false
    78. },
    79. resolvePath(routePath, routeQuery) {
    80. if (isExternal(routePath)) {
    81. return routePath
    82. }
    83. if (isExternal(this.basePath)) {
    84. return this.basePath
    85. }
    86. if (routeQuery) {
    87. let query = JSON.parse(routeQuery);
    88. return { path: path.resolve(this.basePath, routePath), query: query }
    89. }
    90. return path.resolve(this.basePath, routePath)
    91. }
    92. }
    93. }
    94. script>

  • 相关阅读:
    GitHub 已霸榜!阿里技术官肝了 3 个月才完成的 20 万字 Java 面试手册
    MySQL字符集设置、密码管理
    计算机毕业设计ssm基于java网上心理咨询系统50fxl系统+程序+源码+lw+远程部署
    【2022国赛模拟】[SDSC Day5] 毒药——自适应交互、DP
    老弟手把手教你编译Spark3.2.1源码!!!!!
    LeetCode刷题--思路总结记录
    餐厅预订APP有哪些?餐厅预订APP怎么选择?
    《PyTorch深度学习实践》第十二课(循环神经网络RNN)
    C#实现图片对比-支持图片旋转
    【大学生痛苦版】
  • 原文地址:https://blog.csdn.net/renkai721/article/details/133163480