我的编程空间,编程开发者的网络收藏夹
学习永远不晚

element-ui侧边栏router问题怎么解决

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

element-ui侧边栏router问题怎么解决

这篇文章主要介绍了element-ui侧边栏router问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇element-ui侧边栏router问题怎么解决文章都会有所收获,下面我们一起来看看吧。

element-ui 侧边栏的router

element-ui侧边栏router问题怎么解决

所以就动态获取api里面的path值作为其router就行。注意带上上级路由。用字符串拼接的方式::index="'/home/' 

对二级导航栏,这里的item是 v-for循环上级的item.children(一级导航栏)的项。

<el-menu-item :index="'/home/' + item.path"></el-menu-item>

element-ui中侧边栏的分析及实现

el-menu 和 el-submenu

如果需要实现一个侧边栏,会如何设计?

侧边栏的核心是将根据权限过滤后的 router 和 el-menu 组件进行映射,所以 el-menu 和 el-submenu 是理解 sidebar 的基础。

el-menu 表示菜单容器组件,如下所示:

  • default-active:当前激活菜单的 index,注意如果存在子菜单,需要填入子菜单 ID

  • unique-opened 是否只保持一个子菜单的展开

  • mode 模式,枚举值,horizontal / vertical 这两种

  • collapse 是否水平折叠收起菜单(仅在 mode 为 vertical 时可用)

  • collapse-transition 是否开启折叠动画

  • @select 点击菜单事件,菜单激活回调 index: 选中菜单项的 index, indexPath: 选中菜单项的 index path

  • @open: sub-menu 展开的回调

  • @close: sub-menu 收起的回调

el-submenu,子菜单容器,el-menu 表示整个菜单, el-submenu 表示一个具体菜单,只是该菜单还包括了子菜单。 el-submenu 可以通过定制 slot 的 title 来自定义菜单模式。el-submenu 容器内 default 的 slot 用来存放子菜单,可以包括三种子菜单组件,如下所示:

  • el-menu-item-group:菜单分组,为一组菜单添加一个标题,容器内需要存放 el-menu-item,支持通过 title 的 slot 来定制标题样式

  • el-submenu:支持循环嵌套 el-submenu,可以使得超过两级子组件得以实现

  • el-menu-item:子菜单组件

示例代码,如下所示:

<el-row class="tac">  <el-col :span="12">    <h6>默认颜色</h6>    <el-menu      default-active="2"      class="el-menu-vertical-demo"      @open="handleOpen"      @close="handleClose">      <el-submenu index="1">        <template slot="title">          <i class="el-icon-location"></i>          <span>导航一</span>        </template>        <el-menu-item-group>          <template slot="title">分组一</template>          <el-menu-item index="1-1">选项1</el-menu-item>          <el-menu-item index="1-2">选项2</el-menu-item>        </el-menu-item-group>        <el-menu-item-group title="分组2">          <el-menu-item index="1-3">选项3</el-menu-item>        </el-menu-item-group>        <el-submenu index="1-4">          <template slot="title">选项4</template>          <el-menu-item index="1-4-1">选项1</el-menu-item>        </el-submenu>      </el-submenu>      <el-menu-item index="2">        <i class="el-icon-menu"></i>        <span slot="title">导航二</span>      </el-menu-item>      <el-menu-item index="3" disabled>        <i class="el-icon-document"></i>        <span slot="title">导航三</span>      </el-menu-item>      <el-menu-item index="4">        <i class="el-icon-setting"></i>        <span slot="title">导航四</span>      </el-menu-item>    </el-menu>  </el-col>  <el-col :span="12">    <h6>自定义颜色</h6>    <el-menu      default-active="2"      class="el-menu-vertical-demo"      @open="handleOpen"      @close="handleClose"      background-color="#545c64"      text-color="#fff"      active-text-color="#ffd04b">      <el-submenu index="1">        <template slot="title">          <i class="el-icon-location"></i>          <span>导航一</span>        </template>        <el-menu-item-group>          <template slot="title">分组一</template>          <el-menu-item index="1-1">选项1</el-menu-item>          <el-menu-item index="1-2">选项2</el-menu-item>        </el-menu-item-group>        <el-menu-item-group title="分组2">          <el-menu-item index="1-3">选项3</el-menu-item>        </el-menu-item-group>        <el-submenu index="1-4">          <template slot="title">选项4</template>          <el-menu-item index="1-4-1">选项1</el-menu-item>        </el-submenu>      </el-submenu>      <el-menu-item index="2">        <i class="el-icon-menu"></i>        <span slot="title">导航二</span>      </el-menu-item>      <el-menu-item index="3" disabled>        <i class="el-icon-document"></i>        <span slot="title">导航三</span>      </el-menu-item>      <el-menu-item index="4">        <i class="el-icon-setting"></i>        <span slot="title">导航四</span>      </el-menu-item>    </el-menu>  </el-col></el-row>
<script>  export default {    methods: {      handleOpen(key, keyPath) {        console.log(key, keyPath);      },      handleClose(key, keyPath) {        console.log(key, keyPath);      }    }  }</script>

