一、前言
使用vue,nodejs
nodejs自行安装,我的版本是16.2
vue-element-admin 是一个后台前端解决方案,它基于 vue 和 element-ui实现。它使用了最新的前端技术栈,内置了 i18 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件。
二、项目开始
建议使用vscode并且强烈建议安装插件
https://kirei7.lanzouy.com/iqlpq11k4ixi
密码:g8z0
# 进入项目目录
cd vue-admin-template
# 建议不要用 cnpm 安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org
# 本地开发 启动项目
npm run dev
#报错 nodejs版本太高
Error: error:0308010C:digital envelope routines::unsupported
set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve
#启动项目
npm run serve
启动完成后会自动打开浏览器访问 http://localhost:9528
三、改造登录
3.1 编写controller
@RestController
@Api(tags = "登录管理控制器")
@RequestMapping(value = "/admin/system/index")
public class LoginController {
/**
* 登录接口
* @return
*/
@PostMapping(value = "/login")
public Result login()
{
Map<String,Object> map = new HashMap<String, Object>();
map.put("token","admin-token");
// 注意此处状态码还需要处理的,我们返回的是200,人家这里是20000
return Result.ok(map);
}
/**
* 获取用户信息
*/
@GetMapping(value = "/info")
public Result info()
{
Map<String,Object> map = new HashMap<>();
map.put("roles","[admin]");
map.put("introduction","I am a super admin");
map.put("avatar","https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
map.put("name","admin kirei7 hello!");
return Result.ok(map);
}
}
3.2 改造前端
3.2.1 修改 vue.config.js
//before: require('./mock/mock-server.js') //该行注释
proxy: {
'/dev-api': { // 匹配所有以 '/dev-api'开头的请求路径
target: 'http://localhost:8088',
changeOrigin: true, // 支持跨域
pathRewrite: { // 重写路径: 去掉路径中开头的'/dev-api'
'^/dev-api': ''
}
}
}
3.2.2 修改前端状态码
3.2.3 修改登录接口路径和请求方式
路径在mapping方法自行点击查看
四、角色管理模块开发
4.1 管理列表开发
4.1.1 创建组件
<template>
<div>
角色列表
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
<template>
<div>
角色列表
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
4.1.2 修改路由配置
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import Layout from '@/layout'
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: 'Dashboard', icon: 'dashboard' }
}]
},
{
path: '/system', // 父路径
component: Layout,
redirect: '/system/sysUser', // 直接输入system 会重定向到
name: 'system',
meta: { title: '系统管理', icon: 'el-icon-s-help' },
children: [
{
path: 'sysRole', // 子路径 注意这里不要加斜线
name: 'sysRole',
component: () => import('@/views/system/sysRole/list'),
meta: { title: '角色管理', icon: 'table' }
},
{
path: 'sysUser', // 子路径
name: 'Tree',
component: () => import('@/views/system/sysUser/list'),
meta: { title: '用户管理', icon: 'tree' }
}
]
},
{ path: '*', redirect: '/404', hidden: true }
]
const createRouter = () => new Router({
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
4.1.3 编写role.js
import request from* '@/utils/request'
// 定义基本的url
const BASE_URL = '/admin/system/sysRole';
export default {
// 列表*
getPageList(page,limit,searchObj){
return request({
url: `${BASE_URL}/${page}/${limit}`,
method: 'get',
params: searchObj
})
}
}
4.1.4 在 sysRole/list.vue 进行请求数据
<template>
<div class="app-container">
</div>
</template>
<script>
import api from '@/api/role/role.js'
export default {
data () {
return {
list:[],
total:0,
page:1,
limit:3,
searchObj:{}
}
},
created () {
this.fetchData(1);
},
methods: {
fetchData(){
// this.page = pageNum;
api.getPageList(this.page,this.limit,this.searchObj).then(response=>{
// console.log(response);
this.list = response.data.records;
this.total = response.data.total;
})
}
}
}
</script>
<style>
</style>
查看请求结果
修改list
<template>
<div class="app-container">
</div>
</template>
<script>
import api from '@/api/role/role.js'
export default {
data () {
return {
list:[],
total:0,
page:1,
limit:3,
searchObj:{}
}
},
created () {
this.fetchData(1);
},
methods: {
fetchData(pageNum){
this.page = pageNum;
api.getPageList(this.page,this.limit,this.searchObj).then(response=>{
// console.log(response);
this.list = response.data.records;
this.total = response.data.total;
})
}
}
}
</script>
<style>
</style>
4.1.5 修改页面的布局
<!-- 表格 -->
<el-table
v-loading="listLoading"
:data="list"
stripe
border
style="width: 100%;margin-top: 10px;"
@selection-change="handleSelectionChange">
<el-table-column type="selection"/>
<el-table-column
label="序号"
width="70"
align="center">
<template slot-scope="scope">
{{ (page - 1) * limit + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="roleName" label="角色名称" />
<el-table-column prop="roleCode" label="角色编码" />
<el-table-column prop="createTime" label="创建时间" width="160"/>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini" @click="edit(scope.row.id)" title="修改"/>
<el-button type="danger" icon="el-icon-delete" size="mini" @click="removeDataById(scope.row.id)" title="删除"/>
<el-button type="warning" icon="el-icon-baseball" size="mini" @click="showAssignAuth(scope.row)" title="分配权限"/>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
:current-page="page"
:total="total"
:page-size="limit"
style="padding: 30px 0; text-align: center;"
layout="total, prev, pager, next, jumper"
@current-change="fetchData"
/>
4.1.6 处理时间显示问题
在 application-dev.yml加上
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
4.1.7 处理搜索表单
<!--查询表单-->
<div class="search-div">
<el-form label-width="70px" size="small">
<el-row>
<el-col :span="24">
<el-form-item label="角色名称">
<el-input style="width: 100%" v-model="searchObj.roleName" placeholder="角色名称"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row style="display:flex">
<el-button type="primary" icon="el-icon-search" size="mini" @click="fetchData(1)">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetData">重置</el-button>
</el-row>
</el-form>
</div>
method
resetData(){
// 清空表单
this.searchObj={};
// 再次刷新列表数据
this.fetchData();
}
4.2 删除角色
4.2.1 添加role.js
//根据id删除角色信息
removeId(id){
return request({
url:`${BASE_URL}/removeRoleById/${id}`,//增加代码可读性,修改一下。要与controller层一样
method:'delete'
});
},
4.2.2 添加list.vue中methods
//根据id删除单个角色信息的方法
removeDataById(id){
//alert(id);
this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 点击确定
//调用后端的删除的接口
api.removeId(id).then(response=>{
//执行成功后给出的提示信息
this.$message({
type: 'success',
message: '删除成功!'
});
//重新刷新数据
this.fetchData(1);
});
})
},
4.3 添加修改角色
4.3.1 role.js
//添加角色的方法
saveRole(role){
return request({
url: `${BASE_URL}/addRole`,
method: 'post', // 提交方式为 post
data: role // 传递json 数据
})
},
//根据角色id查询角色信息
getRoleById(id){
return request({
url: `${BASE_URL}/findRoleById/${id}`,
method: 'get' // 提交方式为 get
})
},
//修改角色的方法
updateRole(role){
return request({
url: `${BASE_URL}/updateRole`,
method: 'post', // 提交方式为 post
data: role // 传递json 数据
})
},
4.3.2 method
//添加角色方法
add(){
//显示出添加的对话框
this.dialogVisible = true;
//清除之前的旧数据
this.sysRole={}
},
//当点击添加或者修改对话框中的确定按钮时触发的事件
//它这里修改和添加共用的同一个对话框
saveOrUpdate(){
//console.log('saveOrUpdate');
//判断是修改还是添加
//看对象中是否有id属性值,如果有就是修改,如果没有就执行添加的操作
//console.log(this.sysRole.id);
if(this.sysRole.id!=null){
//console.log(1111);
//执行修改操作
this.updateRole();
}else{
//console.log(222);
this.addRole();
}
},
addRole(){
api.saveRole(this.sysRole).then(response=>{
//给出提示信息
this.$message({
type: 'success',
message: '添加角色成功!'
});
//关闭对话框
this.dialogVisible = false;
//重新刷新数据
this.fetchData(1);
});
},
//根据id得到角色对象
edit(id){
//显示出修改的对话框
this.dialogVisible = true;
api.getRoleById(id).then(response=>{
//console.log(response.data);
this.sysRole=response.data;
});
},
//修改的方法
updateRole(){
api.updateRole(this.sysRole).then(response=>{
//给出提示信息
this.$message({
type: 'success',
message: '修改角色成功!'
});
//关闭对话框
this.dialogVisible = false;
//重新刷新数据
this.fetchData(1);
});
},
4.3.3 增加按钮
<!-- 工具条 -->
<div class="tools-div">
<el-button type="success" icon="el-icon-plus" size="mini" @click="add" >添 加
</el-button>
</div>
4.3.4 修改样式
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
<style>
.search-div {
padding:10px;border: 1px solid #EBEEF5;border-radius:3px;
}
.tools-div {
margin-top: 10px;padding:10px;border: 1px solid #EBEEF5;border-radius:3px;
}
</style>
</head>
4.3.5 添加弹框
使用element ui
<!-- 添加和修改的对话框 -->
<el-dialog title="添加/修改" :visible.sync="dialogVisible" width="40%" >
<el-form ref="dataForm" :model="sysRole" label-width="150px" size="small" style="padding-right: 40px;">
<el-form-item label="角色名称">
<el-input v-model="sysRole.roleName"/>
</el-form-item>
<el-form-item label="角色编码">
<el-input v-model="sysRole.roleCode"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false" size="small" icon="el-icon-refresh-right">取 消</el-button>
<el-button type="primary" icon="el-icon-check" @click="saveOrUpdate()" size="small">确 定</el-button>
</span>
</el-dialog>
复制上去是不是界面全白了,我的数据呢啊啊啊啊
F12 console 报错undefined
修改
data () {
return {
list:[],
total:0,
page:1,
limit:3,
searchObj:{},
sysRole:{}, //封装角色信息的
dialogVisible:false, //表示隐藏对话框
electValueData:[] //存储选中了的数据
}
},
4.4 批量删除角色
4.4.1 role.js
//批量删除角色信息
bactchremoveId(ids){
return request({
url:`${BASE_URL}/batchRemove`,
method:'delete',
data:ids //传递的是json数据
});
},
4.4.2 method
handleSelectionChange(selectValue){ //复选框
this.selectValueData = selectValue;
},
//批量删除角色信息
batchRemove(){
// 判断是否有选中select
if(this.selectValueData.length==0)
{
this.$message.warning('请选择要删除的记录!')
return;
}
this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
var ids=[]; //用来存储要删除的角色的id信息的
for(var i=0;i<this.selectValueData.length;i++)
{
var obj= this.selectValueData[i];
// 获取id值
var id = obj.id;
// 将id放进到数组中
ids.push(id);
}
api.bactchremoveId(ids).then((response) => {
// 提示
this.$message({
type: "success",
message: "删除成功!",
});
// 刷新页面
this.fetchData(1);
});
});
},
4.4.3 增加按钮
<!-- 工具条 -->
<div class="tools-div">
<el-button type="success" icon="el-icon-plus" size="mini" @click="add">添 加</el-button>
<el-button class="btn-add" size="mini" @click="batchRemove()" >批量删除</el-button>
</div>
4.4.4添加复选框
<!-- 表格 -->
<el-table
v-loading="listLoading"
:data="list"
stripe
border
style="width: 100%; margin-top: 10px"
@selection-change="handleSelectionChange">
<el-table-column type="selection"/>