遍历json,低效,mockjs调用菜单列表的接口,
菜单路由
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '@/components/Home.vue'
import storage from './../utils/storage'
import API from './../api'
import utils from './../utils/utils'
const routes = [
{
name: 'home',
path: '/',
meta: {
title: '首页'
},
component: Home,
redirect: '/welcome',
children: [
{
name: 'welcome',
path: '/welcome',
meta: {
title: '欢迎体验Vue3全栈课程'
},
component: () => import('@/views/Welcome.vue')
}
]
},
{
name: 'login',
path: '/login',
meta: {
title: '登录'
},
component: () => import('@/views/Login.vue')
},
{
name: '404',
path: '/404',
meta: {
title: '页面不存在'
},
component: () => import('@/views/404.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
async function loadAsyncRoutes() {
let userInfo = storage.getItem('userInfo') || {}
if (userInfo.token) {
try {
const { menuList } = await API.getPermissionList()
let routes = utils.generateRoute(menuList)
routes.map(route => {
let url = `./../views/${route.component}.vue`
route.component = () => import(url);
router.addRoute("home", route);
})
} catch (error) {
}
}
}
await loadAsyncRoutes();
// 判断当前地址是否可以访问
/*
function checkPermission(path) {
let hasPermission = router.getRoutes().filter(route => route.path == path).length;
if (hasPermission) {
return true;
} else {
return false;
}
}
*/
// 导航守卫
router.beforeEach((to, from, next) => {
if (router.hasRoute(to.name)) {
document.title = to.meta.title;
next()
} else {
next('/404')
}
})
export default router
menu.vue
<template>
<div class="user-manage">
<div class="query-form">
<el-form ref="form" :inline="true" :model="queryForm">
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="queryForm.menuName" placeholder="请输入菜单名称" />
</el-form-item>
<el-form-item label="菜单状态" prop="menuState">
<el-select v-model="queryForm.menuState">
<el-option :value="1" label="正常"></el-option>
<el-option :value="2" label="停用"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getMenuList">查询</el-button>
<el-button @click="handleReset('form')">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="base-table">
<div class="action">
<el-button type="primary" @click="handleAdd(1)">新增</el-button>
</div>
<el-table
:data="menuList"
row-key="_id"
:tree-props="{ children: 'children' }"
>
<el-table-column
v-for="item in columns"
:key="item.prop"
:prop="item.prop"
:label="item.label"
:width="item.width"
:formatter="item.formatter"
>
</el-table-column>
<el-table-column label="操作" width="220">
<template #default="scope">
<el-button
@click="handleAdd(2, scope.row)"
type="primary"
size="mini"
>新增</el-button
>
<el-button @click="handleEdit(scope.row)" size="mini"
>编辑</el-button
>
<el-button
type="danger"
size="mini"
@click="handleDel(scope.row._id)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog title="用户新增" v-model="showModal">
<el-form
ref="dialogForm"
:model="menuForm"
label-width="100px"
:rules="rules"
>
<el-form-item label="父级菜单" prop="parentId">
<el-cascader
v-model="menuForm.parentId"
:options="menuList"
:props="{ checkStrictly: true, value: '_id', label: 'menuName' }"
clearable
/>
<span>不选,则直接创建一级菜单</span>
</el-form-item>
<el-form-item label="菜单类型" prop="menuType">
<el-radio-group v-model="menuForm.menuType">
<el-radio :label="1">菜单</el-radio>
<el-radio :label="2">按钮</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="menuForm.menuName" placeholder="请输入菜单名称" />
</el-form-item>
<el-form-item
label="菜单图标"
prop="icon"
v-show="menuForm.menuType == 1"
>
<el-input v-model="menuForm.icon" placeholder="请输入岗位" />
</el-form-item>
<el-form-item
label="路由地址"
prop="path"
v-show="menuForm.menuType == 1"
>
<el-input v-model="menuForm.path" placeholder="请输入路由地址" />
</el-form-item>
<el-form-item
label="权限标识"
prop="menuCode"
v-show="menuForm.menuType == 2"
>
<el-input v-model="menuForm.menuCode" placeholder="请输入权限标识" />
</el-form-item>
<el-form-item
label="组件路径"
prop="component"
v-show="menuForm.menuType == 1"
>
<el-input v-model="menuForm.component" placeholder="请输入组件路径" />
</el-form-item>
<el-form-item
label="菜单状态"
prop="menuState"
v-show="menuForm.menuType == 1"
>
<el-radio-group v-model="menuForm.menuState">
<el-radio :label="1">正常</el-radio>
<el-radio :label="2">停用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="handleSubmit">确 定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import utils from "../utils/utils";
export default {
name: "menu",
data() {
return {
queryForm: {
menuState: 1,
},
menuList: [],
columns: [
{
label: "菜单名称",
prop: "menuName",
width: 150,
},
{
label: "图标",
prop: "icon",
},
{
label: "菜单类型",
prop: "menuType",
formatter(row, column, value) {
return {
1: "菜单",
2: "按钮",
}[value];
},
},
{
label: "权限标识",
prop: "menuCode",
},
{
label: "路由地址",
prop: "path",
},
{
label: "组件路径",
prop: "component",
},
{
label: "菜单状态",
prop: "menuState",
width: 90,
formatter(row, column, value) {
return {
1: "正常",
2: "停用",
}[value];
},
},
{
label: "创建时间",
prop: "createTime",
formatter(row, column, value) {
return utils.formateDate(new Date(value));
},
},
],
showModal: false,
menuForm: {
parentId: [null],
menuType: 1,
menuState: 1,
},
action: "",
rules: {
menuName: [
{
required: true,
message: "请输入菜单名称",
trigger: "blur",
},
{
min: 2,
max: 10,
message: "长度在2-8个字符",
trigger: "blur",
},
],
},
};
},
mounted() {
this.getMenuList();
},
methods: {
// 菜单列表初始化
async getMenuList() {
try {
let list = await this.$api.getMenuList(this.queryForm);
this.menuList = list;
} catch (e) {
throw new Error(e);
}
},
// 表单重置
handleReset(form) {
this.$refs[form].resetFields();
},
// 新增菜单
handleAdd(type, row) {
this.showModal = true;
this.action = "add";
if (type == 2) {
this.menuForm.parentId = [...row.parentId, row._id].filter(
(item) => item
);
}
},
handleEdit(row) {
this.showModal = true;
this.action = "edit";
this.$nextTick(() => {
Object.assign(this.menuForm, row);
});
},
async handleDel(_id) {
await this.$api.menuSubmit({ _id, action: "delete" });
this.$message.success("删除成功");
this.getMenuList();
},
// 菜单操作-提交
handleSubmit() {
this.$refs.dialogForm.validate(async (valid) => {
if (valid) {
let { action, menuForm } = this;
let params = { ...menuForm, action };
let res = await this.$api.menuSubmit(params);
this.showModal = false;
this.$message.success("操作成功");
this.handleReset("dialogForm");
this.getMenuList();
}
});
},
// 弹框关闭
handleClose() {
this.showModal = false;
this.handleReset("dialogForm");
},
},
};
</script>
<style lang="scss">
</style>
routes/menus.js
菜单列表查询,编辑删除新增
const router = require('koa-router')()
const util = require('../utils/util')
const Menu = require('../models/menuSchema')
router.prefix('/menu')
// 菜单列表查询
router.get('/list', async (ctx) => {
const { menuName, menuState } = ctx.request.query;
const params = {}
if (menuName) params.menuName = menuName;
if (menuState) params.menuState = menuState;
let rootList = await Menu.find(params) || []
const permissionList = util.getTreeMenu(rootList, null, [])
ctx.body = util.success(permissionList);
})
// 菜单编辑、删除、新增功能
router.post('/operate', async (ctx) => {
const { _id, action, ...params } = ctx.request.body;
let res, info;
try {
if (action == 'add') {
res = await Menu.create(params)
info = '创建成功'
} else if (action == 'edit') {
params.updateTime = new Date();
res = await Menu.findByIdAndUpdate(_id, params);
info = '编辑成功'
} else {
res = await Menu.findByIdAndRemove(_id)
await Menu.deleteMany({ parentId: { $all: [_id] } })
info = '删除成功'
}
ctx.body = util.success('', info);
} catch (error) {
ctx.body = util.fail(error.stack);
}
})
module.exports = router;