vue-element-admin layout组件解析【Sidebar】

> index.vue

<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: {// 获取vuex中getter中的属性的值...mapGetters(['permission_routes','sidebar']),// 活动菜单activeMenu() {// 获取当前路由对象const route = this.$route// 获取meta对象 和路径对象const { meta, path } = route// 如果设置路径,侧边栏将突出显示您设置的路径if (meta.activeMenu) {return meta.activeMenu}return path},// 显示logoshowLogo() {return this.$store.state.settings.sidebarLogo},// scss颜色变量variables() {return variables},// 是否关闭侧边栏isCollapse() {return !this.sidebar.opened}}
}
script>

> Item.vue

<script>
export default {name: 'MenuItem',functional: true,props: {// 图标icon: {type: String,default: ''},// 标题头title: {type: String,default: ''}},render(h, context) {// 获取参数对象const { icon, title } = context.propsconst vnodes = []if (icon) {// 判断图标是否element-ui中的图标if (icon.includes('el-icon')) {// 使用i标签添加图标vnodes.push(<i class={[icon, 'sub-el-icon']} />)} else {// 不是element-ui直接添加外部icon路径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>

> SidebarItem.vue

<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-itemv-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' // 迭代icon与title
import AppLink from './Link' // 应用关联 用于切换外部链接显示方法
import FixiOSBug from './FixiOSBug' // 用于修复IOS设备鼠标离开bugexport 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() {// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237// TODO: 渲染函数重构this.onlyOneChild = nullreturn {}},methods: {// 有一个子路由hasOneShowingChild(children = [], parent) {const showingChildren = children.filter(item => {if (item.hidden) {return false} else {// Temp set(will be used if only has one showing child)// 临时设置(如果只有一个子路显示子路由并使用)this.onlyOneChild = itemreturn true}})// 当只有一个子路由器时,默认显示子路由器if (showingChildren.length === 1) {return true}// 如果没有要显示的子路由器,则显示父级if (showingChildren.length === 0) {this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }return true}return false},// 解析路径resolvePath(routePath) {// 判断是否是外部的路径if (isExternal(routePath)) {return routePath}if (isExternal(this.basePath)) {return this.basePath}// 返回当前也解析好的路径return path.resolve(this.basePath, routePath)}}
}
script>

> Link.vue

<template><component :is="type" v-bind="linkProps(to)"><slot />component>
template><script>
import { isExternal } from '@/utils/validate' // 判断是否是外部pathexport default {props: {to: {type: String,required: true}},computed: {// 判断是否是外部路径httpsisExternal() {return isExternal(this.to)},type() {// 是外部HTTPS返回a标签if (this.isExternal) {return 'a'}// 是本地路径返回一个router-link,它最终会被渲染成一个a标签return 'router-link'}},methods: {// 链接方法linkProps(to) {// 判断是否是外部HTTPS路径if (this.isExternal) {return {// 链接地址href: to,target: '_blank',rel: 'noopener'}}// 不是外部路径直接返回return {to: to}}}
}
script>

> FixiOSBug.js

export default {computed: {// 获取应用设备device() {return this.$store.state.app.device}},mounted() {// In order to fix the click on menu on the ios device will trigger the mouseleave bug// 为了修复ios设备上点击菜单会触发鼠标离开的bug// https://github.com/PanJiaChen/vue-element-admin/issues/1135this.fixBugIniOS()},methods: {// 修复IOSbug函数fixBugIniOS() {// 获取子菜单对象const $subMenu = this.$refs.subMenuif ($subMenu) {// 处理鼠标离开const handleMouseleave = $subMenu.handleMouseleave$subMenu.handleMouseleave = (e) => {if (this.device === 'mobile') {return}handleMouseleave(e)}}}}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部