董洪蒙
摘 要:前端开发是系统的脸面,国内开源JS框架VUE表现优异,很多前端开发者都采用它来实现业务系统界面。本篇文章来源于开发实战,如何实现一个精致、可拓展动态菜单,并阐述了开发思路、开发技术,展示了精炼后的核心代码,以期为前端开发者提供开发思路,共同集思广益。
关键词:VUE,vue-router,菜单,递归实现
VUE作为国产优秀的构建用户界面的渐进式JS框架,它是以数据驱动和组件化的思想构建的。VUE与国外类似的框架相比,提供了更加简洁的API,能很快地上手,是创建项目的首选前端框架。
笔者在为某政府机关开发一套小型业务系统,采用VUE作为前端框架,且采用了vue-router路由组件、vuex数据组件,主体上使用蚂蚁金服的ant design vue作为界面实现的组件库。采用的业务系统非常流行的顶部-侧边-通栏布局,感觉其中的难点在于菜单的实现,因为各个用户因角色身份的不同,我们希望实现与其权限所对应的菜单,由此必须通过AJAX技术动态从服务端取得动态菜单条目,并填充到界面中。假定通过axios从后端取得如下JSON菜单数据:
"routes": [
"path": "/",
"component": () =>
import(/* webpackChunkName: "layout" */ "./layouts/BasicLayout"),
"children": [
{
"path": "/",
"redirect": "/dashboard/analysis"
},
{
"path": "/dashboard",
"name": "dashboard",
"meta": {
"icon": "dashboard",
"title": "仪表盘",
"authority": ["admin", "user"]
},
}
...
很明显,是在后端开发时根据用户不同,生成不同的菜单数据,路径下的meta字段,包括了authority,以表示显示当前表单项的相关有权限用户。同时也很看出我们要采用VUE的vue-router插件,以控制点击菜单时在layout中出现的不同content组件,实现SPA效果。因为里边有children子菜单的出现,所以要采用递归算法来动态生成相关的菜单表项,下面列出./layouts/SilderMenu/index.vue的模板实现:
:selectedKeys="selectedKeys" :openKeys.sync="openKeys" mode="inline" :theme="theme"> v-if="!item.children" :key="item.path" @click="() => $router.push({ path: item.path, query: $route.query })" > ...
可見要在JS代码中提供menuData等相关数据:
data() {
const menuData = this.getMenuData(this.$router.options.routes)
return {
menuData,
}
},
getMenuData方法是获取由服务端取得相关JSON数据渲染到实现菜单组件中,在methods中实现:
getMenuData(routes = []) {
const menuData = []
for (let item of routes) {
if (item.meta && item.meta.authority) {
if (!check(item.meta.authority)) {
continue
}
}
if (item.name && !item.hideInMenu) {
const newItem = { ...item }
delete newItem.children
if (item.children && !item.hideChildrenMenu) {
newItem.children = this.getMenuData(item.children)
} else {
}
menuData.push(newItem)
} else if (
!item.hideInMenu &&
!item.hideChildrenMenu &&
item.children
) {
menuData.push(
...this.getMenuData(item.children),
)
}
}
return menuData
},
这段代码十分复杂,有以下几点值得注意:
* check(item.meta.authority)是检查当前用户是否显示该菜单的判断;
* 通过JSON菜单数据的hideMenu, hideChildMenu值,以判断是否显示在菜单中,因为我们是通过vue-router来推送路径的,有的路径不需要再现在菜单中,如404、登录注册页面等。
* 根据菜单数据中children数据,采用递归调用方法,简化了算法逻辑。
从./layouts/SilderMenu/index.vue中的实现中,我们还必须实现SubMenu子组件:
......
与SubMenu交互中,只需要通过VUE的props传送已解析的菜单数据即可,即:menu-info="item"这段代码。
菜单组件的实现,主要采用了唐金洲Vue开发实战中的开发思路,是这段业务系统开发中花费时间较多的,逻辑也相对比较复杂的一段代码,综合运用了多种前端开发的前沿知识,本人也无法贴出所有代码,细讲所有的知识点,因为里边涉及的东西太多了。有需要的可与我联系,我们共同进步和提高。
参考文献:
[1]唐金洲.Vue 开发实战[EB/OL].北京:ant-design-vue官網.2019-5-1
[2]肖睿,龙颖.Vue 企业开发实战[M].北京:人民邮电出版社.2018-12-01