qdt-admin-layout 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -0
  3. package/package.json +45 -0
  4. package/src/component/Aside/DefaultSidebar/index.vue +354 -0
  5. package/src/component/Aside/DefaultSidebar/style.scss +32 -0
  6. package/src/component/Aside/index.vue +30 -0
  7. package/src/component/Aside/style.scss +23 -0
  8. package/src/component/Aside/theme-dark.scss +19 -0
  9. package/src/component/Aside/theme-light.scss +18 -0
  10. package/src/component/Breadcrumb/index.vue +111 -0
  11. package/src/component/Breadcrumb/style.scss +27 -0
  12. package/src/component/CachedRouterView/index.vue +162 -0
  13. package/src/component/ContextMenu/functionalUse.js +26 -0
  14. package/src/component/ContextMenu/index.vue +140 -0
  15. package/src/component/ContextMenu/style.scss +30 -0
  16. package/src/component/ElMenu/item.vue +66 -0
  17. package/src/component/ElMenu/mixin.js +36 -0
  18. package/src/component/ElMenu/sub.vue +118 -0
  19. package/src/component/Hamburger/index.vue +27 -0
  20. package/src/component/Hamburger/style.scss +3 -0
  21. package/src/component/Header/index.vue +131 -0
  22. package/src/component/Header/style.scss +74 -0
  23. package/src/component/Header/theme-dark.scss +31 -0
  24. package/src/component/Header/theme-light.scss +15 -0
  25. package/src/component/HorizontalResizableMenu/GhostMenu.vue +101 -0
  26. package/src/component/HorizontalResizableMenu/index.vue +280 -0
  27. package/src/component/HorizontalScroller/index.vue +91 -0
  28. package/src/component/HorizontalScroller/style.scss +12 -0
  29. package/src/component/Layout/index.vue +153 -0
  30. package/src/component/Layout/style.scss +42 -0
  31. package/src/component/LoadingSpinner/index.vue +17 -0
  32. package/src/component/Logo/index.vue +41 -0
  33. package/src/component/Logo/style.scss +26 -0
  34. package/src/component/NavMenu/index.vue +206 -0
  35. package/src/component/NavMenu/style.scss +159 -0
  36. package/src/component/NavMenu/theme-dark.scss +59 -0
  37. package/src/component/NavMenu/theme-light.scss +81 -0
  38. package/src/component/Page/content.vue +58 -0
  39. package/src/component/Page/iframe.vue +63 -0
  40. package/src/component/Page/index.vue +22 -0
  41. package/src/component/Page/style.scss +48 -0
  42. package/src/component/Redirect/index.vue +19 -0
  43. package/src/component/TagsView/index.vue +255 -0
  44. package/src/component/TagsView/style.scss +51 -0
  45. package/src/component/TagsView/util.js +67 -0
  46. package/src/config/const.js +24 -0
  47. package/src/config/defaultRoute.js +23 -0
  48. package/src/config/index.js +4 -0
  49. package/src/config/logic.js +53 -0
  50. package/src/helper.js +43 -0
  51. package/src/index.js +15 -0
  52. package/src/mixin/menu.js +72 -0
  53. package/src/store/app.js +132 -0
  54. package/src/store/aside.js +92 -0
  55. package/src/store/header.js +37 -0
  56. package/src/store/index.js +20 -0
  57. package/src/store/page.js +67 -0
  58. package/src/store/tagsView.js +186 -0
  59. package/src/store/util.js +35 -0
  60. package/src/style/index.scss +23 -0
  61. package/src/style/maxViewHeight.scss +65 -0
  62. package/src/style/transition.scss +71 -0
  63. package/src/style/var.scss +81 -0
  64. package/src/util.js +69 -0
  65. package/types/config.d.ts +12 -0
  66. package/types/helper.d.ts +10 -0
  67. package/types/index.d.ts +5 -0
  68. package/types/menu.d.ts +17 -0
  69. package/types/route.d.ts +15 -0
  70. package/types/store.d.ts +156 -0
  71. package/types/vue-router.d.ts +7 -0
