vue后台管理系统
记录一次后台管理系统项目,需要的朋友私聊我拿源码
介绍
这是在在学校对vue进行学习后搭建的小项目。该后台管理系统为spa单页项目,前后端分离,实现了登录、身份鉴别、用户管理、角色查看、权限管理,实现了基本的增删改查功能,可以为用户设置权限,实现了登录拦截、用户增删改查,权限给予,剥夺,查看等功能。可以作为不同类型网站后台的复用。
技术栈:vue-cli,vue,vue-router,axios,element-ui
正文开始,先上效果图
效果图
代码实现
登录
<template> <div class="bgcbox"> <div class="logincss"> <el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="100px" class="demo-loginForm" > <el-form-item label="用户名" prop="name"> <el-input v-model="loginForm.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="loginForm.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">登录</el-button> <el-button @click="resetForm">重置</el-button> </el-form-item> </el-form> </div> </div> </template> <script> import axios from "axios"; export default {
data() {
return {
loginForm: {
username: "admin", password: "", }, rules: {
username: [ // required 是否为必填项 // message 当前规则校验失败时的提示 // trigger 表单验证的触发实际,blur表示失去焦点时触发 {
required: true, message: "用户名为必填项", trigger: "blur" }, // min 最小长度 // max 最大长度 {
min: 3, max: 6, message: "用户名长度在 3 到 6 个字符", trigger: "blur", }, ], password: [ {
required: true, message: "密码为必填项", trigger: "blur" }, {
min: 3, max: 6, message: "密码长度在 3 到 6 个字符", trigger: "blur", }, ], }, }; }, methods: {
islogin() {
axios .post("http://localhost:8888/api/private/v1/login", this.loginForm) .then((res) => {
const {
data, meta } = res.data; if (meta.status === 200) {
localStorage.setItem("token", data.token); this.$router.push("/home"); //编程式导航,跳转到主页 } else {
this.$message({
showClose: true, message: meta.msg, type: "error", }); } }); }, submitForm() {
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.islogin(); } else {
console.log("error submit!!"); return false; } }); }, resetForm() {
this.$refs.loginForm.resetFields(); }, }, }; </script> <style> .bgcbox {
background-color: #2c414c; width: 100%; height: 100%; } .logincss {
width: 460px; height: 350px; border: 1px solid #000; border-radius: 25px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #ffffff; } .demo-loginForm {
width: 400px; height: 100%; padding-top: 100px; } </style>
用户页
<template> <div> <el-row :gutter="20" style="margin-bottom: 10px"> <el-col :span="6"> <el-input placeholder="请输入内容" v-model="search" class="input-with-select" > <el-button slot="append" icon="el-icon-search" @click="searchdata" ></el-button> </el-input> </el-col> <el-col :span="6"> <el-button type="primary" @click="adduserdialog = true" >添加用户</el-button > </el-col> </el-row> <el-table :data="usersdata" stripe style="width: 100%"> <el-table-column prop="username" label="姓名" width="180"> </el-table-column> <el-table-column prop="email" label="邮箱" width="180"> </el-table-column> <el-table-column prop="mobile" label="电话"> </el-table-column> <el-table-column label="用户状态" width="180"> <template slot-scope="scope"> <el-switch v-model="scope.row.mg_state" @change="changestate(scope.row.id, scope.row.mg_state)" > </el-switch> </template> </el-table-column> <el-table-column label="操作" prop="address"> <template slot-scope="scope"> <!-- 修改 --> <el-button type="primary" icon="el-icon-edit" plain size="mini" @click="openupdate(scope.row)" ></el-button> <!-- 删除 --> <el-button type="danger" icon="el-icon-delete" plain size="mini" @click="deleteuser(scope.row.id)" ></el-button> <el-button type="success" size="mini">角色管理</el-button> </template> </el-table-column> </el-table> <el-pagination background layout="prev, pager, next" :total="total" :page-size="pagesize" :current-page.sync="curpage" @current-change="changecur" > </el-pagination> <!-- 弹出的添加模态框 --> <el-dialog title="添加" :visible.sync="adduserdialog" @close="clearuseradd"> <el-form :model="adduserform" :rules="addrules" ref="addform"> <el-form-item prop="username" label="用户名" :label-width="formLabelWidth" > <el-input v-model="adduserform.username" auto-complete="off" ></el-input> </el-form-item> <el-form-item prop="password" label="密码" :label-width="formLabelWidth" > <el-input type="password" v-model="adduserform.password" auto-complete="off" ></el-input> </el-form-item> <el-form-item prop="email" label="邮箱" :label-width="formLabelWidth"> <el-input v-model="adduserform.email" auto-complete="off"></el-input> </el-form-item> <el-form-item prop="mobile" label="手机" :label-width="formLabelWidth"> <el-input v-model="adduserform.mobile" auto-complete="off"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="adduserdialog = false">取 消</el-button> <el-button type="primary" @click="addUser">确 定</el-button> </div> </el-dialog> <!-- 编辑 --> <el-dialog title="编辑" :visible.sync="updateuserdialog" @close="closeupdate" > <el-form :model="updateuserform" :rules="updateuserrules" ref="updateform" > <el-form-item prop="username" label="用户名" :label-width="formLabelWidth" > <el-input :value="updateuserform.username" auto-complete="off" disabled ></el-input> </el-form-item> <el-form-item prop="email" label="邮箱" :label-width="formLabelWidth"> <el-input v-model="updateuserform.email" auto-complete="off" ></el-input> </el-form-item> <el-form-item prop="mobile" label="手机" :label-width="formLabelWidth"> <el-input v-model="updateuserform.mobile" auto-complete="off" ></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="updateuserdialog = false">取 消</el-button> <el-button type="primary" @click="updateUser">确 定</el-button> </div> </el-dialog> </div> </template> <script> export default {
data() {
return {
usersdata: [], curpage: 1, pagesize: 3, total: 0, search: "", adduserdialog: false, updateuserdialog: false, adduserform: {
username: "", password: "", email: "", mobile: "", }, formLabelWidth: "120px", addrules: {
username: [ // required 是否为必填项 // message 当前规则校验失败时的提示 // trigger 表单验证的触发实际,blur表示失去焦点时触发 {
required: true, message: "用户名为必填项", trigger: "blur" }, // min 最小长度 // max 最大长度 {
min: 3, max: 6, message: "用户名长度在 3 到 6 个字符", trigger: "blur", }, ], password: [ {
required: true, message: "密码为必填项", trigger: "blur" }, {
min: 3, max: 6, message: "密码长度在 3 到 6 个字符", trigger: "blur", }, ], }, updateuserform: {
username: "", email: "", mobile: "", id: "", }, updateuserrules: {
}, }; }, mounted() {
this.getdata(); }, methods: {
getdata(curpage = 1) {
this.$http .get("/users", {
params: {
pagenum: curpage, pagesize: 3, query: this.search || "", }, // headers:{
// Authorization: localStorage.getItem('token') // } }) .then((res) => {
console.log(res); const {
data, meta } = res.data; if (meta.status === 200) {
this.usersdata = data.users; this.total = data.total; } }); }, //分页功能(这个方法是配合ui框架的事件来使用的,当当前页发生改变框架会让这个事件触发一次,使用利用这个特点,当当前页改变时,就获取当前页的数据然后渲染) //参数为获取的页码数 changecur(curpage) {
console.log(curpage); this.getdata(curpage); }, //搜索功能 searchdata() {
this.curpage = 1; this.getdata(); }, //用户状态 changestate(id, status) {
console.log(id, status); this.$http.put(`/users/${
id}/state/${
status}`).then((res) => {
console.log(res); const {
data, meta } = res.data; if (meta.status === 200) {
this.$message({
message: meta.msg, type: "success", }); } }); }, //添加用户 addUser() {
this.$refs.addform.validate((valid) => {
if (valid) {
// console.log(this.adduserform.username); this.$http.post("/users", this.adduserform).then((res) => {
console.log(res); const {
data, meta } = res.data; if (meta.status === 201) {
this.$message({
message: meta.msg, type: "success", }); this.adduserdialog = false; this.getdata(); } else {
this.$message.error(meta.msg); } }); } else {
console.log("提交失败"); return false; } }); }, //情况添加用户的模态框 clearuseradd() {
this.$refs.addform.resetFields(); }, //删除用户 deleteuser(id) {
this.$confirm("是否删除该用户?", "提示", {
confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => {
this.$http.delete(`users/${
id}`).then((res) => {
console.log(res); }); this.getdata(); this.curpage = 1; this.$message({
type: "success", message: "删除成功!", }); }) .catch(() => {
this.$message({
type: "info", message: "已取消删除", }); }); }, //编辑用户 openupdate(data) {
this.updateuserdialog = true; this.updateuserform = data; }, updateUser() {
const id = this.updateuserform.id; this.$http .put(`/users/${
id}`, {
email: this.updateuserform.email, mobile: this.updateuserform.mobile, }) .then((res) => {
const {
data, meta } = res.data; if (meta.status === 200) {
this.$message({
message: meta.msg, type: "success", }); } this.updateuserdialog = false; this.getdata(); this.curpage = 1; }); }, closeupdate() {
this.$refs.updateform.resetFields(); }, }, }; </script> <style> </style>
权限页
<template> <div> <el-table :data="rolesList" stripe style="width: 100%"> <el-table-column type="expand"> <template slot-scope="scope"> <el-form label-position="left" inline class="demo-table-expand"> <el-row v-for="item in scope.row.children" :key="item.id"> <!-- 第一列 --> <el-col :span="4">{
{
item.authName }}</el-col> <!-- 第二列 --> <el-col :span="20"> <el-row v-for="item1 in item.children" :key="item1.id"> <el-col :span="4">{
{
item1.authName }}</el-col> <el-col :span="20"> <span v-for="item2 in item1.children" :key="item2.id"> {
{
item2.authName }} </span> </el-col> </el-row> </el-col> </el-row> </el-form> </template> </el-table-column> <el-table-column type="index" label="#" width="50"></el-table-column> <el-table-column prop="roleName" label="角色名称" width="180"> </el-table-column> <el-table-column prop="roleDesc" label="描述" width="180"> </el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <!-- 修改 --> <el-button type="primary" icon="el-icon-edit" plain size="mini" @click="openrolesupdate(scope.row)" ></el-button> <!-- 删除 --> <el-button type="danger" icon="el-icon-delete" plain size="mini" @click="deleteroles(scope.row.id)" ></el-button> <el-button type="success" size="mini" @click="opensetroles(scope.row.children, scope.row.id)" >权限管理</el-button > </template> </el-table-column> </el-table> <!-- 编辑权限 --> <el-dialog title="编辑" :visible.sync="updaterolesdialog" @close="closeupdate" > <el-form v-model="updaterolesform" ref="rolesform"> <el-form-item prop="roleName" label="用户名" :label-width="formLabelWidth" > <el-input :value="updaterolesform.roleName" auto-complete="off" ></el-input> </el-form-item> <el-form-item prop="roleDesc" label="角色描述" :label-width="formLabelWidth" > <el-input v-model="updaterolesform.roleDesc" auto-complete="off" ></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="updaterolesdialog = false">取 消</el-button> <el-button type="primary" @click="updateRoles">确 定</el-button> </div> </el-dialog> <el-dialog title="权限管理" :visible.sync="rolesdialog"> <el-tree :data="allrolesList" show-checkbox :default-expand-all="true" node-key="id" ref="allroles" highlight-current :props="defaultProps" > </el-tree> <div slot="footer" class="dialog-footer"> <el-button @click="rolesdialog = false">取 消</el-button> <el-button type="primary" @click="putallroles">确 定</el-button> </div> </el-dialog> </div> </template> <script> export default {
data() {
return {
rolesList: [], updaterolesdialog: false, formLabelWidth: "120px", updaterolesform: [], //权限管理数据 rolesdialog: false, allrolesList: [], defaultProps: {
children: "children", label: "authName", }, rid: "", }; }, mounted() {
this.getrolesdata(); this.getallrolestree(); }, methods: {
getrolesdata() {
this.$http.get("/roles").then((res) => {
const {
data, meta } = res.data; if (meta.status === 200) {
this.rolesList = data; console.log(this.rolesList[0].children); } }); }, openrolesupdate(data) {
console.log(data); this.updaterolesdialog = true; this.updaterolesform = data; }, deleteroles(id) {
this.$http.delete(`/roles/${
id}`).then((res) => {
const meta = res.data.meta; if (meta.status === 200) {
this.getrolesdata(); this.$message({
message: meta.msg, type: "success", }); } else {
this.$message.error(meta.msg); } }); }, closeupdate() {
this.$refs.rolesform.resetFields(); }, updateRoles() {
const id = this.updaterolesform.id; // console.log(id); this.$http .put(`/roles/${
id}`, {
roleName: this.updaterolesform.roleName, roleDesc: this.updaterolesform.roleDesc, }) .then((res) => {
console.log(res); const {
data, meta } = res.data; if (meta.status === 200) {
this.updaterolesdialog = false; this.getrolesdata(); this.$message({
message: "修改成功", type: "success", }); } }); }, //打开权限管理框 opensetroles(curRoleRights, id) {
this.rolesdialog = true; this.rid = id; this.$nextTick(() => {
const level3Ids = []; curRoleRights.forEach((level1) => {
level1.children.forEach((level2) => {
level2.children.forEach((level3) => {
level3Ids.push(level3.id); }); }); }); this.$refs.allroles.setCheckedKeys(level3Ids); }); }, //获取权限管理数据 getallrolestree() {
this.$http.get("/rights/tree").then((res) => {
console.log(res); const {
data, meta } = res.data; if (meta.status === 200) {
this.allrolesList = data; } }); }, //修改权限管理 putallroles() {
const checked = this.$refs.allroles.getCheckedKeys(); const halfchecked = this.$refs.allroles.getHalfCheckedKeys(); const allchecked = [...checked, ...halfchecked]; console.log(allchecked); const id = this.rid; this.$http .post(`/roles/${
id}/rights`, {
rids: allchecked.join(","), }) .then((res) => {
this.rolesdialog = false; this.getrolesdata(); }); }, }, }; </script> <style> </style>
路由
import Vue from 'vue' import Router from 'vue-router' import Login from '@/components/login/Login' import Home from '@/components/home/Home' import Users from '@/components/users/Users' import Rights from '@/components/rights/Rights' import Roles from '@/components/roles/Roles' Vue.use(Router) const router = new Router({
//定制路由规则 routes: [ {
path: '/Home', component: Home, children: [{
path: 'Users', component: Users},{
path: '/Rights', component: Rights},{
path: '/Roles', component: Roles}] }, {
path: '/Login', component: Login } ], }) //导航守卫 router.beforeEach((to, from, next) => {
if (to.path === '/login') {
next(); } else {
const token = localStorage.getItem('token'); if (token) {
next(); } else {
next('/login'); } } }) export default router;
总结
这个项目是合作制作完成的,是一个模块化,组件化开发的小项目,我负责前端页面的设计,前端功能的实现,在合作的过程中统一了接口文档,设计等。项目开始的时候,没有接口只能自己用mock方案做假数据,搭项目,进行开发,在实现的过程中我遇到一些困难,我便查看官方文档,上网查看讨论交流所遇到的困难之处,并最后解决问题,也感谢CSDN的网友给我解决了很多困难,让我在代码路上再接再厉,加油。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/217038.html原文链接:https://javaforall.net
