diff --git a/src/icons/svg/link.svg b/src/icons/svg/link.svg new file mode 100644 index 0000000000000000000000000000000000000000..11037e6f64c22879d28451c65c0582c1754c1734 --- /dev/null +++ b/src/icons/svg/link.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1534846208920" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2941" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M912 1008.512H15.488V112h448.256v96H111.488v704.512H816V560.256h96z" p-id="2942"></path><path d="M918.208 37.888l67.904 67.904L545.984 545.92 478.08 478.08z" p-id="2943"></path><path d="M1007.168 310.656h-96V112h-208V16h304z" p-id="2944"></path></svg> \ No newline at end of file diff --git a/src/lang/en.js b/src/lang/en.js index d47b557fe47dd359a37cf9b5338254b7160acb85..52fe707deb3dc9b7145aee05f5ca952245afedb4 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -60,7 +60,8 @@ export default { exportZip: 'Export Zip', theme: 'Theme', clipboardDemo: 'Clipboard', - i18n: 'I18n' + i18n: 'I18n', + externalLink: 'External Link' }, navbar: { logOut: 'Log Out', diff --git a/src/lang/zh.js b/src/lang/zh.js index 7958b8797135f153e971056e982c631a965bcbef..ee182ec4ded82e80721f9d92f14e57eebbf2ced6 100644 --- a/src/lang/zh.js +++ b/src/lang/zh.js @@ -60,7 +60,8 @@ export default { exportZip: 'Export Zip', theme: 'æ¢è‚¤', clipboardDemo: 'Clipboard', - i18n: '国际化' + i18n: '国际化', + externalLink: '外链' }, navbar: { logOut: '退出登录', diff --git a/src/router/index.js b/src/router/index.js index 76a517c87c108c9bd385af5922b9cc4bf7039ef4..6c0c0f0d4968dd74b7b3876bea5b5db9a44e869f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -322,5 +322,16 @@ export const asyncRouterMap = [ ] }, + { + path: 'external-link', + component: Layout, + children: [ + { + path: 'https://github.com/PanJiaChen/vue-element-admin', + meta: { title: 'externalLink', icon: 'link' } + } + ] + }, + { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/views/layout/components/Sidebar/Item.vue b/src/views/layout/components/Sidebar/Item.vue new file mode 100644 index 0000000000000000000000000000000000000000..b515f6159a27862b595f645208ba71ea04ed110f --- /dev/null +++ b/src/views/layout/components/Sidebar/Item.vue @@ -0,0 +1,29 @@ +<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) { + vnodes.push(<svg-icon icon-class={icon}/>) + } + + if (title) { + vnodes.push(<span slot='title'>{(title)}</span>) + } + return vnodes + } +} +</script> diff --git a/src/views/layout/components/Sidebar/SidebarItem.vue b/src/views/layout/components/Sidebar/SidebarItem.vue index 30a22baf67d056f5d14163b8c59e53c830877e26..1a1d9514551b6a7dacc8cd44668adc51bb8124f7 100644 --- a/src/views/layout/components/Sidebar/SidebarItem.vue +++ b/src/views/layout/components/Sidebar/SidebarItem.vue @@ -1,17 +1,23 @@ <template> <div v-if="!item.hidden&&item.children" class="menu-wrapper"> - <router-link v-if="hasOneShowingChild(item.children) && !onlyOneChild.children&&!item.alwaysShow" :to="resolvePath(onlyOneChild.path)"> - <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> - <svg-icon v-if="onlyOneChild.meta&&onlyOneChild.meta.icon" :icon-class="onlyOneChild.meta.icon"/> - <span v-if="onlyOneChild.meta&&onlyOneChild.meta.title" slot="title">{{ generateTitle(onlyOneChild.meta.title) }}</span> - </el-menu-item> - </router-link> + <template v-if="hasOneShowingChild(item.children) && !onlyOneChild.children&&!item.alwaysShow"> + <a v-if="isExternalLink(onlyOneChild.path)" :href="onlyOneChild.path" target="blank"> + apple + <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> + <item v-if="onlyOneChild.meta" :icon="onlyOneChild.meta.icon" :title="generateTitle(onlyOneChild.meta.title)" /> + </el-menu-item> + </a> + <router-link v-else :to="resolvePath(onlyOneChild.path)"> + <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> + <item v-if="onlyOneChild.meta" :icon="onlyOneChild.meta.icon" :title="generateTitle(onlyOneChild.meta.title)" /> + </el-menu-item> + </router-link> + </template> <el-submenu v-else :index="item.name||item.path"> <template slot="title"> - <svg-icon v-if="item.meta&&item.meta.icon" :icon-class="item.meta.icon"/> - <span v-if="item.meta&&item.meta.title" slot="title">{{ generateTitle(item.meta.title) }}</span> + <item v-if="item.meta" :icon="item.meta.icon" :title="generateTitle(item.meta.title)" /> </template> <template v-for="child in item.children" v-if="!child.hidden"> @@ -19,8 +25,7 @@ <router-link v-else :to="resolvePath(child.path)" :key="child.name"> <el-menu-item :index="resolvePath(child.path)"> - <svg-icon v-if="child.meta&&child.meta.icon" :icon-class="child.meta.icon"/> - <span v-if="child.meta&&child.meta.title" slot="title">{{ generateTitle(child.meta.title) }}</span> + <item v-if="child.meta" :icon="child.meta.icon" :title="generateTitle(child.meta.title)" /> </el-menu-item> </router-link> </template> @@ -32,9 +37,12 @@ <script> import path from 'path' import { generateTitle } from '@/utils/i18n' +import { validateURL } from '@/utils/validate' +import Item from './Item' export default { name: 'SidebarItem', + components: { Item }, props: { // route object item: { @@ -71,11 +79,13 @@ export default { } return false }, - resolvePath(...paths) { - return path.resolve(this.basePath, ...paths) + resolvePath(routePath) { + return path.resolve(this.basePath, routePath) + }, + isExternalLink(routePath) { + return validateURL(routePath) }, generateTitle } } </script> -