sidebar 分析

sidebar,如下所示:

  • activeMenu:通过 meta.activeMenu 属性,指定路由对应的高亮菜单,meta.activeMenu 需要提供一个合法的路由,否则不能生效。

  • isCollapse:NavBar 中点击按钮,会修改 Cookie 中的 sidebarStatus,从 vuex 取值时会将 sidebarStatus 转为 Boolean,并判断默认是否需要收缩左侧菜单栏

  • showLogo:判断 settings.js 中的配置项是否需要展示 logo

  • variables:从 @style/variables.css 中获取 scss 对象,从而获取样式

sidebar,代码实现如下:

<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"      >        <sidebar-item v-for="route in permission_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 {  components: { SidebarItem, Logo },  computed: {    ...mapGetters([      'permission_routes',      'sidebar'    ]),    activeMenu() {      const route = this.$route      const { meta, path } = route      if (meta.activeMenu) {        return meta.activeMenu      }      return path    },    showLogo() {      return this.$store.state.settings.sidebarLogo    },    variables() {      return variables    },    isCollapse() {      return !this.sidebar.opened    }  }}</script>

sidebar 中通过 sidebar -item 实现子菜单,sidebar-item 的 props 是 item 为路由对象,basePath 是路由路径。sidebar-item 的展示逻辑,如下所示:

通过 item.hidden 控制菜单是否展示

通过 hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow 逻辑判断 template 菜单是否展示,template 代表单一菜单,如下所示:

  • hasOneShowingChild:判断是否只有一个需要展示的子路由

  • !onlyOneChild.children||onlyOneChild.noShowingChildren: 判断需要展示的子菜单,是否包含 children 属性,如果包含,则说明子菜单可能存在孙子菜单,此时需要再判断 noShowingChildren 属性

  • !item.alwaysShow:判断路由中是否存在 alwaysShow 属性,如何存在,则返回 false,不展示 template 菜单,也就是只要配置了 alwaysShow 属性就会直接进入 el-submenu 组件

对于 hasOneShowingChild 方法,children 是 router 对象的 children 属性,item 是 router 对象,代码如下所示:

