• Java 之SpringBoot+Vue实现后台管理系统的开发【一、前端】


    一、前端项目搭建

    1、项目初始化

    安装 vue可视化

    npm install --g vue-cli
    
    • 1

    打开vue的的可视化管理工具页面

    vue ui
    
    • 1

    访问该地址:
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    访问成功
    在这里插入图片描述
    使用Hbuilder打开项目
    在这里插入图片描述

    2、实现相关依赖的安装

    在这里插入图片描述
    安装 element-ui

    yarn add element-ui
    
    • 1

    安装成功
    在这里插入图片描述
    引入element-ui
    在这里插入图片描述

    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    
    
    Vue.config.productionTip = false
    
    Vue.use(ElementUI);
    
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    安装axios
    axios:一个基于promise的HTTP库,类ajax

    yarn add axios
    
    • 1

    在这里插入图片描述

    引入全局axios
    在这里插入图片描述

    import axios from 'axios'
    Vue.prototype.$axios = axios
    
    • 1
    • 2

    安装qs
    qs:查询参数序列化和解析库

    yarn add qs
    
    • 1

    安装mockjs
    mockjs:为我们生成随机数据的工具库

    yarn add mockjs
    
    • 1

    3、设置页面路由

    删除页面的自动创建好的页面
    在这里插入图片描述
    在这里插入图片描述
    创建一些自定义页面
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    设置路由
    在这里插入图片描述

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    
    Vue.use(VueRouter)
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/login',
        name: 'Login',
        component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
      }
    ]
    
    const router = new VueRouter({
      mode: 'history',
      base: process.env.BASE_URL,
      routes
    })
    
    export default router
    
    
    • 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

    设置登录页面
    找到Element UI的页面
    在这里插入图片描述
    在这里插入图片描述

    <template>
    
    	<div>
    		<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
    			<el-form-item label="活动名称" prop="name">
    				<el-input v-model="ruleForm.name"></el-input>
    		 </el-form-item>
    			<el-form-item label="活动区域" prop="region">
    				<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
    					<el-option label="区域一" value="shanghai"></el-option>
    					<el-option label="区域二" value="beijing"></el-option>
    				</el-select>
    			</el-form-item>
    			<el-form-item label="活动时间" required>
    				<el-col :span="11">
    					<el-form-item prop="date1">
    						<el-date-picker type="date" placeholder="选择日期" v-model="ruleForm.date1" style="width: 100%;">
    						</el-date-picker>
    					</el-form-item>
    				</el-col>
    				<el-col class="line" :span="2">-</el-col>
    				<el-col :span="11">
    					<el-form-item prop="date2">
    						<el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;">
    						</el-time-picker>
    					</el-form-item>
    				</el-col>
    			</el-form-item>
    			<el-form-item label="即时配送" prop="delivery">
    				<el-switch v-model="ruleForm.delivery"></el-switch>
    			</el-form-item>
    			<el-form-item label="活动性质" prop="type">
    				<el-checkbox-group v-model="ruleForm.type">
    					<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
    					<el-checkbox label="地推活动" name="type"></el-checkbox>
    					<el-checkbox label="线下主题活动" name="type"></el-checkbox>
    					<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
    				</el-checkbox-group>
    			</el-form-item>
    			<el-form-item label="特殊资源" prop="resource">
    				<el-radio-group v-model="ruleForm.resource">
    					<el-radio label="线上品牌商赞助"></el-radio>
    					<el-radio label="线下场地免费"></el-radio>
    				</el-radio-group>
    			</el-form-item>
    			<el-form-item label="活动形式" prop="desc">
    				<el-input type="textarea" v-model="ruleForm.desc"></el-input>
    			</el-form-item>
    			<el-form-item>
    				<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
    				<el-button @click="resetForm('ruleForm')">重置</el-button>
    			</el-form-item>
    		</el-form>
    	</div>
    
    </template>
    
    <script>
    	export default {
    		data() {
    			return {
    				ruleForm: {
    					name: '',
    					region: '',
    					date1: '',
    					date2: '',
    					delivery: false,
    					type: [],
    					resource: '',
    					desc: ''
    				},
    				rules: {
    					name: [{
    							required: true,
    							message: '请输入活动名称',
    							trigger: 'blur'
    						},
    						{
    							min: 3,
    							max: 5,
    							message: '长度在 3 到 5 个字符',
    							trigger: 'blur'
    						}
    					],
    					region: [{
    						required: true,
    						message: '请选择活动区域',
    						trigger: 'change'
    					}],
    					date1: [{
    						type: 'date',
    						required: true,
    						message: '请选择日期',
    						trigger: 'change'
    					}],
    					date2: [{
    						type: 'date',
    						required: true,
    						message: '请选择时间',
    						trigger: 'change'
    					}],
    					type: [{
    						type: 'array',
    						required: true,
    						message: '请至少选择一个活动性质',
    						trigger: 'change'
    					}],
    					resource: [{
    						required: true,
    						message: '请选择活动资源',
    						trigger: 'change'
    					}],
    					desc: [{
    						required: true,
    						message: '请填写活动形式',
    						trigger: 'blur'
    					}]
    				}
    			};
    		},
    		methods: {
    			submitForm(formName) {
    				this.$refs[formName].validate((valid) => {
    					if (valid) {
    						alert('submit!');
    					} else {
    						console.log('error submit!!');
    						return false;
    					}
    				});
    			},
    			resetForm(formName) {
    				this.$refs[formName].resetFields();
    			}
    		}
    	}
    </script>
    
    <style>
    </style>
    
    
    • 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

    运行测试
    http://localhost:8080/login

    在这里插入图片描述
    修改页面设置为登录页面
    在这里插入图片描述

    <template>
    
    	<div>
    		<el-row class="elrow" type="flex" justify="center">
    			<el-col :span="8">
    				<el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="100px" class="demo-loginForm">
    					<el-form-item label="账号" prop="username" style="width: 380px;">
    						<el-input v-model="loginForm.username"></el-input>
    					</el-form-item>
    					<el-form-item label="密码" prop="password" style="width: 380px;">
    						<el-input placeholder="请输入密码" v-model="loginForm.password" show-password></el-input>
    					</el-form-item>
    					<el-form-item label="验证码" prop="code" style="width: 380px;">
    						<el-input v-model="loginForm.code" style="width: 172px;float: left;"></el-input>
    						<el-image style="width: 80px; height: 40px;float: left;padding-left: 25px;" :src="url" :fit="fit"></el-image>
    					</el-form-item>
    					<el-form-item style="width: 380px;">
    						<el-button type="primary" @click="submitForm('loginForm')">登录</el-button>
    						<el-button @click="resetForm('loginForm')">重置</el-button>
    					</el-form-item>
    				</el-form>
    			</el-col>
    		</el-row>
    	</div>
    </template>
    
    <script>
    	export default {
    		data() {
    			return {
    				loginForm: {
    					username: '',
    					password: '',
    					code:'',
    				},
    				rules: {
    					username: [ {
    						required: true,
    						message: '请输入用户名',
    						trigger: 'blur'
    					}],
    					password: [{
    						required: true,
    						message: '请设置密码',
    						trigger: 'blur'
    					}],
    					code: [{
    						required: true,
    						message: '请输入验证码',
    						trigger: 'change'
    					}]
    				}
    			};
    		},
    		methods: {
    			submitForm(formName) {
    				this.$refs[formName].validate((valid) => {
    					if (valid) {
    						alert('submit!');
    					} else {
    						console.log('error submit!!');
    						return false;
    					}
    				});
    			},
    			resetForm(formName) {
    				this.$refs[formName].resetFields();
    			}
    		}
    	}
    </script>
    
    <style scoped>
    	
    	.elrow{
    		display: flex;
    		align-items: center;
    		text-align: center;
    		height:100%;
    	}
    	
    </style>
    
    
    • 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

    4、设置前端发起请求,设置验证码相关内容

    在这里插入图片描述

    <template>
    
    	<div>
    		<el-row class="elrow" type="flex" justify="center">
    			<el-col :span="8">
    				<el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="100px" class="demo-loginForm">
    					<el-form-item label="账号" prop="username" style="width: 380px;">
    						<el-input v-model="loginForm.username"></el-input>
    					</el-form-item>
    					<el-form-item label="密码" prop="password" style="width: 380px;">
    						<el-input placeholder="请输入密码" v-model="loginForm.password" show-password></el-input>
    					</el-form-item>
    					<el-form-item label="验证码" prop="code" style="width: 380px;">
    						<el-input v-model="loginForm.code" style="width: 172px;float: left;"></el-input>
    						<el-image style="width: 80px; height: 40px;float: left;padding-left: 25px;" :src="captchaImg" :fit="fit"></el-image>
    					</el-form-item>
    					<el-form-item style="width: 380px;">
    						<el-button type="primary" @click="submitForm('loginForm')">登录</el-button>
    						<el-button @click="resetForm('loginForm')">重置</el-button>
    					</el-form-item>
    				</el-form>
    			</el-col>
    		</el-row>
    	</div>
    </template>
    
    <script>
    	export default {
    		data() {
    			return {
    				loginForm: {
    					username: '',
    					password: '',
    					code:'',
    					token:''
    				},
    				rules: {
    					username: [ {
    						required: true,
    						message: '请输入用户名',
    						trigger: 'blur'
    					}],
    					password: [{
    						required: true,
    						message: '请设置密码',
    						trigger: 'blur'
    					}],
    					code: [{
    						required: true,
    						message: '请输入验证码',
    						trigger: 'change'
    					}]
    				},
    				captchaImg:null
    			};
    		},
    		methods: {
    			submitForm(formName) {
    				this.$refs[formName].validate((valid) => {
    					if (valid) {
    						this.$axios.post("url",this.loginForm).then(res =>{
    						})
    					} else {
    						console.log('error submit!!');
    						return false;
    					}
    				});
    			},
    			resetForm(formName) {
    				this.$refs[formName].resetFields();
    			},
    			getCaptcha(){
    				this.$axios.post("/captcha").then(res =>{
    					this.loginForm.token = res.data.data.token;
    					this.captchaImg = res.data.data.captchaImg;
    				})
    			}
    			//Result - code、msg、data
    		}
    	}
    </script>
    
    <style scoped>
    	
    	.elrow{
    		display: flex;
    		align-items: center;
    		text-align: center;
    		height:100%;
    	}
    	
    </style>
    
    
    • 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

    5、创建mock.js

    在这里插入图片描述
    在main.js当中引入mock.js
    在这里插入图片描述

    require("./mock.js")
    
    • 1

    完善mock.js
    在这里插入图片描述

    const Mock = require('mockjs')
    
    const Random = Mock.Random
    
    let Result = {
    	code: 200,
    	msg: '操作成功',
    	data: null
    }
    
    Mock.mock('/captcha','get',()=>{
    	Result.data = {
    		token: Random.string(32),
    		captchaImg:Random.dataImage('120x40','p7n5w')
    	}
    	return Result;
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    修改Login.vue,设置发起请求
    在这里插入图片描述

    		   getCaptcha(){
    				this.$axios.get("/captcha").then(res =>{
    					console.log("/captcha")
    					console.log(res)
    					this.loginForm.token = res.data.data.token;
    					this.captchaImg = res.data.data.captchaImg;
    				})
    			}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查看页面
    http://localhost:8080/login
    在这里插入图片描述

    6、在store当中的index.js设置SET_TOKEN

    在这里插入图片描述

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
    	  token:''
      },
      getters: {
    	  
      },
      mutations: {
    	  SET_TOKEN:(state, token ) =>{
    		  state.token = token
    		  localStorage.setItem("token",token)
    	  } 
      },
      actions: {
      },
      modules: {
      }
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    7、完善登录的请求

    		 submitForm(formName) {
    				this.$refs[formName].validate((valid) => {
    					if (valid) {
    						this.$axios.post("/login",this.loginForm).then(res =>{
    							const jwt = res.headers['authorization']
    							this.$store.commit('SET_TOKEN',jwt);
    							this.$router.push("/home")
    						})
    					} else {
    						console.log('error submit!!');
    						return false;
    					}
    				});
    			},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    设置mock.js
    在这里插入图片描述

    Mock.mock('/login','post',()=>{
    	//无法在header当中存入jwt
    	return Result;
    })
    
    • 1
    • 2
    • 3
    • 4

    在登录页测试
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    8、定义全局axios拦截器

    在这里插入图片描述
    在这里插入图片描述

    import axios from "axios"
    import router from "./router"
    import Element from "element-ui"
    
    //axios.defaults.baseURL = "http://localhost:8081"
    
    const request = axios.create({
    	timeout: 5000,
    	headers: {
    		'Content-Type': "application/json;charset=utf-8"
    	}
    })
    request.interceptors.request.use(config => {
    	config.headers['Authorization'] = localStorage.getItem("token")
    	return config;
    });
    request.interceptors.response.use(response => {
    		let res = response.data
    		
    		if (res.code === 200) {
    			return response
    		} else {
    			Element.Message.error(!res.msg ? '系统异常' : res.msg)
    			return Promise.reject(response.data.msg)
    		}
    	}, error => {
    		
    		if (error.response.data) {
    			error.message = error.response.data.msg
    		}
    		if (error.response.status === 401) {
    			router.push("/login")
    		}
    		Element.Message.error(error.message, { duration: 3000 })
    		return Promise.reject(error)
    	}
    )
    
    export default request
    
    
    • 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

    在main.js当中引入axios.js

    在这里插入图片描述
    在mock.js当中这请求返回数据
    在这里插入图片描述

    Mock.mock('/login','post',()=>{
    	//无法在header当中存入jwt
    	
    	Result.code = 404
    	Result.msg = "验证码错误"
    	
    	return Result;
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    的登录页面发起请求测试
    在这里插入图片描述
    在这里插入图片描述

    二、后台管理界面开发

    1、创建index.vue

    一般来说,管理系统的页面我们都是头部是一个简单的信息展示系统名称和登录用户信息,然后中间的左边是菜单导航栏,右边是内容,对应到elementui的组件中,我们可以找到这个
    Container布局容器用于布局,方便快速搭建页面的基本结构。
    而我们采用这个布局:

    在这里插入图片描述
    直接使用Element UI提供的布局

    创建index.vue
    在这里插入图片描述

    在这里插入图片描述

    <template>
    	
    	<div>
    		
    		<el-container>
    		  <el-aside width="200px">Aside</el-aside>
    		  <el-container>
    		    <el-header>Header</el-header>
    		    <el-main>Main</el-main>
    		  </el-container>
    		</el-container>
    		
    	</div>
    	
    </template>
    
    <script>
    </script>
    
    <style>
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2、设置页面路由和跳转路径

    在这里插入图片描述

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    import Index from '../views/index.vue'
    
    Vue.use(VueRouter)
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: 'index',
        name: 'Index',
        component: Index
      },
      {
        path: '/login',
        name: 'Login',
        component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
      }
    ]
    
    const router = new VueRouter({
      mode: 'history',
      base: process.env.BASE_URL,
      routes
    })
    
    export default router
    
    
    • 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

    设置跳转路径在这里插入图片描述

    在这里插入图片描述
    设置一下状态码使其跳转成功
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    3、设置页面布局

    引入一些ELement UI提供的样式
    在这里插入图片描述

    
    <style>
    	.el-header, .el-footer {
    	    background-color: #B3C0D1;
    	    color: #333;
    	    text-align: center;
    	    line-height: 60px;
    	  }
    	  
    	  .el-aside {
    	    background-color: #D3DCE6;
    	    color: #333;
    	    text-align: center;
    	    line-height: 200px;
    	  }
    	  
    	  .el-main {
    	    background-color: #E9EEF3;
    	    color: #333;
    	    text-align: center;
    	    line-height: 160px;
    	  }
    	  
    	  body > .el-container {
    	    margin-bottom: 40px;
    	  }
    	  
    	  .el-container:nth-child(5) .el-aside,
    	  .el-container:nth-child(6) .el-aside {
    	    line-height: 260px;
    	  }
    	  
    	  .el-container:nth-child(7) .el-aside {
    	    line-height: 320px;
    	  }
    	  .el-container{
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    	
    </style>
    
    • 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

    在这里插入图片描述
    设置一些元件
    在这里插入图片描述

    <template>
    	
    		
    		<el-container>
    		  <el-aside width="200px">Aside</el-aside>
    		  <el-container>
    		    <el-header>
    				<strong>xxx后台管理系统</strong>
    				
    				<div class="header-avatar">
    					
    					<el-avatar size="medium" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"></el-avatar>
    					<el-dropdown>
    					  <span class="el-dropdown-link">
    					    Admin<i class="el-icon-arrow-down el-icon--right"></i>
    					  </span>
    					  <el-dropdown-menu slot="dropdown">
    					    <el-dropdown-item>个人中心</el-dropdown-item>
    					    <el-dropdown-item>退出</el-dropdown-item>
    					  </el-dropdown-menu>
    					</el-dropdown>	
    					
    					<el-link href="" target="_blank">网站</el-link>
    					<el-link href="" target="_blank">B站</el-link>					
    				</div>
    				
    			</el-header>
    		    <el-main>Main</el-main>
    		  </el-container>
    		</el-container>
    		
    	
    </template>
    
    <script>
    </script>
    
    <style>
    	
    	.header-avatar{
    		
    		float: right;
    		width: 210px;
    		display: flex;
    		justify-content: space-around;
    		align-items: center;
    		
    		
    	}
    	
    	body  {
    	  margin: 0;
    	  padding: 0;
    	  height: 100%;
    	}
    	
    	.template{
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    	
    	.el-dropdown-link{
    		cursor: pointer;
    		color: #409EFF;
    	}
    
    	.el-container{
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    	
    	.el-header, .el-footer {
    	    background-color: #B3C0D1;
    	    color: #333;
    	    text-align: center;
    	    line-height: 60px;
    	  }
    	  
    	  .el-aside {
    	    background-color: #D3DCE6;
    	    color: #333;
    	    text-align: center;
    	    line-height: 200px;
    	  }
    	  
    	  .el-main {
    	    background-color: #E9EEF3;
    	    color: #333;
    	    text-align: center;
    	    line-height: 160px;
    	  }
    	  
    	  
    	  .el-container:nth-child(5) .el-aside,
    	  .el-container:nth-child(6) .el-aside {
    	    line-height: 260px;
    	  }
    	  
    	  .el-container:nth-child(7) .el-aside {
    	    line-height: 320px;
    	  }
    </style>
    
    
    • 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

    在这里插入图片描述

    4、设置左侧导航

    在这里插入图片描述

    <template>
    
    
    	<el-container>
    		<el-aside width="200px">
    			<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
    				background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
    				
    				<el-menu-item index="0">
    					<template slot="title">
    						<i class="el-icon-s-home"></i>
    						<span slot="title">主页</span>
    					</template>
    				</el-menu-item>
    				<el-submenu index="1">
    					<template slot="title">
    						<i class="el-icon-location"></i>
    						<span>系统管理</span>
    					</template>
    					<el-menu-item-group>
    						<el-menu-item index="1-1">用户管理</el-menu-item>
    						<el-menu-item index="1-2">角色管理</el-menu-item>
    						<el-menu-item index="1-2">菜单管理</el-menu-item>
    					</el-menu-item-group>
    				</el-submenu>
    				<el-submenu index="2">
    					<template slot="title">
    						<i class="el-icon-location"></i>
    						<span>系统工具</span>
    					</template>
    					<el-menu-item-group>
    						<el-menu-item index="1-1">数字字典</el-menu-item>
    					</el-menu-item-group>
    				</el-submenu>
    			</el-menu>
    
    
    		</el-aside>
    		<el-container>
    			<el-header>
    				<strong>xxx后台管理系统</strong>
    
    				<div class="header-avatar">
    
    					<el-avatar size="medium" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png">
    					</el-avatar>
    					<el-dropdown>
    						<span class="el-dropdown-link">
    							Admin<i class="el-icon-arrow-down el-icon--right"></i>
    						</span>
    						<el-dropdown-menu slot="dropdown">
    							<el-dropdown-item>个人中心</el-dropdown-item>
    							<el-dropdown-item>退出</el-dropdown-item>
    						</el-dropdown-menu>
    					</el-dropdown>
    
    					<el-link href="" target="_blank">网站</el-link>
    					<el-link href="" target="_blank">B站</el-link>
    				</div>
    
    			</el-header>
    			<el-main>Main</el-main>
    		</el-container>
    	</el-container>
    
    
    </template>
    
    <script>
    </script>
    
    <style>
    	.header-avatar {
    		float: right;
    		width: 210px;
    		display: flex;
    		justify-content: space-around;
    		align-items: center;
    	}
    
    	body {
    		margin: 0;
    		padding: 0;
    		height: 100%;
    	}
    	
    	.el-aside{
    		background-color: #545c64;
    	}
    
    	.template {
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    
    	.el-dropdown-link {
    		cursor: pointer;
    		color: #409EFF;
    	}
    
    	.el-container {
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    
    	.el-header  {
    		background-color: #0bd18f;
    		color: #333;
    		text-align: center;
    		line-height: 60px;
    	}
    
    
    	.el-main {
    		color: #333;
    		text-align: center;
    		line-height: 160px;
    	}
    
    
    </style>
    
    
    • 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

    在这里插入图片描述

    5、Vue代码抽取

    (1)抽取菜单

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    <template>
    	<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
    		background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
    		<el-menu-item index="0">
    			<template slot="title">
    				<i class="el-icon-s-home"></i>
    				<span slot="title">主页</span>
    			</template>
    		</el-menu-item>
    		<el-submenu index="1">
    			<template slot="title">
    				<i class="el-icon-location"></i>
    				<span>系统管理</span>
    			</template>
    			<el-menu-item-group>
    				<el-menu-item index="1-1">用户管理</el-menu-item>
    				<el-menu-item index="1-2">角色管理</el-menu-item>
    				<el-menu-item index="1-2">菜单管理</el-menu-item>
    			</el-menu-item-group>
    		</el-submenu>
    		<el-submenu index="2">
    			<template slot="title">
    				<i class="el-icon-location"></i>
    				<span>系统工具</span>
    			</template>
    			<el-menu-item-group>
    				<el-menu-item index="1-1">数字字典</el-menu-item>
    			</el-menu-item-group>
    		</el-submenu>
    	</el-menu>
    	
    </template>
    
    <script>
    </script>
    
    <style>
    	
    	.el-menu-vertical-demo{
    		height: 100%;
    	}
    	
    </style>
    
    
    • 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

    在index.vue当中引用SideMenu
    在这里插入图片描述
    在这里插入图片描述

    <template>
    
    
    	<el-container>
    		<el-aside width="200px">
    			
    			<SideMenu></SideMenu>
    			
    
    		</el-aside>
    		<el-container>
    			<el-header>
    				<strong>xxx后台管理系统</strong>
    
    				<div class="header-avatar">
    
    					<el-avatar size="medium" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png">
    					</el-avatar>
    					<el-dropdown>
    						<span class="el-dropdown-link">
    							Admin<i class="el-icon-arrow-down el-icon--right"></i>
    						</span>
    						<el-dropdown-menu slot="dropdown">
    							<el-dropdown-item>个人中心</el-dropdown-item>
    							<el-dropdown-item>退出</el-dropdown-item>
    						</el-dropdown-menu>
    					</el-dropdown>
    
    					<el-link href="" target="_blank">网站</el-link>
    					<el-link href="" target="_blank">B站</el-link>
    				</div>
    
    			</el-header>
    			<el-main>Main</el-main>
    		</el-container>
    	</el-container>
    
    
    </template>
    
    <script>
    	
    	import SideMenu from "./inc/SideMenu.vue"
    	export default{
    		name: "Index",
    		components:{
    			SideMenu
    		}
    	}
    	
    </script>
    
    <style>
    	.header-avatar {
    		float: right;
    		width: 210px;
    		display: flex;
    		justify-content: space-around;
    		align-items: center;
    	}
    
    	body {
    		margin: 0;
    		padding: 0;
    		height: 100%;
    	}
    	
    	.el-aside{
    		background-color: #545c64;
    	}
    
    	.template {
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    
    	.el-dropdown-link {
    		cursor: pointer;
    		color: #409EFF;
    	}
    
    	.el-container {
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    
    	.el-header  {
    		background-color: #0bd18f;
    		color: #333;
    		text-align: center;
    		line-height: 60px;
    	}
    
    </style>
    
    • 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

    最后效果
    在这里插入图片描述

    (2)index

    将index.vue的内容全部抽取到Home
    在这里插入图片描述

    <template>
    	
    	
    	<el-container>
    		<el-aside width="200px">
    			<SideMenu></SideMenu>
    		</el-aside>
    		<el-container>
    			<el-header>
    				<strong>xxx后台管理系统</strong>
    				<div class="header-avatar">
    					<el-avatar size="medium" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png">
    					</el-avatar>
    					<el-dropdown>
    						<span class="el-dropdown-link">
    							Admin<i class="el-icon-arrow-down el-icon--right"></i>
    						</span>
    						<el-dropdown-menu slot="dropdown">
    							<el-dropdown-item>个人中心</el-dropdown-item>
    							<el-dropdown-item>退出</el-dropdown-item>
    						</el-dropdown-menu>
    					</el-dropdown>
    					<el-link href="" target="_blank">网站</el-link>
    					<el-link href="" target="_blank">B站</el-link>
    				</div>
    			</el-header>
    			<el-main>Main</el-main>
    		</el-container>
    	</el-container>
    </template>
    <script>
    	import SideMenu from "./inc/SideMenu.vue"
    	export default{
    		name: "Home",
    		components:{
    			SideMenu
    		}
    	}
    </script>
    
    <style>
    </style>
    
    
    • 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

    index.vue当中
    在这里插入图片描述
    访问页面:http://localhost:8080/index
    访问也发现空白
    在这里插入图片描述

    (3)设置子路由

    在这里插入图片描述

    	children:[
    		{
    			path:'/index',
    			name:'Index',
    			component:Index
    		}
    	]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    再次访问:
    在这里插入图片描述
    但是我们发现上面没有index的内容

    设置内容
    在这里插入图片描述

    				<router-view>
    				</router-view>
    
    • 1
    • 2

    在这里插入图片描述

    6、编写导航栏路由

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    <template>
    	<div>用户管理</div>
    </template>
    
    <script>
    </script>
    
    <style>
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    <template>
    	<div>角色管理</div>
    </template>
    
    <script>
    </script>
    
    <style>
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    <template>
    	<div>菜单管理</div>	
    </template>
    
    <script>
    </script>
    
    <style>
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    设置子路由
    在这里插入图片描述
    在这里插入图片描述

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    import Index from '../views/index.vue'
    import Menu from '../views/sys/Menu.vue'
    import Role from '../views/sys/Role.vue'
    import User from '../views/sys/User.vue'
    Vue.use(VueRouter)
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home,
    	children:[
    		{
    			path:'/index',
    			name:'Index',
    			component:Index
    		},
    		{
    			path:'/users',
    			name:'SysUser',
    			component:User
    		},
    		{
    			path:'/roles',
    			name:'SysRole',
    			component:Role
    		},
    		{
    			path:'/menus',
    			name:'SysMenu',
    			component:Menu
    		}
    	]
      },
      {
        path: '/index',
        name: 'Index',
        component: Index
      },
      {
        path: '/login',
        name: 'Login',
        component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
      }
    ]
    const router = new VueRouter({
      mode: 'history',
      base: process.env.BASE_URL,
      routes
    })
    export default router
    
    • 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

    访问:http://localhost:8080/roles

    在这里插入图片描述
    http://localhost:8080/users

    在这里插入图片描述
    http://localhost:8080/menus

    在这里插入图片描述

    设置页面路由
    在这里插入图片描述

    <template>
    	<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
    		background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
    		
    		<router-link to="/index">
    			<el-menu-item index="0">
    				<template slot="title">
    					<i class="el-icon-s-home"></i>
    					<span slot="title">主页</span>
    				</template>
    			</el-menu-item>
    		</router-link>
    		
    			<el-submenu index="1">
    				<template slot="title">
    					<i class="el-icon-location"></i>
    					<span>系统管理</span>
    				</template>
    				<el-menu-item-group>
    					<router-link to="/users">
    						<el-menu-item index="1-1">
    							<template>
    								<i class="el-icon-s-custom" ></i>
    								<span>用户管理</span>
    							</template>
    							
    						</el-menu-item>
    					</router-link>
    					<router-link to="/roles">
    						<el-menu-item index="1-2">
    							<template>
    								<i class="el-icon-rank" ></i>
    								<span>角色管理</span>
    							</template>
    						</el-menu-item>
    					</router-link>
    					<router-link to="/menus">
    						<el-menu-item index="1-3">
    							<template>
    								<i class="el-icon-menu" ></i>
    								<span>菜单管理</span>
    							</template>
    						</el-menu-item>
    					</router-link>
    				</el-menu-item-group>
    			</el-submenu>
    		
    		<el-submenu index="2">
    			<template slot="title">
    				<i class="el-icon-location"></i>
    				<span>系统工具</span>
    			</template>
    			<el-menu-item-group>
    				<el-menu-item index="2-1">
    					<template>
    						<i class="el-icon-menu" ></i>
    						<span>数字字典</span>
    					</template>
    				</el-menu-item>
    			</el-menu-item-group>
    		</el-submenu>
    	</el-menu>
    </template>
    <script>
    	export default{
    		name: "SideMenu",
    	}
    </script>
    <style>
    	.header-avatar {
    		float: right;
    		width: 210px;
    		display: flex;
    		justify-content: space-around;
    		align-items: center;
    	}
    
    	body {
    		margin: 0;
    		padding: 0;
    		height: 100%;
    	}
    
    	.el-aside {
    		background-color: #545c64;
    	}
    
    	.template {
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    
    	.el-dropdown-link {
    		cursor: pointer;
    		color: #409EFF;
    	}
    
    	.el-container {
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    
    	.el-header {
    		background-color: #0bd18f;
    		color: #333;
    		text-align: center;
    		line-height: 60px;
    	}
    </style>
    
    
    • 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

    点击测试
    在这里插入图片描述

    三、用户登录信息展示

    管理界面的右上角的用户信息现在是写死的,
    因为我们现在已经登录成功,所以我们可以通过接口去请求获取到当前的用户信息了,
    这样我们就可以动态显示用户的信息,这个接口比较简单,然后退出登录的链接也一起完成,
    就请求接口同时把浏览器中的缓存删除就退出了哈。

    1、实现用户信息页面编写

    在这里插入图片描述
    在这里插入图片描述

    <template>
    	
    	
    	<el-container>
    		<el-aside width="200px">
    			<SideMenu></SideMenu>
    		</el-aside>
    		<el-container>
    			<el-header>
    				<strong>xxx后台管理系统</strong>
    				<div class="header-avatar">
    					<el-avatar size="medium" :src="userInfo.avatar">
    					</el-avatar>
    					<el-dropdown>
    						<span class="el-dropdown-link">
    							{{userInfo.username}}<i class="el-icon-arrow-down el-icon--right"></i>
    						</span>
    						<el-dropdown-menu slot="dropdown">
    							<el-dropdown-item>个人中心</el-dropdown-item>
    							<el-dropdown-item>退出</el-dropdown-item>
    						</el-dropdown-menu>
    					</el-dropdown>
    					<el-link href="" target="_blank">网站</el-link>
    					<el-link href="" target="_blank">B</el-link>
    				</div>
    			</el-header>
    			<el-main>
    				
    				<router-view>
    					
    				</router-view>
    				
    			</el-main>
    		</el-container>
    	</el-container>
    </template>
    <script>
    	import SideMenu from "./inc/SideMenu.vue"
    	export default{
    		name: "Home",
    		components:{
    			SideMenu
    		},
    		data(){
    			return {
    				userInfo:{
    					id:"",
    					username:"",
    					avatar:""
    				}
    			}
    		},
    		created() {
    			this.getUserInfo();
    		},
    		methods:{
    			getUserInfo(){
    				this.$axios.get("/sys/userInfo").then(res =>{
    					this.userInfo= res.data.data;
    				})
    			}
    		}
    	}
    </script>
    <style>
    </style>
    
    • 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

    2、设置mock.js

    在这里插入图片描述

    Mock.mock('/sys/userInfo','get',()=>{
    	//无法在header当中存入jwt
    	Result.data = {
    		id:"1",
    		username:"test",
    		avatar:"https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
    	}
    	return Result;
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    3、设置个人中心的路由

    在这里插入图片描述

    	<router-link to="/userCenter"> 个人中心 </router-link>
    
    • 1

    在这里插入图片描述

    {
    			path:'/userCenter',
    			name:'UserCenter',
    			component: () => import('../views/UserCenter.vue')
    		},
    
    • 1
    • 2
    • 3
    • 4
    • 5

    创建UserCenter.vue
    在这里插入图片描述
    在这里插入图片描述

    <template>
    	
    	<div>
    		
    		<el-row class="elrow" type="flex" justify="center">
    			<el-col :span="8">
    				<el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="100px" class="demo-loginForm">
    					<div>修改用户信息</div>
    					<el-form-item label="账号" prop="username" style="width: 380px;">
    						<el-input v-model="loginForm.username"></el-input>
    					</el-form-item>
    					<el-form-item label="密码" prop="password" style="width: 380px;">
    						<el-input placeholder="请输入密码" v-model="loginForm.password" show-password></el-input>
    					</el-form-item>
    					<el-form-item label="验证码" prop="code" style="width: 380px;">
    						<el-input v-model="loginForm.code" style="width: 172px;float: left;"></el-input>
    						<el-image style="width: 80px; height: 40px;float: left;padding-left: 25px;" :src="captchaImg" ></el-image>
    					</el-form-item>
    					<el-form-item style="width: 380px;">
    						<el-button type="primary" @click="submitForm('loginForm')">修改</el-button>
    						<el-button @click="resetForm('loginForm')">重置</el-button>
    					</el-form-item>
    				</el-form>
    			</el-col>
    		</el-row>
    	</div>
    	
    </template>
    
    
    <script>
    	export default {
    		data() {
    			return {
    				loginForm: {
    					
    					username: '',
    					password: '',
    					code:'',
    					token:''
    				},
    				rules: {
    					username: [ {
    						required: true,
    						message: '请输入用户名',
    						trigger: 'blur'
    					}],
    					password: [{
    						required: true,
    						message: '请设置密码',
    						trigger: 'blur'
    					}],
    					code: [{
    						required: true,
    						message: '请输入验证码',
    						trigger: 'change'
    					}]
    				},
    				captchaImg:null
    			};
    		},
    		methods: {
    			submitForm(formName) {
    				this.$refs[formName].validate((valid) => {
    					if (valid) {
    						this.$axios.post("/updateUser",this.loginForm).then(res =>{
    							const jwt = res.headers['authorization']
    							this.$store.commit('SET_TOKEN',jwt);
    							this.$router.push("/index")
    						})
    					} else {
    						console.log('error submit!!');
    						return false;
    					}
    				});
    			},
    			resetForm(formName) {
    				this.$refs[formName].resetFields();
    			},
    			getCaptcha(){
    				this.$axios.get("/captcha").then(res =>{
    					console.log("/captcha")
    					console.log(res)
    					this.loginForm.token = res.data.data.token;
    					this.captchaImg = res.data.data.captchaImg;
    				})
    			}
    			//Result - code、msg、data
    		},
    		created() {
    			this.getCaptcha();
    		}
    	}
    </script>
    
    <style scoped>
    	
    	.elrow{
    		display: flex;
    		align-items: center;
    		text-align: center;
    		height:100%;
    	}
    	
    </style>
    
    
    
    • 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

    在这里插入图片描述
    在这里插入图片描述

    4、设置退出登录

    在这里插入图片描述

    <el-dropdown-item @click.native="logout" >退出</el-dropdown-item>
    
    • 1

    在这里插入图片描述

    		   logout(){
    				this.$axios.post("/logout").then(res =>{
    					localStorage.clear();
    					sessionStorage.clear();
    					this.$store.commit("resetState");
    					this.$router.push("/login")
    				})
    			}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

      resetState:(state) =>{
    		  state.token = ''
    	  }
    
    • 1
    • 2
    • 3

    设置模拟登出
    在这里插入图片描述

    Mock.mock('/logout','post',()=>{
    	return Result;
    })
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    在这里插入图片描述

    四、动态菜单栏的开发

    1、修改一下路由规则

    在这里插入图片描述

    	   {
    			path:'/sys/users',
    			name:'SysUser',
    			component:User
    		},
    		{
    			path:'/sys/roles',
    			name:'SysRole',
    			component:Role
    		},
    		{
    			path:'/sys/menus',
    			name:'SysMenu',
    			component:Menu
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2、设置动态菜单的数据

    在这里插入图片描述

    <template>
    	<el-menu default-active="2" class="el-menu-vertical-demo" background-color="#545c64" text-color="#fff"
    		active-text-color="#ffd04b">
    
    		<router-link to="/index">
    			<el-menu-item index="0">
    				<template slot="title">
    					<i class="el-icon-s-home"></i>
    					<span slot="title">主页</span>
    				</template>
    			</el-menu-item>
    		</router-link>
    
    		<el-submenu :index="menu.name" v-for="menu in menuList">
    			<template slot="title">
    				<i :class="menu.icon"></i>
    				<span>{{menu.title}}</span>
    			</template>
    			<el-menu-item-group>
    				<router-link :to="item.path" v-for="item in menu.children">
    					<el-menu-item :index="item.name">
    						<template>
    							<i :class="item.icon"></i>
    							<span slot="title">{{item.title}}</span>
    						</template>
    					</el-menu-item>
    				</router-link>
    			</el-menu-item-group>
    		</el-submenu>
    	</el-menu>
    </template>
    <script>
    	export default {
    		name: "SideMenu",
    		data() {
    			return {
    				menuList: [{
    						title: '系统管理',
    						name: 'SysMange',
    						icon: 'el-icon-location',
    						path: '',
    						children: [{
    							title: '用户管理',
    							name: 'SysUser',
    							icon: 'el-icon-s-custom',
    							path: '/sys/users',
    							children: []
    						}]
    					},
    					{
    						title: '系统工具',
    						name: 'SysTools',
    						icon: 'el-icon-tools',
    						path: '',
    						children: [{
    							title: '数字字典',
    							name: 'SysDict',
    							icon: 'el-icon-s-order',
    							path: '/sys/dicts',
    							children: []
    						}]
    					}
    				]
    			}
    		},
    		methods: {
    
    		}
    	}
    </script>
    <style>
    	.header-avatar {
    		float: right;
    		width: 210px;
    		display: flex;
    		justify-content: space-around;
    		align-items: center;
    	}
    	body {
    		margin: 0;
    		padding: 0;
    		height: 100%;
    	}
    	.el-aside {
    		background-color: #545c64;
    	}
    	.template {
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    	.el-dropdown-link {
    		cursor: pointer;
    		color: #409EFF;
    	}
    	.el-container {
    		padding: 0;
    		margin: 0;
    		height: 100%;
    	}
    	.el-header {
    		background-color: #0bd18f;
    		color: #333;
    		text-align: center;
    		line-height: 60px;
    	}
    </style>
    
    
    • 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

    在这里插入图片描述

    3、设置mock.js获取导航数据

    将SideMenu的数据清空
    在这里插入图片描述

    设置mockjs
    在这里插入图片描述

    
    Mock.mock('/sys/menu/nav', 'get', () => {
    
    	let nav = [{
    			title: '系统管理',
    			name: 'SysMange',
    			icon: 'el-icon-location',
    			component:'',
    			path: '',
    			children: [{
    				title: '用户管理',
    				name: 'SysUser',
    				icon: 'el-icon-s-custom',
    				path: '/sys/users',
    				component:'sys/User',
    				children: []
    			}]
    		},
    		{
    			title: '系统工具',
    			name: 'SysTools',
    			icon: 'el-icon-tools',
    			path: '',
    			component:'',
    			children: [{
    				title: '数字字典',
    				name: 'SysDict',
    				icon: 'el-icon-s-order',
    				path: '/sys/dicts',
    				component:'',
    				children: []
    			}]
    		}
    	];
    
    	let authoritys = [];
    
    	Result.data = {
    		nav: nav,
    		authoritys: authoritys
    	}
    	return Result;
    })
    
    • 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

    创建新模块
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default {
      state: {
      },
      getters: {
    	  
      },
      mutations: {
    	 
      },
      actions: {
      },
      modules: {
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在store当中的index当中引用上面创建好的menus.js
    在这里插入图片描述
    完善menus.js
    在这里插入图片描述

    	  menuList:[],
    	  authoritys:[]
    
    • 1
    • 2

    设置路由规则
    在这里插入图片描述

    
    router.beforeEach((to,from,next)=>{
    	axios.get("/sys/menu/nav",{
    		headers:{
    			Authorization: localStorage.getItem("token")
    		}
    	}).then(res =>{
    		//拿到menuList
    		store.state.commit("setMenuList",this.data.data.nva);  
    		//拿到用户权限
    		store.state.commit("setPermList",this.data.data.authoritys);  
    	})
    	next()
    	
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    设置菜单方法
    在这里插入图片描述

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    export default {
      state: {
    	  menuList:[],
    	  permList:[]
      },
      getters: {
      },
      mutations: {
    	 setMenuList(state,menus){
    		state.menuList = menus;
    	 },
    	 setPermList(state,perms){
    		state.permList = perms;
    	 }
      },
      actions: {
      },
      modules: {
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    	get(){
    		return this.$store.state.menus.menuList;
    	}
    
    • 1
    • 2
    • 3

    4、设置动态路由

    在这里插入图片描述

    router.beforeEach((to,from,next)=>{
    	axios.get("/sys/menu/nav",{
    		headers:{
    			Authorization: localStorage.getItem("token")
    		}
    	}).then(res =>{
    		//拿到menuList
    		store.commit("setMenuList",res.data.data.nav);
    		//拿到用户权限
    		store.commit("setPermList",res.data.data.authoritys);
    		console.log(store.state.menus.menuList)
    		//设置动态绑定路由
    		let newRoutes = router.options.routes;
    		res.data.data.nav.forEach(menu => {
    			if(menu.children){
    				menu.children.forEach(e =>{
    					//生成路由
    					let route = menuToRoute(e)
    					//把路由添加到路由器管理中
    					if(route){
    						newRoutes[0].children.push(route)
    					}
    				})
    			}
    		})
    		console.log("newRoutes")
    		console.log(newRoutes)
    		router.addRoutes(newRoutes)
    	})
    	next()
    })
    //导航转成路由
    const menuToRoute = (menu) => {
    	if(!menu.component){
    		return null;
    	}
    	let route = {
    		name: menu.name,
    		path: menu.path,
    		meta: {
    			icon: menu.icon,
    			title: menu.title
    		}
    	}
    	route.component = () => import('@/views/'+ menu.component +'.vue')
    	
    	return route;
    }
    export default router
    
    • 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

    访问测试
    在这里插入图片描述

    5、设置动态路由加载一次以后无需二次加载

    menus.js
    在这里插入图片描述

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default {
      state: {
    	  menuList:[],
    	  permList:[],
    	  hasRoutes: false
      },
      getters: {
    	  
      },
      mutations: {
    	 setMenuList(state,menus){
    		state.menuList = menus;
    	 },
    	 setPermList(state,perms){
    		state.permList = perms;
    	 },
    	 changeRouteStatus(state,hasRoutes){
    		 state.hasRoutes = hasRoutes;
    	 }
      },
      actions: {
      },
      modules: {
      }
    }
    
    
    • 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

    在这里插入图片描述

    
    router.beforeEach((to,from,next)=>{
    	let hasRoute = store.state.menus.hasRoutes;
    	if(!hasRoute){
    		axios.get("/sys/menu/nav",{
    			headers:{
    				Authorization: localStorage.getItem("token")
    			}
    		}).then(res =>{
    			//拿到menuList
    			store.commit("setMenuList",res.data.data.nav);
    			//拿到用户权限
    			store.commit("setPermList",res.data.data.authoritys);
    			console.log(store.state.menus.menuList)
    			//设置动态绑定路由
    			let newRoutes = router.options.routes;
    			res.data.data.nav.forEach(menu => {
    				if(menu.children){
    					menu.children.forEach(e =>{
    						//生成路由
    						let route = menuToRoute(e)
    						//把路由添加到路由器管理中
    						if(route){
    							newRoutes[0].children.push(route)
    						}
    					})
    				}
    			})
    			router.addRoutes(newRoutes)
    			hasRoute = true
    			store.commit("changeRouteStatus",hasRoute);
    		})
    	}
    	next()
    })
    
    • 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

    6、实现动态导航

    在这里插入图片描述
    在这里插入图片描述

    <template>
    	<el-tabs v-model="editableTabsValue" type="card" closable @tab-remove="removeTab">
    		<el-tab-pane v-for="(item, index) in editableTabs" :key="item.name" :label="item.title" :name="item.name">
    			{{item.content}}
    		</el-tab-pane>
    	</el-tabs>
    </template>
    
    <script>
    	export default {
    		data() {
    			return {
    				editableTabsValue: '2',
    				editableTabs: [{
    					title: 'Tab 1',
    					name: '1',
    					content: 'Tab 1 content'
    				}, {
    					title: 'Tab 2',
    					name: '2',
    					content: 'Tab 2 content'
    				}],
    				tabIndex: 2
    			}
    		},
    		methods: {
    			handleTabsEdit(targetName, action) {
    				if (action === 'add') {
    					let newTabName = ++this.tabIndex + '';
    					this.editableTabs.push({
    						title: 'New Tab',
    						name: newTabName,
    						content: 'New Tab content'
    					});
    					this.editableTabsValue = newTabName;
    				}
    				if (action === 'remove') {
    					let tabs = this.editableTabs;
    					let activeName = this.editableTabsValue;
    					if (activeName === targetName) {
    						tabs.forEach((tab, index) => {
    							if (tab.name === targetName) {
    								let nextTab = tabs[index + 1] || tabs[index - 1];
    								if (nextTab) {
    									activeName = nextTab.name;
    								}
    							}
    						});
    					}
    
    					this.editableTabsValue = activeName;
    					this.editableTabs = tabs.filter(tab => tab.name !== targetName);
    				}
    			}
    		}
    	}
    </script>
    <style>
    	.el-main{
    		padding: 0px;
    		text-align: center;
    	}
    </style>
    
    • 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

    查看效果
    在Home当中引入该内容
    在这里插入图片描述

    <template>
    	<el-container>
    		<el-aside width="200px">
    			<SideMenu></SideMenu>
    		</el-aside>
    		<el-container>
    			<el-header>
    				<strong>xxx后台管理系统</strong>
    				<div class="header-avatar">
    					<el-avatar size="medium" :src="userInfo.avatar">
    					</el-avatar>
    					<el-dropdown>
    						<span class="el-dropdown-link">
    							{{userInfo.username}}<i class="el-icon-arrow-down el-icon--right"></i>
    						</span>
    						<el-dropdown-menu slot="dropdown">
    							
    							<el-dropdown-item>
    								<router-link to="/userCenter"> 个人中心 </router-link>
    							</el-dropdown-item>
    							
    							<el-dropdown-item @click.native="logout" >退出</el-dropdown-item>
    						</el-dropdown-menu>
    					</el-dropdown>
    					<el-link href="" target="_blank">网站</el-link>
    					<el-link href="" target="_blank">B</el-link>
    				</div>
    			</el-header>
    			<el-main>
    				<Tabs>
    				</Tabs>
    				<router-view/>
    			</el-main>
    		</el-container>
    	</el-container>
    </template>
    <script>
    	import SideMenu from "./inc/SideMenu.vue"
    	import Tabs from "./inc/Tabs.vue"
    	export default{
    		name: "Home",
    		components:{
    			SideMenu,Tabs
    		},
    		data(){
    			return {
    				userInfo:{
    					id:"",
    					username:"",
    					avatar:""
    				}
    			}
    		},
    		created() {
    			this.getUserInfo();
    		},
    		methods:{
    			getUserInfo(){
    				this.$axios.get("/sys/userInfo").then(res =>{
    					this.userInfo= res.data.data;
    				})
    			},
    			logout(){
    				this.$axios.post("/logout").then(res =>{
    					localStorage.clear();
    					sessionStorage.clear();
    					this.$store.commit("resetState");
    					this.$router.push("/login")
    				})
    			}
    		}
    	}
    </script>
    <style>
    	a{
    		text-decoration: none;
    	}
    </style>
    
    
    • 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

    在这里插入图片描述

    7、设置侧栏和页面进行动态绑定

    • 在menus.js当中设置添加tab 的功能
      在这里插入图片描述
    ,
    	 addTab(state,tab) {
    	 	let newTabName = '';
    	 	state.editableTabs.push({
    	       title: tab.title,
    	 	   name: tab.name,
    	 	});
    	 	state.editableTabsValue = tab.name;
    	 },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 在SideMenu.vue当中添加点击事件
      在这里插入图片描述
    					<el-menu-item :index="item.name" @click="selectMenu(item)">
    						<template>
    							<i :class="item.icon"></i>
    							<span slot="title">{{item.title}}</span>
    						</template>
    					</el-menu-item>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    			selectMenu(item){
    				this.$store.commit("addTab",item)
    			}
    
    • 1
    • 2
    • 3
    • 完善Tabs.vue
      在这里插入图片描述
    		data() {
    			return {
    				//editableTabsValue: this.$store.state.menus.editableTabsValue,
    				//editableTabs: this.$store.state.menus.editableTabs,
    			}
    		},
    		computed:{
    			
    			editableTabs: {
    				get(){
    					return this.$store.state.menus.editableTabs;
    				},
    				set(val){
    					this.$store.state.menus.editableTabs = val;
    				}
    			},
    			editableTabsValue:{
    				get(){
    					return this.$store.state.menus.editableTabsValue;
    				},
    				set(val){
    					this.$store.state.menus.editableTabsValue = val;
    				}
    			}
    			
    		},
    
    • 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
    • 查看效果
      在这里插入图片描述
      在这里插入图片描述
    • 我们发现重复点击会重复的添加到上面,现在设置重复点击不会出现重复的信息
      menus.js
      在这里插入图片描述
    	addTab(state,tab) {
    		let index = state.editableTabs.findIndex(e => e.name === tab.name )
    		if(index === -1){
    			state.editableTabs.push({
    			   title: tab.title,
    			   name: tab.name,
    			});
    		}
    	 	state.editableTabsValue = tab.name;
    	 },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 不会出现上面的问题
      在这里插入图片描述
    • 设置首页的点击事件

    SideMenu.vue
    在这里插入图片描述

    <el-menu-item index="0"  @click="selectMenu({name:'Index',title:'首页'})">
    				<template slot="title">
    					<i class="el-icon-s-home"></i>
    					<span slot="title">主页</span>
    				</template>
    			</el-menu-item>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 设置点击tab进行内容的切换
      在这里插入图片描述
      在这里插入图片描述
    <el-menu :default-active="this.$store.state.menus.editableTabsValue" class="el-menu-vertical-demo" background-color="#545c64" text-color="#fff"
    		active-text-color="#ffd04b">
    		<router-link to="/index">
    			<el-menu-item index="Index"  @click="selectMenu({name:'Index',title:'首页'})">
    				<template slot="title">
    					<i class="el-icon-s-home"></i>
    					<span slot="title">主页</span>
    				</template>
    			</el-menu-item>
    		</router-link>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    实现高亮的同步
    在这里插入图片描述
    设置点击tap内容切换
    在这里插入图片描述

     @tab-click="clickTab"
    
    • 1

    在这里插入图片描述

    			clickTab(target){
    				this.$router.push({name: target.name})
    			}
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    设置删除对菜单的时候设置对应内容切换,设置首页不能删除
    在这里插入图片描述

    		  removeTab(targetName) {
    				let tabs = this.editableTabs;
    				let activeName = this.editableTabsValue;
    				if(targetName === 'Index'){
    					return
    				}
    				if (activeName === targetName) {
    					tabs.forEach((tab, index) => {
    						if (tab.name === targetName) {
    							let nextTab = tabs[index + 1] || tabs[index - 1];
    							if (nextTab) {
    								activeName = nextTab.name;
    							}
    						}
    					});
    				}
    				this.editableTabsValue = activeName;
    				this.editableTabs = tabs.filter(tab => tab.name !== targetName);
    				this.$router.push({name: activeName})
    			},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    设置通过ip路径访问的时候,设置对应tabs
    在这里插入图片描述

    <template>
      <div id="app">
        <router-view/>
      </div>
    </template>
    
    <script>
    	
    	export default{
    		name:"App",
    		watch:{
    			$route(to,from){
    				if(to.path != '/login'){
    					let obj = {
    						name: to.name,
    						title: to.meta.title
    					}
    					this.$store.commit("addTab",obj)
    				}
    			}
    		}
    	}
    	
    </script>
    
    <style>
    	
    body html  {
      margin: 0;
      padding: 0;
      height: 100%;
    }
    #app {
      margin: 0;
      padding: 0;
      height: 800px;
    }
    .router-view{
    	height: 100%;
    }
    
    nav a {
      font-weight: bold;
      color: #2c3e50;
    }
    
    nav a.router-link-exact-active {
      color: #42b983;
    }
    </style>
    
    
    • 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

    http://localhost:8080/sys/roles
    在这里插入图片描述
    设置退出登录后清除tab
    在这里插入图片描述
    在这里插入图片描述

    	  resetState: (state) => {
    			state.menuList = [],
    			state.permList = [],
    			state.hasRoutes = false,
    			state.editableTabsValue = 'Index',
    			state.editableTabs = [{
    				title: '首页',
    				name: 'Index',
    			}]
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    四、菜单管理界面开发

    1、设置Home的内容

    在这里插入图片描述

    		   <el-main>
    				<Tabs></Tabs>
    				<div style="margin: 0 15px;">
    						
    						
    					<router-view />
    				</div>
    				
    			</el-main>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、设置Menu.vue

    (1)设置Menu.vue

    在这里插入图片描述

    <template>
    	<div>
    		<el-form :inline="true">
    			<el-form-item>
    				<el-button type="primary" @click="dialogVisible = true">新增</el-button>
    			</el-form-item>
    		</el-form>
    		<el-table :data="tableData" style="width: 100%;margin-bottom: 20px;" row-key="id" stripe border
    			default-expand-all :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
    			<el-table-column prop="name" label="名称" sortable width="180">
    			</el-table-column>
    			<el-table-column prop="perm" label="权限编码" sortable width="180">
    			</el-table-column>
    
    			<el-table-column prop="icon" label="图标">
    			</el-table-column>
    			<el-table-column prop="type" label="类型">
    				<template slot-scope="scope">
    					<el-tag size="small" v-if="scope.row.type === 0"> 目录 </el-tag>
    					<el-tag size="small" v-else-if="scope.row.type === 1" type="success"> 菜单 </el-tag>
    					<el-tag size="small" v-else-if="scope.row.type === 2" type="info"> 按钮 </el-tag>
    				</template>
    			</el-table-column>
    			<el-table-column prop="path" label="菜单URL">
    			</el-table-column>
    
    			<el-table-column prop="component" label="菜单组件">
    			</el-table-column>
    
    			<el-table-column prop="orderNum" label="排序号">
    			</el-table-column>
    			<el-table-column prop="statu" label="状态">
    				<template slot-scope="scope">
    					<el-button size="small" type="success" v-if="scope.row.statu === 1">正常</el-button>
    					<el-button size="small" type="danger" v-else-if="scope.row.statu === 0">禁用</el-button>
    				</template>
    			</el-table-column>
    			<el-table-column prop="type" label="操作">
    				<template slot-scope="scope">
    					<el-button type="text">编辑</el-button>
    					<el-divider direction="vertical"></el-divider>
    					<template>
    						<el-popconfirm title="这是一段内容确定删除吗?" >
    						  <el-button type="text" slot="reference">删除</el-button>
    						</el-popconfirm>
    					</template>
    					
    				</template>
    			</el-table-column>
    		</el-table>
    
    		<!-- 新增对话框-->
    		<el-dialog title="提示" :visible.sync="dialogVisible" width="50%" :before-close="handleClose">
    			<el-form ref="editForm" :rules="editFormRules" :model="editForm" label-width="100px">
    				<el-form-item label="上级菜单" prop="parentId">
    					<el-select v-model="editForm.parentId" placeholder="请选择上级菜单">
    						<template v-for="item in tableData">
    							<el-option :label="item.name" :value="item.id">
    							</el-option>
    							<template v-for="child in item.children">
    								<el-option :label="child.name" :value="child.id">
    									<span>{{ "-- "+child.name}}</span>
    								</el-option>
    							</template>
    						</template>
    					</el-select>
    				</el-form-item>
    
    				<el-form-item label="菜单名称" prop="name">
    					<el-input v-model="editForm.name"></el-input>
    				</el-form-item>
    
    				<el-form-item label="权限编码" prop="perms">
    					<el-input v-model="editForm.perms"></el-input>
    				</el-form-item>
    
    				<el-form-item label="图标" >
    					<el-input v-model="editForm.name"></el-input>
    				</el-form-item>
    
    				<el-form-item label="菜单URL"  >
    					<el-input v-model="editForm.name"></el-input>
    				</el-form-item>
    
    				<el-form-item label="菜单组件"  >
    					<el-input v-model="editForm.name"></el-input>
    				</el-form-item>
    
    				<el-form-item label="类型" prop="type" lable-width="100px" >
    					<el-radio-group v-model="editForm.type">
    						<el-radio :lable="0">目录</el-radio>
    						<el-radio :lable="1">菜单</el-radio>
    						<el-radio :lable="2">按钮</el-radio>
    					</el-radio-group>
    				</el-form-item>
    
    				<el-form-item label="状态" prop="statu" lable-width="100px"  >
    					<el-radio-group v-model="editForm.statu">
    						<el-radio :lable="0">禁用</el-radio>
    						<el-radio :lable="1">正常</el-radio>
    					</el-radio-group>
    				</el-form-item>
    				<el-form-item label="排序号" prop="orderNum" label-width="100px">
    					<el-input-number v-model="editForm.orderNum" :min="1" label="排序号">1</el-input-number>
    				</el-form-item>
    
    				<el-form-item >
    					<el-button type="primary" @click="onSubmit">立即创建</el-button>
    					<el-button>取消</el-button>
    				</el-form-item>
    			</el-form>
    
    		</el-dialog>
    	</div>
    </template>
    
    <script>
    	export default {
    		data() {
    			return {
    				dialogVisible: false,
    
    				tableData: [],
    				editForm: {},
    				editFormRules: {
    					parentId: [{
    						required: true,
    						message: '请选择上级菜单',
    						trigger: 'blur'
    					}],
    					name: [{
    						required: true,
    						message: '请输入名称',
    						trigger: 'blur'
    					}],
    					perms: [{
    						required: true,
    						message: '请输入权限编码',
    						trigger: 'blur'
    					}],
    					type: [{
    						required: true,
    						message: '请选择类型',
    						trigger: 'blur'
    					}],
    					orderNum: [{
    						required: true,
    						message: '请填入排序号',
    						trigger: 'blur'
    					}],
    					statu: [{
    						required: true,
    						message: '请选择状态',
    						trigger: 'blur'
    					}],
    				}
    			}
    		},
    		methods: {
    			load(tree, treeNode, resolve) {
    				setTimeout(() => {
    					resolve([{
    						id: 31,
    						date: '2016-05-01',
    						name: '王小虎',
    						address: '上海市普陀区金沙江路 1519 弄'
    					}, {
    						id: 32,
    						date: '2016-05-01',
    						name: '王小虎',
    						address: '上海市普陀区金沙江路 1519 弄'
    					}])
    				}, 1000)
    			},
    			handleClose(done) {
    				this.$confirm('确认关闭?')
    					.then(_ => {
    						done();
    					})
    					.catch(_ => {});
    			},
    			onSubmit() {
    				console.log('submit!');
    			},
    			getMenuTree(){
    				this.$axios.get("/sys/menu/list").then(res => {
    					this.tableData = res.data.data
    				})
    			}
    		},
    		created(){
    			this.getMenuTree();
    		},
    		
    	}
    </script>
    
    <style>
    </style>
    
    
    • 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
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200

    (2)设置mock.js

    在这里插入图片描述

    Mock.mock('/sys/menu/list', 'get', () => {
    	let menus = [{
    		id: 1,
    		date: '2016-05-02',
    		name: '王小虎1',
    		address: '上海市普陀区金沙江路 1518 弄',
    		statu: 1,
    		type: 0,
    	}, {
    		id: 2,
    		date: '2016-05-04',
    		name: '王小虎2',
    		address: '上海市普陀区金沙江路 1517 弄',
    		statu: 0.,
    		type: 1,
    	}, {
    		id: 3,
    		date: '2016-05-01',
    		name: '王小虎3',
    		address: '上海市普陀区金沙江路 1519 弄',
    		statu: 1,
    		type: 0,
    		children: [{
    			id: 31,
    			date: '2016-05-01',
    			name: '王小虎4',
    			address: '上海市普陀区金沙江路 1519 弄',
    			statu: 1,
    			type: 2,
    		}, {
    			id: 32,
    			date: '2016-05-01',
    			name: '王小虎5',
    			address: '上海市普陀区金沙江路 1519 弄',
    			statu: 0,
    			type: 0,
    		}]
    	}, {
    		id: 4,
    		date: '2016-05-03',
    		name: '王小虎6',
    		address: '上海市普陀区金沙江路 1516 弄',
    		statu: 1,
    		type: 2,
    	}]
    	Result.data = menus
    	return Result;
    })
    
    • 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

    3、设置Menu.vue新增弹出和修改弹出,以及删除

    在这里插入图片描述
    在这里插入图片描述

    <template>
    	<div>
    
    		<el-form :inline="true">
    			<el-form-item>
    				<el-button type="primary" @click="dialogVisible = true">新增</el-button>
    			</el-form-item>
    		</el-form>
    
    		<el-table
    				:data="tableData"
    				style="width: 100%;margin-bottom: 20px;"
    				row-key="id"
    				border
    				stripe
    				default-expand-all
    				:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
    
    			<el-table-column
    					prop="name"
    					label="名称"
    					sortable
    					width="180">
    			</el-table-column>
    			<el-table-column
    					prop="perms"
    					label="权限编码"
    					sortable
    					width="180">
    			</el-table-column>
    
    			<el-table-column
    					prop="icon"
    					label="图标">
    			</el-table-column>
    
    			<el-table-column
    					prop="type"
    					label="类型">
    				<template slot-scope="scope">
    					<el-tag size="small" v-if="scope.row.type === 0">目录</el-tag>
    					<el-tag size="small" v-else-if="scope.row.type === 1" type="success">菜单</el-tag>
    					<el-tag size="small" v-else-if="scope.row.type === 2" type="info">按钮</el-tag>
    				</template>
    
    			</el-table-column>
    
    			<el-table-column
    					prop="path"
    					label="菜单URL">
    			</el-table-column>
    			<el-table-column
    					prop="component"
    					label="菜单组件">
    			</el-table-column>
    			<el-table-column
    					prop="orderNum"
    					label="排序号">
    			</el-table-column>
    			<el-table-column
    					prop="statu"
    					label="状态">
    				<template slot-scope="scope">
    					<el-tag size="small" v-if="scope.row.statu === 1" type="success">正常</el-tag>
    					<el-tag size="small" v-else-if="scope.row.statu === 0" type="danger">禁用</el-tag>
    				</template>
    
    			</el-table-column>
    			<el-table-column
    					prop="icon"
    					label="操作">
    
    				<template slot-scope="scope">
    					<el-button type="text" @click="editHandle(scope.row.id)">编辑</el-button>
    					<el-divider direction="vertical"></el-divider>
    
    					<template>
    						<el-popconfirm title="这是一段内容确定删除吗?" @confirm="delHandle(scope.row.id)">
    							<el-button type="text" slot="reference">删除</el-button>
    						</el-popconfirm>
    					</template>
    
    				</template>
    			</el-table-column>
    
    		</el-table>
    
    
    		<!--新增对话框-->
    		<el-dialog
    				title="提示"
    				:visible.sync="dialogVisible"
    				width="600px"
    				:before-close="handleClose">
    
    			<el-form :model="editForm" :rules="editFormRules" ref="editForm" label-width="100px" class="demo-editForm">
    
    				<el-form-item label="上级菜单" prop="parentId">
    					<el-select v-model="editForm.parentId" placeholder="请选择上级菜单">
    						<template v-for="item in tableData">
    							<el-option :label="item.name" :value="item.id"></el-option>
    							<template v-for="child in item.children">
    								<el-option :label="child.name" :value="child.id">
    									<span>{{ "- " + child.name }}</span>
    								</el-option>
    							</template>
    						</template>
    					</el-select>
    				</el-form-item>
    
    				<el-form-item label="菜单名称" prop="name" label-width="100px">
    					<el-input v-model="editForm.name" autocomplete="off"></el-input>
    				</el-form-item>
    
    				<el-form-item label="权限编码" prop="perms" label-width="100px">
    					<el-input v-model="editForm.perms" autocomplete="off"></el-input>
    				</el-form-item>
    
    				<el-form-item label="图标" prop="icon" label-width="100px">
    					<el-input v-model="editForm.icon" autocomplete="off"></el-input>
    				</el-form-item>
    				<el-form-item label="菜单URL" prop="path" label-width="100px">
    					<el-input v-model="editForm.path" autocomplete="off"></el-input>
    				</el-form-item>
    
    				<el-form-item label="菜单组件" prop="component" label-width="100px">
    					<el-input v-model="editForm.component" autocomplete="off"></el-input>
    				</el-form-item>
    
    				<el-form-item label="类型" prop="type" label-width="100px">
    					<el-radio-group v-model="editForm.type">
    						<el-radio :label=0>目录</el-radio>
    						<el-radio :label=1>菜单</el-radio>
    						<el-radio :label=2>按钮</el-radio>
    					</el-radio-group>
    				</el-form-item>
    
    				<el-form-item label="状态" prop="statu" label-width="100px">
    					<el-radio-group v-model="editForm.statu">
    						<el-radio :label=0>禁用</el-radio>
    						<el-radio :label=1>正常</el-radio>
    					</el-radio-group>
    				</el-form-item>
    
    				<el-form-item label="排序号" prop="orderNum" label-width="100px">
    					<el-input-number v-model="editForm.orderNum" :min="1" label="排序号">1</el-input-number>
    				</el-form-item>
    
    
    				<el-form-item>
    					<el-button type="primary" @click="submitForm('editForm')">立即创建</el-button>
    					<el-button @click="resetForm('editForm')">重置</el-button>
    				</el-form-item>
    			</el-form>
    
    		</el-dialog>
    
    
    	</div>
    
    </template>
    
    
    <script>
    	export default {
    		data() {
    			return {
    				dialogVisible: false,
    
    				tableData: [],
    				editForm: {},
    				editFormRules: {
    					parentId: [{
    						required: true,
    						message: '请选择上级菜单',
    						trigger: 'blur'
    					}],
    					name: [{
    						required: true,
    						message: '请输入名称',
    						trigger: 'blur'
    					}],
    					perms: [{
    						required: true,
    						message: '请输入权限编码',
    						trigger: 'blur'
    					}],
    					type: [{
    						required: true,
    						message: '请选择类型',
    						trigger: 'blur'
    					}],
    					orderNum: [{
    						required: true,
    						message: '请填入排序号',
    						trigger: 'blur'
    					}],
    					statu: [{
    						required: true,
    						message: '请选择状态',
    						trigger: 'blur'
    					}],
    				}
    			}
    		},
    		methods: {
    			load(tree, treeNode, resolve) {
    				setTimeout(() => {
    					resolve([{
    						id: 31,
    						date: '2016-05-01',
    						name: '王小虎',
    						address: '上海市普陀区金沙江路 1519 弄'
    					}, {
    						id: 32,
    						date: '2016-05-01',
    						name: '王小虎',
    						address: '上海市普陀区金沙江路 1519 弄'
    					}])
    				}, 1000)
    			},
    			
    			submitForm(formName) {
    				this.$refs[formName].validate((valid) => {
    					if (valid) {
    						this.$axios.post("/sys/menu/"+(this.editForm.id?'update':'save'),this.loginForm)
    						.then(res =>{
    							 this.$message({
    								showClose:true, 
    							    message: '恭喜你,操作成功',
    							    type: 'success',
    								onClose:()=>{
    									this.getMenuTree()
    								}
    							 });
    							 this.dialogVisible = false
    						})
    					} else {
    						console.log('error submit!!');
    						return false;
    					}
    				});
    			},
    			resetForm() {
    				console.log('submit!');
    			},
    			getMenuTree(){
    				this.$axios.get("/sys/menu/list").then(res => {
    					this.tableData = res.data.data
    				})
    			},
    			editHandle(id){
    				this.$axios.get('/sys/menu/info/'+id).then(res =>{
    					this.editForm = res.data.data
    					this.dialogVisible = true
    				})
    			},
    			resetForm(formName) {
    				this.$refs[formName].resetFields();
    				this.dialogVisible = false
    				this.editForm = {}
    			},
    			handleClose() {
    				this.resetForm('editForm')
    			},
    			delHandle(id) {
    				this.$axios.post("/sys/menu/delete/" + id).then(res => {
    					this.$message({
    						showClose: true,
    						message: '恭喜你,操作成功',
    						type: 'success',
    							onClose:() => {
    								this.getMenuTree()
    						}
    					});
    				})
    			}
    		},
    		created(){
    			this.getMenuTree();
    		},
    		
    	}
    </script>
    
    <style>
    </style>
    
    
    • 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
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    五、角色管理

    1、设置角色信息的增删改查-权限分配

    在这里插入图片描述

    <template>
    	<div>
    		<el-form :inline="true">
    			<el-form-item>
    				<el-input
    						v-model="searchForm.name"
    						placeholder="名称"
    						clearable>
    				</el-input>
    			</el-form-item>
    
    			<el-form-item>
    				<el-button @click="getRoleList">搜索</el-button>
    			</el-form-item>
    
    			<el-form-item>
    				<el-button type="primary" @click="dialogVisible = true">新增</el-button>
    			</el-form-item>
    			<el-form-item>
    				<el-popconfirm title="这是确定批量删除吗?" @confirm="delHandle(null)">
    					<el-button type="danger" slot="reference" :disabled="delBtlStatu">批量删除</el-button>
    				</el-popconfirm>
    			</el-form-item>
    		</el-form>
    
    		<el-table
    				ref="multipleTable"
    				:data="tableData"
    				tooltip-effect="dark"
    				style="width: 100%"
    				border
    				stripe
    				@selection-change="handleSelectionChange">
    
    			<el-table-column
    					type="selection"
    					width="55">
    			</el-table-column>
    
    			<el-table-column
    					prop="name"
    					label="名称"
    					width="120">
    			</el-table-column>
    			<el-table-column
    					prop="code"
    					label="唯一编码"
    					show-overflow-tooltip>
    			</el-table-column>
    			<el-table-column
    					prop="remark"
    					label="描述"
    					show-overflow-tooltip>
    			</el-table-column>
    
    			<el-table-column
    					prop="statu"
    					label="状态">
    				<template slot-scope="scope">
    					<el-tag size="small" v-if="scope.row.statu === 1" type="success">正常</el-tag>
    					<el-tag size="small" v-else-if="scope.row.statu === 0" type="danger">禁用</el-tag>
    				</template>
    
    			</el-table-column>
    			<el-table-column
    					prop="icon"
    					label="操作">
    
    				<template slot-scope="scope">
    					<el-button type="text" @click="permHandle(scope.row.id)">分配权限</el-button>
    					<el-divider direction="vertical"></el-divider>
    
    					<el-button type="text" @click="editHandle(scope.row.id)">编辑</el-button>
    					<el-divider direction="vertical"></el-divider>
    
    					<template>
    						<el-popconfirm title="这是一段内容确定删除吗?" @confirm="delHandle(scope.row.id)">
    							<el-button type="text" slot="reference">删除</el-button>
    						</el-popconfirm>
    					</template>
    
    				</template>
    			</el-table-column>
    
    		</el-table>
    
    
    		<el-pagination
    				@size-change="handleSizeChange"
    				@current-change="handleCurrentChange"
    				layout="total, sizes, prev, pager, next, jumper"
    				:page-sizes="[10, 20, 50, 100]"
    				:current-page="current"
    				:page-size="size"
    				:total="total">
    		</el-pagination>
    
    
    		<!--新增对话框-->
    		<el-dialog
    				title="提示"
    				:visible.sync="dialogVisible"
    				width="600px"
    				:before-close="handleClose">
    
    			<el-form :model="editForm" :rules="editFormRules" ref="editForm" label-width="100px" class="demo-editForm">
    
    				<el-form-item label="角色名称" prop="name" label-width="100px">
    					<el-input v-model="editForm.name" autocomplete="off"></el-input>
    				</el-form-item>
    
    				<el-form-item label="唯一编码" prop="code" label-width="100px">
    					<el-input v-model="editForm.code" autocomplete="off"></el-input>
    				</el-form-item>
    
    				<el-form-item label="描述" prop="remark" label-width="100px">
    					<el-input v-model="editForm.remark" autocomplete="off"></el-input>
    				</el-form-item>
    
    
    				<el-form-item label="状态" prop="statu" label-width="100px">
    					<el-radio-group v-model="editForm.statu">
    						<el-radio :label=0>禁用</el-radio>
    						<el-radio :label=1>正常</el-radio>
    					</el-radio-group>
    				</el-form-item>
    
    				<el-form-item>
    					<el-button type="primary" @click="submitForm('editForm')">立即创建</el-button>
    					<el-button @click="resetForm('editForm')">重置</el-button>
    				</el-form-item>
    			</el-form>
    
    		</el-dialog>
    
    		<el-dialog
    				title="分配权限"
    				:visible.sync="permDialogVisible"
    				width="600px">
    
    			<el-form :model="permForm">
    
    				<el-tree
    						:data="permTreeData"
    						show-checkbox
    						ref="permTree"
    						:default-expand-all=true
    						node-key="id"
    						:check-strictly=true
    						:props="defaultProps">
    				</el-tree>
    
    			</el-form>
    
    			<span slot="footer" class="dialog-footer">
    			    <el-button @click="permDialogVisible = false">取 消</el-button>
    			    <el-button type="primary" @click="submitPermFormHandle('permForm')">确 定</el-button>
    			</span>
    
    		</el-dialog>
    
    	</div>
    </template>
    
    <script>
    	export default {
    		name: "Role",
    		data() {
    			return {
    				searchForm: {},
    				delBtlStatu: true,
    				total: 0,
    				size: 10,
    				current: 1,
    				dialogVisible: false,
    				editForm: {
    					
    				},
    				tableData: [],
    				editFormRules: {
    					name: [
    						{required: true, message: '请输入角色名称', trigger: 'blur'}
    					],
    					code: [
    						{required: true, message: '请输入唯一编码', trigger: 'blur'}
    					],
    					statu: [
    						{required: true, message: '请选择状态', trigger: 'blur'}
    					]
    				},
    				multipleSelection: [],
    				permDialogVisible: false,
    				permForm: {},
    				defaultProps: {
    					children: 'children',
    					label: 'name'
    				},
    				permTreeData: []
    			}
    		},
    		created() {
    			this.getRoleList()
    			this.$axios.get('/sys/menu/list').then(res => {
    				this.permTreeData = res.data.data
    			})
    		},
    		methods: {
    			toggleSelection(rows) {
    				if (rows) {
    					rows.forEach(row => {
    						this.$refs.multipleTable.toggleRowSelection(row);
    					});
    				} else {
    					this.$refs.multipleTable.clearSelection();
    				}
    			},
    			handleSelectionChange(val) {
    				console.log("勾选")
    				console.log(val)
    				this.multipleSelection = val;
    				this.delBtlStatu = val.length == 0
    			},
    			handleSizeChange(val) {
    				console.log(`每页 ${val}`);
    				this.size = val
    				this.getRoleList()
    			},
    			handleCurrentChange(val) {
    				console.log(`当前页: ${val}`);
    				this.current = val 
    				this.getRoleList()
    			},
    			resetForm(formName) {
    				this.$refs[formName].resetFields();
    				this.dialogVisible = false
    				this.editForm = {}
    			},
    			handleClose() {
    				this.resetForm('editForm')
    			},
    			getRoleList() {
    				this.$axios.get("/sys/role/list", {
    					params: {
    						name: this.searchForm.name,
    						current: this.current,
    						size: this.size
    					}
    				}).then(res => {
    					this.tableData = res.data.data.records
    					this.size = res.data.data.size
    					this.current = res.data.data.current
    					this.total = res.data.data.total
    				})
    			},
    			submitForm(formName) {
    				this.$refs[formName].validate((valid) => {
    					if (valid) {
    						this.$axios.post('/sys/role/' + (this.editForm.id?'update' : 'save'), this.editForm)
    							.then(res => {
    								this.$message({
    									showClose: true,
    									message: '恭喜你,操作成功',
    									type: 'success',
    									onClose:() => {
    										this.getRoleList()
    									}
    								});
    								this.dialogVisible = false
    								this.resetForm(formName)
    							})
    					} else {
    						console.log('error submit!!');
    						return false;
    					}
    				});
    			},
    			editHandle(id) {
    				this.$axios.get('/sys/role/info/' + id).then(res => {
    					this.editForm = res.data.data
    					this.dialogVisible = true
    				})
    			},
    			delHandle(id) {
    				var ids = []
    				if (id != null) {
    					ids.push(id)
    				} else {
    					this.multipleSelection.forEach(row => {
    						ids.push(row.id)
    					})
    				}
    				console.log(ids)
    				this.$axios.post("/sys/role/delete", ids).then(res => {
    					this.$message({
    						showClose: true,
    						message: '恭喜你,操作成功',
    						type: 'success',
    						onClose:() => {
    							this.getRoleList()
    						}
    					});
    				})
    			},
    			permHandle(id) {
    				this.permDialogVisible = true
    				this.$axios.get("/sys/role/info/" + id).then(res => {
    					this.$refs.permTree.setCheckedKeys(res.data.data.menuIds)
    					this.permForm = res.data.data
    				})
    			},
    			submitPermFormHandle(formName) {
    				var menuIds = this.$refs.permTree.getCheckedKeys()
    				console.log(menuIds)
    				this.$axios.post('/sys/role/perm/' + this.permForm.id, menuIds).then(res => {
    					this.$message({
    						showClose: true,
    						message: '恭喜你,操作成功',
    						type: 'success',
    						onClose:() => {
    							this.getRoleList()
    						}
    					});
    					this.permDialogVisible = false
    					this.resetForm(formName)
    				})
    			}
    		}
    	}
    </script>
    
    <style scoped>
    	.el-pagination {
    		float: right;
    		margin-top: 22px;
    	}
    </style>
    
    • 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
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    六、用户管理

    用户的增删改查以及对应的权限
    在这里插入图片描述

    <template>
    	<div>
    		<el-form :inline="true">
    			<el-form-item>
    				<el-input
    						v-model="searchForm.username"
    						placeholder="用户名"
    						clearable
    				>
    				</el-input>
    			</el-form-item>
    
    			<el-form-item>
    				<el-button @click="getUserList">搜索</el-button>
    			</el-form-item>
    
    			<el-form-item>
    				<el-button type="primary" @click="dialogVisible = true">新增</el-button>
    			</el-form-item>
    			<el-form-item>
    				<el-popconfirm title="这是确定批量删除吗?" @confirm="delHandle(null)">
    					<el-button type="danger" slot="reference" :disabled="delBtlStatu" >批量删除</el-button>
    				</el-popconfirm>
    			</el-form-item>
    		</el-form>
    
    		<el-table
    				ref="multipleTable"
    				:data="tableData"
    				tooltip-effect="dark"
    				style="width: 100%"
    				border
    				stripe
    				@selection-change="handleSelectionChange">
    
    			<el-table-column
    					type="selection"
    					width="55">
    			</el-table-column>
    
    			<el-table-column
    					label="头像"
    					width="50">
    				<template slot-scope="scope">
    					<el-avatar size="small" :src="scope.row.avatar"></el-avatar>
    				</template>
    			</el-table-column>
    
    			<el-table-column
    					prop="username"
    					label="用户名"
    					width="120">
    			</el-table-column>
    			<el-table-column
    					prop="code"
    					label="角色名称">
    				<template slot-scope="scope">
    					<el-tag size="small" type="info" v-for="item in scope.row.sysRoles">{{item.name}}</el-tag>
    				</template>
    
    			</el-table-column>
    			<el-table-column
    					prop="email"
    					label="邮箱">
    			</el-table-column>
    			<el-table-column
    					prop="phone"
    					label="手机号">
    			</el-table-column>
    
    			<el-table-column
    					prop="statu"
    					label="状态">
    				<template slot-scope="scope">
    					<el-tag size="small" v-if="scope.row.statu === 1" type="success">正常</el-tag>
    					<el-tag size="small" v-else-if="scope.row.statu === 0" type="danger">禁用</el-tag>
    				</template>
    
    			</el-table-column>
    			<el-table-column
    					prop="created"
    					width="200"
    					label="创建时间"
    			>
    			</el-table-column>
    			<el-table-column
    					prop="icon"
    					width="260px"
    					label="操作">
    
    				<template slot-scope="scope">
    					<el-button type="text" @click="roleHandle(scope.row.id)">分配角色</el-button>
    					<el-divider direction="vertical"></el-divider>
    
    					<el-button type="text" @click="repassHandle(scope.row.id, scope.row.username)">重置密码</el-button>
    					<el-divider direction="vertical"></el-divider>
    
    					<el-button type="text" @click="editHandle(scope.row.id)">编辑</el-button>
    					<el-divider direction="vertical"></el-divider>
    
    					<template>
    						<el-popconfirm title="这是一段内容确定删除吗?" @confirm="delHandle(scope.row.id)">
    							<el-button type="text" slot="reference">删除</el-button>
    						</el-popconfirm>
    					</template>
    
    				</template>
    			</el-table-column>
    
    		</el-table>
    
    		<el-pagination
    				@size-change="handleSizeChange"
    				@current-change="handleCurrentChange"
    				layout="total, sizes, prev, pager, next, jumper"
    				:page-sizes="[10, 20, 50, 100]"
    				:current-page="current"
    				:page-size="size"
    				:total="total">
    		</el-pagination>
    
    
    		<!--新增对话框-->
    		<el-dialog
    				title="提示"
    				:visible.sync="dialogVisible"
    				width="600px"
    				:before-close="handleClose">
    
    			<el-form :model="editForm" :rules="editFormRules" ref="editForm">
    				<el-form-item label="用户名" prop="username" label-width="100px">
    					<el-input v-model="editForm.username" autocomplete="off"></el-input>
    					<el-alert
    							title="初始密码为888888"
    							:closable="false"
    							type="info"
    							style="line-height: 12px;"
    					></el-alert>
    				</el-form-item>
    
    				<el-form-item label="邮箱"  prop="email" label-width="100px">
    					<el-input v-model="editForm.email" autocomplete="off"></el-input>
    				</el-form-item>
    				<el-form-item label="手机号"  prop="phone" label-width="100px">
    					<el-input v-model="editForm.phone" autocomplete="off"></el-input>
    				</el-form-item>
    
    				<el-form-item label="状态"  prop="statu" label-width="100px">
    					<el-radio-group v-model="editForm.statu">
    						<el-radio :label="0">禁用</el-radio>
    						<el-radio :label="1">正常</el-radio>
    					</el-radio-group>
    				</el-form-item>
    
    			</el-form>
    			<div slot="footer" class="dialog-footer">
    				<el-button @click="resetForm('editForm')">取 消</el-button>
    				<el-button type="primary" @click="submitForm('editForm')">确 定</el-button>
    			</div>
    		</el-dialog>
    
    		<!-- 分配权限对话框 -->
    		<el-dialog title="分配角色" :visible.sync="roleDialogFormVisible" width="600px">
    
    			<el-form :model="roleForm">
    				<el-tree
    						:data="roleTreeData"
    						show-checkbox
    						ref="roleTree"
    						:check-strictly=checkStrictly
    						node-key="id"
    						:default-expand-all=true
    						:props="defaultProps">
    				</el-tree>
    			</el-form>
    
    			<div slot="footer" class="dialog-footer">
    				<el-button @click="roleDialogFormVisible=false">取 消</el-button>
    				<el-button type="primary" @click="submitRoleHandle('roleForm')">确 定</el-button>
    			</div>
    		</el-dialog>
    
    	</div>
    </template>
    
    <script>
    	export default {
    		name: "Role",
    		data() {
    			return {
    				searchForm: {},
    				delBtlStatu: true,
    
    				total: 0,
    				size: 10,
    				current: 1,
    
    				dialogVisible: false,
    				editForm: {
    
    				},
    
    				tableData: [],
    
    				editFormRules: {
    					username: [
    						{required: true, message: '请输入用户名称', trigger: 'blur'}
    					],
    					email: [
    						{required: true, message: '请输入邮箱', trigger: 'blur'}
    					],
    					statu: [
    						{required: true, message: '请选择状态', trigger: 'blur'}
    					]
    				},
    
    				multipleSelection: [],
    
    				roleDialogFormVisible: false,
    				defaultProps: {
    					children: 'children',
    					label: 'name'
    				},
    				roleForm: {},
    				roleTreeData:  [],
    				treeCheckedKeys: [],
    				checkStrictly: true
    
    			}
    		},
    		created() {
    			this.getUserList()
    
    			this.$axios.get("/sys/role/list").then(res => {
    				this.roleTreeData = res.data.data.records
    			})
    		},
    		methods: {
    			toggleSelection(rows) {
    				if (rows) {
    					rows.forEach(row => {
    						this.$refs.multipleTable.toggleRowSelection(row);
    					});
    				} else {
    					this.$refs.multipleTable.clearSelection();
    				}
    			},
    			handleSelectionChange(val) {
    				console.log("勾选")
    				console.log(val)
    				this.multipleSelection = val;
    
    				this.delBtlStatu = val.length == 0
    			},
    
    			handleSizeChange(val) {
    				console.log(`每页 ${val}`);
    				this.size = val
    				this.getUserList()
    			},
    			handleCurrentChange(val) {
    				console.log(`当前页: ${val}`);
    				this.current = val
    				this.getUserList()
    			},
    
    			resetForm(formName) {
    				this.$refs[formName].resetFields();
    				this.dialogVisible = false
    				this.editForm = {}
    			},
    			handleClose() {
    				this.resetForm('editForm')
    			},
    
    			getUserList() {
    				this.$axios.get("/sys/user/list", {
    					params: {
    						username: this.searchForm.username,
    						current: this.current,
    						size: this.size
    					}
    				}).then(res => {
    					this.tableData = res.data.data.records
    					this.size = res.data.data.size
    					this.current = res.data.data.current
    					this.total = res.data.data.total
    				})
    			},
    
    			submitForm(formName) {
    				this.$refs[formName].validate((valid) => {
    					if (valid) {
    						this.$axios.post('/sys/user/' + (this.editForm.id?'update' : 'save'), this.editForm)
    							.then(res => {
    
    								this.$message({
    									showClose: true,
    									message: '恭喜你,操作成功',
    									type: 'success',
    									onClose:() => {
    										this.getUserList()
    									}
    								});
    
    								this.dialogVisible = false
    							})
    					} else {
    						console.log('error submit!!');
    						return false;
    					}
    				});
    			},
    			editHandle(id) {
    				this.$axios.get('/sys/user/info/' + id).then(res => {
    					this.editForm = res.data.data
    
    					this.dialogVisible = true
    				})
    			},
    			delHandle(id) {
    				var ids = []
    				if (id) {
    					ids.push(id)
    				} else {
    					this.multipleSelection.forEach(row => {
    						ids.push(row.id)
    					})
    				}
    				console.log(ids)
    				this.$axios.post("/sys/user/delete", ids).then(res => {
    					this.$message({
    						showClose: true,
    						message: '恭喜你,操作成功',
    						type: 'success',
    						onClose:() => {
    							this.getUserList()
    						}
    					});
    				})
    			},
    			roleHandle (id) {
    				this.roleDialogFormVisible = true
    				this.$axios.get('/sys/user/info/' + id).then(res => {
    					this.roleForm = res.data.data
    					let roleIds = []
    					res.data.data.sysRoles.forEach(row => {
    						roleIds.push(row.id)
    					})
    					this.$refs.roleTree.setCheckedKeys(roleIds)
    				})
    			},
    			submitRoleHandle(formName) {
    				var roleIds = this.$refs.roleTree.getCheckedKeys()
    				console.log(roleIds)
    				this.$axios.post('/sys/user/role/' + this.roleForm.id, roleIds).then(res => {
    					this.$message({
    						showClose: true,
    						message: '恭喜你,操作成功',
    						type: 'success',
    						onClose:() => {
    							this.getUserList()
    						}
    					});
    					this.roleDialogFormVisible = false
    				})
    			},
    			repassHandle(id, username) {
    				this.$confirm('将重置用户【' + username + '】的密码, 是否继续?', '提示', {
    					confirmButtonText: '确定',
    					cancelButtonText: '取消',
    					type: 'warning'
    				}).then(() => {
    					this.$axios.post("/sys/user/repass", id).then(res => {
    						this.$message({
    							showClose: true,
    							message: '恭喜你,操作成功',
    							type: 'success',
    							onClose: () => {
    							}
    						});
    					})
    				})
    			}
    		}
    	}
    </script>
    <style scoped>
    	.el-pagination {
    		float: right;
    		margin-top: 22px;
    	}
    </style>
    
    • 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
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393

    七、用户管理

    上面的菜单、角色、用户有增删改查操作,但是不是每个用户都有权限的,
    没权限的用户我们应该隐藏按钮,因此我们需要通过条件来判断按钮是否应该显示,
    那么应该怎么定义一个方法可以让全局都能使用呢?

    我们再src下面新建一个js文件用于定义一个全局使用的方法:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    import Vue from "vue"
    
    Vue.mixin({
    	methods: {
    		hasAuth(perm) {
    			var authority = this.$store.state.menus.permList
    
    			return authority.indexOf(perm) > -1
    		}
    	}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    之前我们在加载菜单的时候说过,我们同时要加载权限数据,现在就需要用到权限数据了,这里数组,因此我们通过按钮的权限是否在所有权限列表内就行了。

    mixin的作用是多个组件可以共享数据和方法,在使用mixin的组件中引入后,mixin中的方法和属性也就并入到该组件中,可以直接使用,在已有的组件数据和方法进行了扩充。

    引入mixin分全局引用和局部引用。

    然后我们需要在main.js中引入这个文件
    在这里插入图片描述

    import global from './globalFun'
    
    • 1

    在这里插入图片描述

    v-if="hasAuth('sys:user:save')"
    
    • 1

    刷新页面
    没有也新增按钮
    在这里插入图片描述
    测试有对应去权限
    在这里插入图片描述

    
    	let authoritys = ['sys:user:list', "sys:user:save", "sys:user:delete"]
    
    
    • 1
    • 2
    • 3

    刷新页面
    在这里插入图片描述

  • 相关阅读:
    buuctf-web-p6 [NPUCTF2020]web 狗
    MySQL主从复制+读写分离
    一个简单算法解决集群定时任务重复执行
    Day08--自定义组件的behaviors(等用于vue中的mixins)
    如何解决 flaky test 调试成本高问题?
    微服务(一) go kratos 用户服务
    低代码+知识管理,打造智能化供应链管理系统
    Taro + vue3 中微信小程序中实现拉起支付
    运动控制比例随动系统学习笔记
    从北斗到Mate 50:星空中的中国式浪漫
  • 原文地址:https://blog.csdn.net/qq_44757034/article/details/124072716