Vue.js 筆記(六)vite-element-admin 動態選單
今天要跟大家介紹如何使用 vite-element-admin
製作動態 menu
。vite-element-admin
是一個後台前端解決方案,使用了最新的 vue3
、 vite2
…等技術。
Quick Start
Table Schema
在開始之前,需要先跟大家介紹一下關於動態選單,我的後端 table schema
是怎麼設計的。
adm_user
後台使用者1
2
3
4
5
6
7
8
9
10
11
12
13
14
15create table adm_user
(
id bigint auto_increment primary key,
role_code varchar(10) not null comment 'role code',
username varchar(255) charset utf8mb3 not null comment '用户名',
password varchar(255) charset utf8mb3 not null comment '密码',
user_status int default 0 null comment '0:正常, 1:禁止',
last_login_time datetime null,
create_user varchar(50) charset utf8mb3 null,
create_time datetime default CURRENT_TIMESTAMP null,
modify_user varchar(50) charset utf8mb3 null,
modify_time datetime default CURRENT_TIMESTAMP null,
constraint username unique (username)
);
INSERT INTO djsj.adm_user (id, role_code, username, password, user_status, last_login_time, create_user, create_time, modify_user, modify_time) VALUES (1, 'admin', 'admin', '$2b$10$c4lupIdjmr/znwcTqkjVX./7wveGopVLO/MfgcB0QtOoNEGyEkIeC', 0, '2023-08-25 15:05:09', 'sys', '2021-03-19 10:06:51', null, null);adm_role
後台角色1
2
3
4
5
6
7
8
9create table adm_role
(
id bigint auto_increment primary key,
role_code varchar(10) not null,
name varchar(255) charset utf8mb3 not null comment '角色名稱',
createTime datetime default CURRENT_TIMESTAMP null comment '創建時間',
constraint name unique (role_code)
);
INSERT INTO djsj.adm_role (id, role_code, name, createTime) VALUES (1, 'admin', '管理員', '2021-03-01 00:00:00');adm_menu
選單1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26create table adm_menu
(
id bigint auto_increment primary key,
pid bigint not null comment '上層選單',
phyle varchar(50) null comment 'Parent Hierarchy',
name varchar(255) not null comment '权限名称',
path varchar(255) not null comment '权限对应的接口',
redirect varchar(255) null comment 'redirect',
component varchar(255) not null comment 'component',
meta json null comment 'meta data',
sort int default 0 not null comment '排序'
);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (1, 0, '0', 'Dashboard', '/', '/dashboard', 'layout', '{"icon": "home", "title": "首頁"}', 1);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (2, 1, '0|1', 'Dashboard', 'dashboard', null, 'dashboard/index', '{"title": "首頁", "noCache": true}', 1);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (3, 0, '0', 'User', '/user', '/user/log', 'layout', '{"title": "個人資訊", "hidden": true}', 1);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (4, 3, '0|3', 'UserLog', 'log', null, 'user/log', '{"title": "操作記錄", "hidden": true}', 0);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (5, 3, '0|3', 'UserPassword', 'password', null, 'user/password', '{"title": "修改密碼", "hidden": true}', 0);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (6, 0, '0', 'Admin', '/admin', '/admin/user', 'layout', '{"icon": "users", "title": "使用者管理"}', 2);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (7, 6, '0|6', 'AdminUser', 'user', null, 'admin/user', '{"title": "使用者帳號", "noCache": true}', 0);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (8, 6, '0|6', 'AdminLog', 'log', null, 'admin/log', '{"title": "系統日誌", "noCache": true}', 1);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (9, 0, '0', 'Player', '/player', '/player/index', 'layout', '{"icon": "account", "title": "玩家管理"}', 3);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (10, 9, '0|9', 'PlayerIndex', 'index', null, 'player/index', '{"title": "玩家帳號", "noCache": true}', 0);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (11, 9, '0|9', 'PlayerWallet', 'wallet', null, 'player/wallet', '{"title": "玩家帳務", "noCache": true}', 1);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (12, 0, '0', 'Game', '/game', '/game/record', 'layout', '{"icon": "bug", "title": "遊戲管理"}', 4);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (13, 12, '0|12', 'GameRecord', 'record', null, 'game/record', '{"title": "遊戲紀錄", "noCache": true}', 0);
INSERT INTO djsj.adm_menu (id, pid, phyle, name, path, redirect, component, meta, sort) VALUES (14, 12, '0|12', 'GameLog', 'log', null, 'game/log', '{"title": "遊戲歷程", "noCache": true}', 1);adm_role_menu_map
角色選單對應表1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20create table adm_role_menu_map
(
id bigint auto_increment primary key,
role_code varchar(10) not null comment 'role code',
menu_id bigint not null comment 'adm_menu.id'
);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (1, 'admin', 1);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (2, 'admin', 2);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (3, 'admin', 3);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (4, 'admin', 4);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (5, 'admin', 5);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (6, 'admin', 6);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (7, 'admin', 7);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (8, 'admin', 8);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (9, 'admin', 9);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (10, 'admin', 10);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (11, 'admin', 11);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (12, 'admin', 12);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (13, 'admin', 13);
INSERT INTO djsj.adm_role_menu_map (id, role_code, menu_id) VALUES (14, 'admin', 14);
後台API
indexHandle.js
1
2
3
4
5
6
7router.get('/getMenuInfo', [filter.authorize], asyncHandler(async function (req, res) {
let roleCode = req.roleCode;
let admMenuList = await admMenuService.getAdmMenuByRoleCode(roleCode);
utils.resEnd(res, new SuccessResBaseObj({
admMenuList
}));
}));sql
1
2
3
4select am.*
from adm_menu am
join adm_role_menu_map armm on am.id = armm.menu_id
where armm.role_code = ?response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162{
"code": 0,
"message": "成功",
"data": {
"admMenuList": [
{
"id": 1,
"pid": 0,
"phyle": "0",
"name": "Dashboard",
"path": "/",
"redirect": "/dashboard",
"component": "layout",
"meta": "{\"icon\": \"home\", \"title\": \"首頁\"}",
"sort": 1
},
{
"id": 2,
"pid": 1,
"phyle": "0|1",
"name": "Dashboard",
"path": "dashboard",
"redirect": null,
"component": "dashboard/index",
"meta": "{\"title\": \"首頁\", \"noCache\": true}",
"sort": 1
},
{
"id": 3,
"pid": 0,
"phyle": "0",
"name": "User",
"path": "/user",
"redirect": "/user/log",
"component": "layout",
"meta": "{\"title\": \"個人資訊\", \"hidden\": true}",
"sort": 1
},
{
"id": 4,
"pid": 3,
"phyle": "0|3",
"name": "UserLog",
"path": "log",
"redirect": null,
"component": "user/log",
"meta": "{\"title\": \"操作記錄\", \"hidden\": true}",
"sort": 0
},
{
"id": 5,
"pid": 3,
"phyle": "0|3",
"name": "UserPassword",
"path": "password",
"redirect": null,
"component": "user/password",
"meta": "{\"title\": \"修改密碼\", \"hidden\": true}",
"sort": 0
},
{
"id": 6,
"pid": 0,
"phyle": "0",
"name": "Admin",
"path": "/admin",
"redirect": "/admin/user",
"component": "layout",
"meta": "{\"icon\": \"users\", \"title\": \"使用者管理\"}",
"sort": 2
},
{
"id": 7,
"pid": 6,
"phyle": "0|6",
"name": "AdminUser",
"path": "user",
"redirect": null,
"component": "admin/user",
"meta": "{\"title\": \"使用者帳號\", \"noCache\": true}",
"sort": 0
},
{
"id": 8,
"pid": 6,
"phyle": "0|6",
"name": "AdminLog",
"path": "log",
"redirect": null,
"component": "admin/log",
"meta": "{\"title\": \"系統日誌\", \"noCache\": true}",
"sort": 1
},
{
"id": 9,
"pid": 0,
"phyle": "0",
"name": "Player",
"path": "/player",
"redirect": "/player/index",
"component": "layout",
"meta": "{\"icon\": \"account\", \"title\": \"玩家管理\"}",
"sort": 3
},
{
"id": 10,
"pid": 9,
"phyle": "0|9",
"name": "PlayerIndex",
"path": "index",
"redirect": null,
"component": "player/index",
"meta": "{\"title\": \"玩家帳號\", \"noCache\": true}",
"sort": 0
},
{
"id": 11,
"pid": 9,
"phyle": "0|9",
"name": "PlayerWallet",
"path": "wallet",
"redirect": null,
"component": "player/wallet",
"meta": "{\"title\": \"玩家帳務\", \"noCache\": true}",
"sort": 1
},
{
"id": 12,
"pid": 0,
"phyle": "0",
"name": "Game",
"path": "/game",
"redirect": "/game/record",
"component": "layout",
"meta": "{\"icon\": \"bug\", \"title\": \"遊戲管理\"}",
"sort": 4
},
{
"id": 13,
"pid": 12,
"phyle": "0|12",
"name": "GameRecord",
"path": "record",
"redirect": null,
"component": "game/record",
"meta": "{\"title\": \"遊戲紀錄\", \"noCache\": true}",
"sort": 0
},
{
"id": 14,
"pid": 12,
"phyle": "0|12",
"name": "GameLog",
"path": "log",
"redirect": null,
"component": "game/log",
"meta": "{\"title\": \"遊戲歷程\", \"noCache\": true}",
"sort": 1
}
]
}
}
vite-element-admin 修改
主要重點在於修改,
router/index.js
,獲取方式改為由api
資料,並且使用遞迴將json
組合出來。
成果
這次的介紹就到這邊,如果有其他問題請再跟我說。
Reference
vite-element-admin
vue-element-admin
Donate
謝謝您的支持與鼓勵