@@ -0,0 +1,255 @@
1
+ <script>
2
+ /**
3
+ * 页签栏
4
+ */
5
+
6
+ import {
7
+ appGetters,
8
+ pageGetters,
9
+ pageMutations,
10
+ tagsViewGetters,
11
+ tagsViewMutations
12
+ } from '../../store'
13
+ import useContextMenu from '../../component/ContextMenu/functionalUse'
14
+ import HorizontalScroller from '../../component/HorizontalScroller'
15
+ import { refreshPage } from '../../helper'
16
+ import { getRouterKey, getRouterTitle, isRedirectRouter } from '../../config/logic'
17
+ import { isAffix, getAffixTagsFromMenuTree, renderDefaultStyleTag } from './util'
18
+
19
+ export default {
20
+ name: 'TagsView',
21
+
22
+ data() {
23
+ return {
24
+ // 当前激活的页签的key,随路由变化
25
+ activeKey: '',
26
+
27
+ // 当前选中的页签
28
+ selectedTag: undefined,
29
+
30
+ // 页签右键菜单的属性
31
+ contextMenu: {
32
+ show: false,
33
+ top: 0,
34
+ left: 0
35
+ }
36
+ }
37
+ },
38
+
39
+ computed: {
40
+ contextMenuItems() {
41
+ const { visitedViews } = tagsViewGetters
42
+ const closeable = visitedViews.length > 1 && !isAffix(this.selectedTag)
43
+
44
+ return [
45
+ { content: '刷新', click: this.refreshSelectedTag },
46
+ { content: closeable && '关闭', click: this.closeSelectedTag },
47
+ { content: '关闭其他', click: this.closeOthersTags },
48
+ { content: '关闭全部', click: this.closeAllTags }
49
+ ].filter(i => i.content)
50
+ },
51
+
52
+ // 避免HorizontalScroller在右键时触发$forceUpdate
53
+ // https://segmentfault.com/q/1010000040171066
54
+ tagsSlot() {
55
+ return this._u([{
56
+ key: 'default',
57
+ fn: this.renderTags,
58
+ proxy: true
59
+ }])
60
+ }
61
+ },
62
+
63
+ watch: {
64
+ $route(to, from) {
65
+ tagsViewGetters.enableChangeTransition && this.decideRouteTransition(to, from)
66
+
67
+ // 如果是刷新的话,不需要进行后续操作
68
+ if (isRedirectRouter(to)) return
69
+
70
+ this.setActiveKey(to)
71
+ this.addTag(to)
72
+ this.$nextTick(this.moveToCurrentTag)
73
+ }
74
+ },
75
+
76
+ methods: {
77
+ /**
78
+ * 根据路由设置当前激活的页签key
79
+ * @param route {import('vue-router').Route}
80
+ */
81
+ setActiveKey(route) {
82
+ this.activeKey = getRouterKey(route)
83
+ },
84
+
85
+ /**
86
+ * 根据访问的tab页的左右顺序来确定路由动画
87
+ * @param to {import('vue-router').Route}
88
+ * @param from {import('vue-router').Route}
89
+ */
90
+ decideRouteTransition(to, from) {
91
+ const { next, prev } = pageGetters.transition
92
+ const { visitedViews } = tagsViewGetters
93
+ const fromKey = getRouterKey(from)
94
+ const toKey = getRouterKey(to)
95
+
96
+ // 这里认为页签数量不会太多,所以为了可读性使用两次循环查找
97
+ const fromIndex = visitedViews.findIndex(i => i.key === fromKey)
98
+ const toIndex = visitedViews.findIndex(i => i.key === toKey)
99
+
100
+ let transitionName = prev
101
+
102
+ // 新开tab也认为顺序高于上一个tab
103
+ if (toIndex === -1 || fromIndex < toIndex) {
104
+ transitionName = next
105
+ }
106
+
107
+ pageMutations.transition({ curr: transitionName })
108
+ },
109
+
110
+ // 初始化固定显示的页签
111
+ initTags() {
112
+ // TODO 如果页签栏初始化后菜单未加载,则固定页签会出问题
113
+ // 添加所有固定显示的页签
114
+ getAffixTagsFromMenuTree(this.$router, appGetters.menus).forEach(tagsViewMutations.addTagOnly)
115
+
116
+ // 将当前路由对象添加为页签
117
+ this.addTag(this.$route)
118
+ },
119
+ /**
120
+ * 尝试将路由对象添加为tab页
121
+ * @param route {import('vue-router').Route}
122
+ */
123
+ addTag(route) {
124
+ tagsViewMutations.addTagAndCache({
125
+ ...route,
126
+ meta: {
127
+ ...route.meta,
128
+ title: getRouterTitle(route)
129
+ }
130
+ })
131
+ },
132
+ // 横向滚动条移动至当前tab
133
+ moveToCurrentTag() {
134
+ const { scroller } = this.$refs
135
+ const cur =
136
+ Array
137
+ .from(scroller.$el.children)
138
+ .find(el => el.classList.contains('active'))
139
+ cur && scroller.moveToTarget(cur)
140
+ },
141
+ /**
142
+ * 激活末尾页签
143
+ * @param refresh {boolean=} 目标路由是当前路由时是否需要刷新
144
+ * @return {Promise<Route>}
145
+ */
146
+ gotoLastTag(refresh = false) {
147
+ const views = tagsViewGetters.visitedViews
148
+ const router = this.$router
149
+
150
+ if (views.length === 0) {
151
+ return router.push('/')
152
+ }
153
+
154
+ const latest = views[views.length - 1]
155
+
156
+ // 目标路由是当前路由时需要刷新,否则直接跳转
157
+ this.activeKey === latest.key
158
+ ? refresh && refreshPage(router)
159
+ // 需要套一层$nextTick,否则tagsViewStore.visitedViews可能只会变动一次
160
+ : this.$nextTick(() => router.push(latest))
161
+ },
162
+
163
+ /**
164
+ * 刷新所选页签
165
+ * @param view {View}
166
+ */
167
+ refreshSelectedTag(view = this.selectedTag) {
168
+ refreshPage(this.$router, view)
169
+ },
170
+ /**
171
+ * 关闭所选页签
172
+ * @param view {VisitedView}
173
+ */
174
+ closeSelectedTag(view = this.selectedTag) {
175
+ if (tagsViewGetters.visitedViews.length <= 1 || isAffix(view)) return
176
+
177
+ tagsViewMutations.delTagAndCache(view)
178
+ this.activeKey === view.key && this.gotoLastTag()
179
+ },
180
+ // 关闭除激活、固定页签以外的所有页签
181
+ closeOthersTags() {
182
+ tagsViewMutations.delOtherTagAndCache(this.selectedTag)
183
+ this.gotoLastTag()
184
+ },
185
+ // 关闭除固定页签以外的所有页签
186
+ closeAllTags() {
187
+ tagsViewMutations.delAllTagAndCache()
188
+ this.gotoLastTag(true)
189
+ },
190
+ /**
191
+ * 在页签上打开右键菜单
192
+ * @param tag {VisitedView}
193
+ * @param e {MouseEvent}
194
+ */
195
+ openContextMenu(tag, e) {
196
+ e.preventDefault()
197
+
198
+ // 销毁之前的右键菜单实例
199
+ this.$contextmenu && this.$contextmenu()
200
+
201
+ this.selectedTag = tag
202
+
203
+ this.$contextmenu = useContextMenu(this.contextMenuItems, {
204
+ left: e.clientX + 15,
205
+ top: e.clientY + 5
206
+ })
207
+ },
208
+
209
+ renderTags() {
210
+ const { $createElement: h, $router, activeKey } = this
211
+ const { itemSlot, visitedViews } = tagsViewGetters
212
+ const renderFn = itemSlot || renderDefaultStyleTag
213
+
214
+ return visitedViews.map(view => {
215
+ const active = activeKey === view.key
216
+ const showClose = !isAffix(view) && visitedViews.length > 1
217
+ const on = {
218
+ contextmenu: e => this.openContextMenu(view, e)
219
+ }
220
+ const onClose = e => {
221
+ // 需要阻止事件冒泡,不然会触发tag的click事件
222
+ e.stopPropagation()
223
+ this.closeSelectedTag(view)
224
+ }
225
+
226
+ // 非激活页签时,绑定点击事件,点击跳转到页签对应的路由
227
+ if (!active) {
228
+ on.click = () => $router.push(view, () => undefined)
229
+ }
230
+
231
+ return renderFn(h, {
232
+ key: view.key,
233
+ active,
234
+ on,
235
+ title: view.meta.title,
236
+ close: showClose && onClose
237
+ })
238
+ })
239
+ }
240
+ },
241
+
242
+ mounted() {
243
+ this.setActiveKey(this.$route)
244
+ this.initTags()
245
+ },
246
+
247
+ render() {
248
+ return (
249
+ <nav class="tags-view">
250
+ <HorizontalScroller ref="scroller" scopedSlots={this.tagsSlot}/>
251
+ </nav>
252
+ )
253
+ }
254
+ }
255
+ </script>
@@ -0,0 +1,51 @@
1
+ .tags-view {
2
+ height: $tags-view-height;
3
+ background-color: $tags-view-background-color;
4
+ box-shadow: $tags-view-shadow;
5
+ overflow: hidden;
6
+
7
+ &-item {
8
+ display: flex;
9
+ align-items: center;
10
+ flex-shrink: 0;
11
+ border: $tags-view-item-border;
12
+ border-radius: $tags-view-item-border-radius;
13
+ padding: $tags-view-item-padding;
14
+ margin: $tags-view-item-between / 2;
15
+ font-size: $tags-view-item-font-size;
16
+ color: $--color-text-secondary;
17
+ background-color: $--color-white;
18
+ box-sizing: border-box;
19
+ user-select: none;
20
+ cursor: pointer;
21
+
22
+ &:first-of-type {
23
+ margin-left: $tags-view-item-between;
24
+ }
25
+
26
+ &:last-of-type {
27
+ margin-right: $tags-view-item-between;
28
+ }
29
+
30
+ &.active {
31
+ color: $--color-primary;
32
+
33
+ .tags-view-item__dot {
34
+ background-color: $--color-primary;
35
+ }
36
+ }
37
+
38
+ &__dot {
39
+ background-color: #e8eaec;
40
+ width: $tags-view-item-font-size;
41
+ height: $tags-view-item-font-size;
42
+ border-radius: 50%;
43
+ margin-right: .5em;
44
+ }
45
+
46
+ .el-icon-close {
47
+ font-size: $tags-view-item-font-size + 2;
48
+ margin-left: 1em;
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,67 @@
1
+ import { getRouterTitle } from '../../config/logic'
2
+
3
+ /**
4
+ * 判断页签是否固定
5
+ *
6
+ * @param view {View}
7
+ * @return {boolean} 是固定页签则返回true,否则false
8
+ */
9
+ export function isAffix(view) {
10
+ return view ? view.meta.affix : false
11
+ }
12
+
13
+ /**
14
+ * 从菜单树中获取所有需要固定显示的页签
15
+ *
16
+ * @param router {VueRouter} - 路由实例
17
+ * @param menus {StoreMenuItem[]} - appStore中的菜单
18
+ * @return {View[]}
19
+ */
20
+ export function getAffixTagsFromMenuTree(router, menus) {
21
+ return menus.reduce((affixTags, menu) => {
22
+ const { fullPath, children, meta } = menu
23
+
24
+ if (meta.affix === true) {
25
+ const { route } = router.resolve(fullPath)
26
+
27
+ affixTags.push({
28
+ ...route,
29
+ meta: {
30
+ affix: true,
31
+ ...route.meta,
32
+ title: getRouterTitle(route)
33
+ }
34
+ })
35
+ }
36
+
37
+ if (children) {
38
+ const tempTags = getAffixTagsFromMenuTree(router, children)
39
+ tempTags.length && affixTags.push(...tempTags)
40
+ }
41
+
42
+ return affixTags
43
+ }, [])
44
+ }
45
+
46
+ /**
47
+ * 渲染默认样式的页签
48
+ *
49
+ * @param h {import('vue').CreateElement} - 渲染函数
50
+ * @param key {string} - vnode的key值
51
+ * @param active {boolean=} - 是否激活
52
+ * @param on {{[k:string]:function}?} - 绑定的事件监听器
53
+ * @param title {string} - 页签文字
54
+ * @param close {function?} - 点击关闭按钮时触发的函数
55
+ * @return {import('vue').VNode}
56
+ */
57
+ export function renderDefaultStyleTag(h, { key, active = false, on, title, close }) {
58
+ const className = `tags-view-item${active ? ' active' : ''}`
59
+
60
+ return (
61
+ <div key={key} class={className} {...{ on }}>
62
+ <div class="tags-view-item__dot"/>
63
+ <span>{title}</span>
64
+ {close && <i class="el-icon-close" on-click={close}/>}
65
+ </div>
66
+ )
67
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 一些可修改的常量
3
+ */
4
+
5
+ export default {
6
+ /**
7
+ * 移动端的最大宽度
8
+ * 默认为scss中的$max-mobile-width变量
9
+ * 该值的变动并不能影响样式,需要同时修改$max-mobile-width或覆盖相关样式
10
+ */
11
+ maxMobileWidth: 500,
12
+
13
+ /**
14
+ * redirect的路径名
15
+ * 如果需要修改,则需要在injectDefaultRoute执行前修改
16
+ */
17
+ redirectPath: '/redirect',
18
+
19
+ /**
20
+ * 是否开启Layout组件的插槽功能
21
+ * 关闭后只能通过store使用render方式来自定义渲染内容,不过可以提高一丢丢性能
22
+ */
23
+ enableLayoutSlot: true
24
+ }
@@ -0,0 +1,23 @@
1
+ import Const from './const'
2
+ import Redirect from '../component/Redirect'
3
+
4
+ /**
5
+ * 注入默认的路由
6
+ *
7
+ * @param layout 你的layout组件
8
+ * @returns {array}
9
+ */
10
+ export function injectDefaultRoute(layout) {
11
+ return [
12
+ {
13
+ path: Const.redirectPath,
14
+ component: layout,
15
+ children: [
16
+ {
17
+ path: '*',
18
+ component: Redirect
19
+ }
20
+ ]
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,4 @@
1
+ import Const from './const'
2
+ import { injectDefaultRoute } from './defaultRoute'
3
+
4
+ export { Const, injectDefaultRoute }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * 一些可能后续会修改的公用逻辑
3
+ */
4
+
5
+ import Const from './const'
6
+
7
+ /**
8
+ * 获取每个路由对应的唯一key
9
+ * @param route {Route}
10
+ * @returns {string}
11
+ */
12
+ export function getRouterKey(route) {
13
+ const { name, path, fullPath, meta: { usePathKey, useFullPathKey } = {} } = route
14
+ return usePathKey
15
+ ? path
16
+ : useFullPathKey
17
+ ? fullPath
18
+ : name || fullPath
19
+ }
20
+
21
+ /**
22
+ * 获取路由标题
23
+ * @param route {Route}
24
+ * @returns {string}
25
+ */
26
+ export function getRouterTitle(route) {
27
+ const { title, dynamicTitle } = route.meta || {}
28
+
29
+ return typeof dynamicTitle === 'function'
30
+ ? dynamicTitle(route) || title
31
+ : title
32
+ }
33
+
34
+ /**
35
+ * 获取路由对应的激活菜单index
36
+ * @param route {Route}
37
+ * @returns {string}
38
+ */
39
+ export function getRouterActiveMenu(route) {
40
+ const { path, meta: { activeMenu } = {} } = route
41
+
42
+ return activeMenu || path
43
+ }
44
+
45
+ /**
46
+ * 判断路由是否为redirect路由,是则返回true
47
+ * @param route {Route}
48
+ * @returns {boolean}
49
+ */
50
+ export function isRedirectRouter(route) {
51
+ const [first] = route.matched
52
+ return first && first.path === Const.redirectPath
53
+ }
package/src/helper.js ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 为避免循环依赖拆分出来的工具类
3
+ */
4
+
5
+ import { Const } from './config'
6
+ import { tagsViewMutations } from './store'
7
+
8
+ /**
9
+ * 根据宽度判断是否为移动端,是则返回true
10
+ *
11
+ * @return {boolean}
12
+ */
13
+ export function isMobile() {
14
+ return window.innerWidth <= Const.maxMobileWidth
15
+ }
16
+
17
+ /**
18
+ * 路由刷新
19
+ *
20
+ * @param router vue-router实例
21
+ * @param route 需要刷新的路由对象,默认为当前路由
22
+ * @param replace {boolean} 是否使用replace进行跳转
23
+ * @return {Promise} 返回vue-router跳转的结果
24
+ */
25
+ export function refreshPage(router, route = router.currentRoute, replace = true) {
26
+ tagsViewMutations.delCacheOnly(route)
27
+ const to = `${Const.redirectPath}${route.fullPath}`
28
+ return router[replace ? 'replace' : 'push'](to)
29
+ }
30
+
31
+ /**
32
+ * 关闭当前页,如果传入next则跳转到next页面
33
+ *
34
+ * @param router vue-router实例
35
+ * @param next {string|route} 跳转的目标页面,作为第一个参数传入vue-router.replace
36
+ * @return {undefined|Promise} 仅在next有值时,返回vue-router.replace的结果
37
+ */
38
+ export function closeCurrentPage(router, next) {
39
+ tagsViewMutations.delTagAndCache(router.currentRoute)
40
+ if (next) {
41
+ return router.replace(next)
42
+ }
43
+ }
package/src/index.js ADDED
@@ -0,0 +1,15 @@
1
+ import Layout from './component/Layout'
2
+ import Breadcrumb from './component/Breadcrumb'
3
+ import ContextMenu from './component/ContextMenu'
4
+ import Hamburger from './component/Hamburger'
5
+ import HorizontalResizableMenu from './component/HorizontalResizableMenu'
6
+ import Logo from './component/Logo'
7
+ import NavMenu from './component/NavMenu'
8
+
9
+ export default Layout
10
+ export { Breadcrumb, ContextMenu, Hamburger, HorizontalResizableMenu, Logo, NavMenu }
11
+
12
+ export * from './config'
13
+ export * from './store'
14
+
15
+ export { refreshPage, closeCurrentPage } from './helper'
@@ -0,0 +1,72 @@
1
+ /**
2
+ * 顶部菜单和侧边栏菜单的公共混入
3
+ */
4
+ import { refreshPage } from '../helper'
5
+ import { getRouterKey } from '../config/logic'
6
+
7
+ export default {
8
+ data() {
9
+ return {
10
+ // 当前激活的菜单的fullPath
11
+ // 之所以手动维护是因为el-menu在点击后就会设置activeIndex
12
+ activeMenu: '',
13
+
14
+ // 传递给nav-menu,只会在activeMenu第一次变化时变化
15
+ defaultActive: ''
16
+ }
17
+ },
18
+
19
+ methods: {
20
+ // 点击菜单后的动作
21
+ actionOnSelectMenu(menuIndex, refreshWhenSame = true) {
22
+ // 外部链接时打开新窗口
23
+ if (menuIndex.startsWith('http')) {
24
+ window.open(menuIndex)
25
+ return this.resetActiveMenu()
26
+ }
27
+
28
+ const { route } = this.$router.resolve(menuIndex)
29
+
30
+ if (route.matched.length === 0) {
31
+ console.warn(`点击菜单时出错,'${menuIndex}'没有对应的路由`)
32
+ return this.resetActiveMenu()
33
+ }
34
+
35
+ // 触发的菜单会跳转到当前路由时,根据参数判断是否进行刷新
36
+ getRouterKey(this.$route) === getRouterKey(route)
37
+ ? refreshWhenSame && refreshPage(this.$router)
38
+ : this.$router.push(route)
39
+ },
40
+
41
+ // el-menu的高亮结果可能有误,所以手动更新
42
+ resetActiveMenu() {
43
+ const elMenu = this.$_getElMenuInstance()
44
+
45
+ // 仅当存在index为this.activeMenu的el-menu-item时才更新
46
+ if (elMenu && elMenu.items[this.activeMenu]) {
47
+ elMenu.updateActiveIndex(this.activeMenu)
48
+ }
49
+ },
50
+
51
+ // 将defaultActive更新为activeMenu的值,如果两者相同会调用resetActiveMenu()
52
+ // 尽量少调用,defaultActive的变化将导致调用方以及nav-menu的重新渲染
53
+ setDefaultActiveMenu() {
54
+ const newVal = this.activeMenu
55
+ const oldVal = this.defaultActive
56
+
57
+ // 该值变化时,nav-menu会重新渲染来更新高亮菜单
58
+ this.defaultActive = newVal
59
+
60
+ // 未变化时需要手动更新
61
+ if (oldVal === newVal) {
62
+ this.resetActiveMenu()
63
+ }
64
+ },
65
+
66
+ // 获取el-menu实例
67
+ $_getElMenuInstance() {
68
+ const navMenu = this.$refs['nav-menu']
69
+ return navMenu && navMenu.$refs['el-menu']
70
+ }
71
+ }
72
+ }