hasOneShowingChild(children = [], parent) {  const showingChildren = children.filter(item => {    // 如果 children 中的路由包含 hidden 属性,则返回 false    if (item.hidden) {      return false    } else {      // 将子路由赋值给 onlyOneChild,用于只包含一个路由时展示      this.onlyOneChild = item      return true    }  })  // 如果过滤后,只包含展示一个路由,则返回 true  if (showingChildren.length === 1) {    return true  }  // 如果没有子路由需要展示,则将 onlyOneChild 的 push 设置空路由,并添加 noShowingChildren  if (showingChildren.length === 0) {    this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }    return true  }  // 返回 false,表示不需要展示子路由,或者超过 需要展示的子路由  return false}

对于它们之间的关系,如下所示:

如果展示 template 组件,首先会展示 app-link 组件,然后是 el-menu-item,最里面嵌套的是 item 组件。item 组件需要 meta 中包含 title 和 icon 属性,否则将渲染内容为空的 vnode 对象。

如果 template 菜单不展示,则展示 el-submenu 菜单,el-submenu 逻辑中采用了嵌套组件的做法,将 sidebar-item 嵌套在 el-submenu 中

el-submenu 中的 sidebar-item 的区别,第一个是传入 is-nest 参数,第二个是传入 base-path 参数

sidebar-item,代码如下所示:

<template>  <div v-if="!item.hidden">    <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">        <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">          <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />        </el-menu-item>      </app-link>    </template>    <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>      <template slot="title">        <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />      </template>      <sidebar-item        v-for="child in item.children"        :key="child.path"        :is-nest="true"        :item="child"        :base-path="resolvePath(child.path)"        class="nest-menu"      />    </el-submenu>  </div></template>
<script>import path from 'path'import { isExternal } from '@/utils/validate'import Item from './Item'import AppLink from './Link'import FixiOSBug from './FixiOSBug'export default {  name: 'SidebarItem',  components: { Item, AppLink },  mixins: [FixiOSBug],  props: {    // route object    item: {      type: Object,      required: true    },    isNest: {      type: Boolean,      default: false    },    basePath: {      type: String,      default: ''    }  },  data() {    this.onlyOneChild = null    return {}  },  methods: {    hasOneShowingChild(children = [], parent) {      const showingChildren = children.filter(item => {        // 如果 children 中的路由包含 hidden 属性,则返回 false        if (item.hidden) {          return false        } else {          // 将子路由赋值给 onlyOneChild,用于只包含一个路由时展示          this.onlyOneChild = item          return true        }      })      // 如果过滤后,只包含展示一个路由,则返回 true      if (showingChildren.length === 1) {        return true      }      // 如果没有子路由需要展示,则将 onlyOneChild 的 push 设置空路由,并添加 noShowingChildren      if (showingChildren.length === 0) {        this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }        return true      }      // 返回 false,表示不需要展示子路由,或者超过 需要展示的子路由      return false    },    resolvePath(routePath) {      if (isExternal(routePath)) {        return routePath      }      if (isExternal(this.basePath)) {        return this.basePath      }      return path.resolve(this.basePath, routePath)    }  }}</script>

app-link,是一个动态组件,通过 to 参数,如果包含 http 前缀则变成一个 a 标签,否则变成一个 router-link 组件。

app-link,代码如下所示:

<template>  <component :is="type" v-bind="linkProps(to)">    <slot />  </component></template>
<script>import { isExternal } from '@/utils/validate'export default {  props: {    to: {      type: String,      required: true    }  },  computed: {    isExternal() {      return isExternal(this.to)    },    type() {      if (this.isExternal) {        return 'a'      }      return 'router-link'    }  },  methods: {    linkProps(to) {      if (this.isExternal) {        return {          href: to,          target: '_blank',          rel: 'noopener'        }      }      return {        to: to      }    }  }}</script>

item 组件,通过定义的 render 函数完成组件渲染。

10item,代码如下所示:

<script>export default {  name: 'MenuItem',  functional: true,  props: {    icon: {      type: String,      default: ''    },    title: {      type: String,      default: ''    }  },  render(h, context) {    const { icon, title } = context.props    const vnodes = []    if (icon) {      if (icon.includes('el-icon')) {        vnodes.push(<i class={[icon, 'sub-el-icon']} />)      } else {        vnodes.push(<svg-icon icon-class={icon}/>)      }    }    if (title) {      vnodes.push(<span slot='title'>{(title)}</span>)    }    return vnodes  }}</script>
<style scoped>.sub-el-icon {  color: currentColor;  width: 1em;  height: 1em;}</style>

侧边栏实现总结

sidebar 主要包括 el-menu 容器组件,el-menu 中遍历 vuex 中的 routes,生成 sidebar-item 组件。sidebar 主要配置如下所示:

  • activeMenu:根据当前路由的 meta.activeMenu 属性控制侧边栏中高亮菜单

  • isCollapse:根据 Cookie 的 sidebarStatus 控制侧边栏是否折叠

  • variables:通过 @style/variables.css 填充 el-menu 的基本样式

sidebar-item,分为两个部分,如下所示:

第一部分是当只需要展示一个 children 或者没有 children 时进行展示,展示的组件包括:

  • app-link:动态组件,path 为链接时,显示为 a 标签,path 为路由时,显示为 router-link 组件

  • el-menu-item:菜单项,当 sidebar-item 为非 nest 组件时,el-menu-item 会增加 submenu-title-noDropdown 的 class

  • item:el-menu-item 里的内容,主要是 icon 和 title,当 title 为空时,整个菜单项将不会展示

第二部分是当 children 超过两项时进行展示,展示的组件包括:

el-submenu:子菜单组件容器,用于嵌套子菜单组件

sidebar-item:el-submen 迭代嵌套了 sidebar-item 组件,在 sidebar-item 组件中的变化,设置了 is-nest 属性为 true,根据 child.path 生成了 base-path 属性传入 sidebar-item 组件

关于“element-ui侧边栏router问题怎么解决”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“element-ui侧边栏router问题怎么解决”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

element-ui侧边栏router问题怎么解决

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

element-ui侧边栏router问题怎么解决

这篇文章主要介绍了element-ui侧边栏router问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇element-ui侧边栏router问题怎么解决文章都会有所收获,下面我们一起来看看吧。ele
2023-06-30

element-ui中样式覆盖问题怎么解决

今天小编给大家分享一下element-ui中样式覆盖问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。! impor
2023-07-05

element-ui select多选绑定回显值问题怎么解决

本篇内容主要讲解“element-ui select多选绑定回显值问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“element-ui select多选绑定回显值问题怎么解决”吧!el
2023-07-05

Vue router应用问题怎么解决

这篇文章主要讲解了“Vue router应用问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue router应用问题怎么解决”吧!问题记录路由守卫的应用根据路由守卫绑定的位置不
2023-06-30

element-ui使用el-upload,before-upload函数不好使问题怎么解决

这篇文章主要介绍了element-ui使用el-upload,before-upload函数不好使问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇element-ui使用el-upload,befor
2023-07-05

vue-router的beforeRouteUpdate不触发问题怎么解决

这篇文章主要介绍“vue-router的beforeRouteUpdate不触发问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue-router的beforeRouteUpdate不触
2023-06-30

vue-router怎么解决相同路径跳转报错问题

这篇“vue-router怎么解决相同路径跳转报错问题”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“vue-router怎么
2023-07-05

element select必填项验证回显问题怎么解决

本文小编为大家详细介绍“element select必填项验证回显问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“element select必填项验证回显问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来
2023-07-05

基于element UI input组件自行封装数字区间输入框组件的问题怎么解决

今天小编给大家分享一下基于element UI input组件自行封装数字区间输入框组件的问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下
2023-06-30

element中form组件prop嵌套属性问题怎么解决

本篇内容介绍了“element中form组件prop嵌套属性问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Introductio
2023-06-29

android整数二分模板怎么解决边界问题

本篇内容主要讲解“android整数二分模板怎么解决边界问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“android整数二分模板怎么解决边界问题”吧!1.区间 //区间分为[l,mid]和[
2023-06-22

vue路由组件vue-router实例被复用问题怎么解决

本文小编为大家详细介绍“vue路由组件vue-router实例被复用问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue路由组件vue-router实例被复用问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一
2023-07-02

Element组件beforeUpload上传前限制失效问题怎么解决

本篇内容介绍了“Element组件beforeUpload上传前限制失效问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Eleme
2023-07-05

怎么解决win10底部任务栏无响应的问题

今天就跟大家聊聊有关怎么解决win10底部任务栏无响应的问题,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。解决方法如下:方法一:1、按下“ctrl+alt+delete”键,打开任务
2023-06-05

Win11任务栏太宽了怎么办?一招解决Win11任务栏太宽问题

相信有不少小伙伴都优先体验了Windows11系统,而Windows11确实非常好看。但是不少用户都觉得Windows11的任务栏非常的大,想要调整任务栏的大小又不知道怎么调整,这要怎么办呢?下面小编就带着大家www.cppcns.com一
2023-05-23

vue3与webpack5安装element-plus样式webpack编译报错问题怎么解决

本篇内容主要讲解“vue3与webpack5安装element-plus样式webpack编译报错问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue3与webpack5安装elem
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录