CMDB前端开发(上)
大纲
- 登录页面
- 后台基本布局
登录页面
- 前端代码架构可以参考: https://blog.51cto.com/devwanghui/6193473
- 开发前预览页面
仪表盘占位页面开发
- 创建视图: devops_web/src/views/dashboard/Dashboard.vue
<template>
这是仪表盘
</template>
<script>
export default {
name: "Dashboard"
}
</script>
<style scoped>
</style>
- dashboard路由处理: devops_web/src/router/index.js
...
const routes = [
{
path: '/',
name: '首页',
icon: 'Monitor',
component: Layout,
redirect: '/dashboard',
children: [
{
path: '/dashboard',
name: '仪表盘',
component: () => import('../views/dashboard/Dashboard.vue')
}
]
},
....
- Layout页面修改(将默认的首页设置为dashboard,并且是一级菜单): devops_web/src/views/Layout.vue
<template>
<div class="common-layout">
<el-container>
<el-aside :width="isCollapse ? '64px' : '200px'">
<el-menu
default-active="2"
background-color="#304156"
text-color="#FFFFFF"
active-text-color="#ffd04b"
class="el-menu"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
:collapse-transition="false"
router
>
<div class="logo">
<img src="../assets/logo.png" alt="">
</div>
<template v-for="menu in this.$router.options.routes" :key="menu">
<!-- 单独处理仪表盘的菜单-->
<el-menu-item v-if="menu.path == '/'" :index="menu.children[0].path">
<el-icon><component :is="menu.children[0].icon" /></el-icon>
<span>{{menu.name}}</span>
</el-menu-item>
<!-- 处理有子路由的菜单 -->
<el-sub-menu v-else :index="menu.path">
<template #title>
<el-icon><component :is="menu.icon" /></el-icon>
<span>{{menu.children[0].name}}</span>
</template>
<el-menu-item v-for="child in menu.children" :key="child" :index="child.path">{{child.name}}</el-menu-item>
</el-sub-menu>
</template>
</el-menu>
</el-aside>
<el-container>
<el-header>
<!-- 导航栏折叠-->
<div class="toggleCollapse">
<el-icon :size="25" @click="toggleCollapse"><Fold /></el-icon>
</div>
<!-- 头像-->
<el-dropdown>
<span class="el-dropdown-link">
<img src="../assets/avatar.png" alt="">
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>密码修改</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<el-main>
<!-- 占位符,显示路由跳转后加载的内容-->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: 'Layout',
data() {
return {
isCollapse: false
}
},
methods: {
toggleCollapse() {
this.isCollapse = !this.isCollapse
}
}
}
</script>
<style>
.common-layout, .el-container, .el-menu {
height: 100%;
}
.el-header {
border-bottom: 1px lightgrey solid;
}
.el-aside {
background: grey;
}
.el-main {
background: #FFFFF;
}
.collapse-transition {
cursor: pointer;
}
.logo img {
width: 200px;
height: 60px;
/*margin-left: 10px;*/
}
.el-dropdown-link img {
width: 50px;
height: 50px;
border-radius: 50%;
flex: auto;
}
.el-header {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>
- 页面测试
登录页面大体布局和数据提交
静态页面布局
- 登录页面准备独立页面:devops_web/src/views/Login.vue
<template>
<div class="main">
<div class="login_box">
<div class="title">
欢迎访问DevOps运维平台
</div>
<div class="login_form">
<el-form label-width="30px">
<el-form-item>
<el-input
:prefix-icon="User"
placeholder="用户名"
v-model="form.username"
></el-input>
</el-form-item>
<el-form-item>
<el-input
:prefix-icon="Lock"
placeholder="密码"
type="password"
v-model="form.password"
show-password
></el-input>
</el-form-item>
<el-form-item class="btn">
<el-button type="primary" @click="onSubmit" >登录</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script>
// input里加图标必须单独按需导入
import { User, Lock } from "@element-plus/icons-vue";
export default {
name: 'Login',
data() {
return {
form: {
username: '',
password: ''
}
}
},
methods: {
onSubmit() {
console.log("aaa")
}
},
// 需要用setup导入
setup() {
return {
User,Lock
}
}
}
</script>
<style scoped>
.main {
background-image: url("../assets/img/login_background.jpeg");
background-size: 100% 100%;
height: 100%;
}
.login_box {
width: 400px;
height: 300px;
background-color: #FFFFFF;
box-shadow: 0 5px 20px 0 #e8e8e8;
border-radius: 20px;
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
margin: auto;
}
.title {
font-size: 20px;
font-weight: bold;
color: #409eff;
text-align: center;
margin-top: 30px;
}
.login_form {
margin-top: 40px;
margin-right: 30px;
}
.btn {
margin-left: 36%;
}
.btn .el-button {
width: 140px;
}
</style>
- 登录页面路由: devops_web/src/router/index.js
...
const routes = [
{
path: '/login',
name: '登录',
component: () => import('../views/Login.vue')
},
{
path: '/',
name: '首页',
component: Layout,
redirect: '/dashboard',
children: [
{
path: '/dashboard',
name: '仪表盘',
icon: 'Monitor',
component: () => import('../views/dashboard/Dashboard.vue')
}
]
},
....
- 页面测试:
数据提交
- 项目安装axios
cd devops_web
npm install axios
- 配置axios: devops_web/src/api/http.js
import axios from "axios"
import {ElMessage} from "element-plus"
const instance = axios.create({
baseURL: 'http://127.0.0.1:8000/api',
timeout: 5000
})
//请求拦截器
instance.interceptors.request.use(config => {
//在请求api之前携带token
const token = window.sessionStorage.getItem('token')
if (token) {
config.headers = {
'Authorization': 'Token ' + token
}
}
return config;
}, error => {
return Promise.reject(error)
})
//响应拦截器
instance.interceptors.response.use(response => {
//处理响应数据
if (response.data.code != 200 ) {
ElMessage.error(response.data.msg)
}
return response
}, error => {
//处理catch的地方
ElMessage('连接服务器失败,请稍后再试!!')
return Promise.reject(error)
})
export default instance
- 全局注册axios: devops_web/src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import * as ElIconModules from '@element-plus/icons-vue'
//导入axios, 重新封装的axios
import axios from "./api/http";
const app = createApp(App)
app.use(ElementPlus)
for(let iconName in ElIconModules) {
app.component(iconName,ElIconModules[iconName])
}
app.config.globalProperties.$http = axios;
app.use(router).mount('#app')
- 登录提交函数: devops_web/src/views/Login.vue
<template>
<div class="main">
<div class="login_box">
<div class="title">
欢迎访问DevOps运维平台
</div>
<div class="login_form">
<el-form :model="form" ref="form" :rules="rules" label-width="30px">
<el-form-item prop="username">
<el-input
:prefix-icon="User"
placeholder="用户名"
v-model="form.username"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
:prefix-icon="Lock"
placeholder="密码"
type="password"
v-model="form.password"
show-password
></el-input>
</el-form-item>
<el-form-item class="btn">
<el-button type="primary" @click="onSubmit" >登录</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script>
// input里加图标必须单独按需导入
import { User, Lock } from "@element-plus/icons-vue";
export default {
name: 'Login',
data() {
return {
form: {
username: '',
password: ''
},
rules: {
username: [
{required: true, message: '请输入用户名', trigger: 'blur'},
{min: 3, message: '用户名长度应不小于3个字符', trigger: 'blur'}
],
password: [
{required: true, message: '请输入密码', trigger: 'blur'},
{min: 6, message: '用户名长度应不小于6个字符', trigger: 'blur'}
]
}
}
},
methods: {
onSubmit() {
// 提交前预验证
this.$refs.form.validate((valid) => { //回调函数中valid布尔值
if (valid) {
// 登陆成功并给消息提示
this.$http.post('/login/', this.form)
.then(res => {
if (res.data.code == 200) {
this.$message.success('登录成功');
// 保存token
window.sessionStorage.setItem("token", res.data.token);
this.$router.push('/dashboard/')
}
})
} else {
this.$message.warning('用户名或密码格式错误!')
}
})
}
},
// 需要用setup导入
setup() {
return {
User,Lock
}
}
}
</script>
<style scoped>
.main {
background-image: url("../assets/img/login_background.jpeg");
background-size: 100% 100%;
height: 100%;
}
.login_box {
width: 400px;
height: 300px;
background-color: #FFFFFF;
box-shadow: 0 5px 20px 0 #e8e8e8;
border-radius: 20px;
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
margin: auto;
}
.title {
font-size: 20px;
font-weight: bold;
color: #409eff;
text-align: center;
margin-top: 30px;
}
.login_form {
margin-top: 40px;
margin-right: 30px;
}
.btn {
margin-left: 36%;
}
.btn .el-button {
width: 140px;
}
</style>
- 配置Layout隐藏没有子路由的项目:devops_web/src/views/Layout.vue
<template>
<div class="common-layout">
<el-container>
<el-aside :width="isCollapse ? '64px' : '200px'">
<el-menu
default-active="2"
background-color="#304156"
text-color="#FFFFFF"
active-text-color="#ffd04b"
class="el-menu"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
:collapse-transition="false"
router
>
<div class="logo">
<img src="../assets/logo.png" alt="">
</div>
<template v-for="menu in this.$router.options.routes" :key="menu">
<!-- 一级菜单 没有子路由的菜单-->
<!-- <el-menu-item v-if="!menu.children" :index="menu.path">-->
<!-- <el-icon><component :is="menu.icon" /></el-icon>-->
<!-- <span>{{menu.name}}</span>-->
<!-- </el-menu-item>-->
<!-- 单独处理仪表盘的菜单-->
<el-menu-item v-if="menu.path == '/'" :index="menu.children[0].path">
<el-icon><component :is="menu.children[0].icon" /></el-icon>
<span>{{menu.children[0].name}}</span>
</el-menu-item>
<!-- 处理有子路由的菜单 -->
<el-sub-menu v-else-if="menu.children" :index="menu.path">
<template #title>
<el-icon><component :is="menu.icon" /></el-icon>
<span>{{menu.name}}</span>
</template>
<el-menu-item v-for="child in menu.children" :key="child" :index="child.path">{{child.name}}</el-menu-item>
</el-sub-menu>
</template>
</el-menu>
</el-aside>
<el-container>
<el-header>
<!-- 导航栏折叠-->
<div class="toggleCollapse">
<el-icon :size="25" @click="toggleCollapse"><Fold /></el-icon>
</div>
<!-- 头像-->
<el-dropdown>
<span class="el-dropdown-link">
<img src="../assets/avatar.png" alt="">
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>密码修改</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<el-main>
<!-- 占位符,显示路由跳转后加载的内容-->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: 'Layout',
data() {
return {
isCollapse: false
}
},
methods: {
toggleCollapse() {
this.isCollapse = !this.isCollapse
}
}
}
</script>
<style>
.common-layout, .el-container, .el-menu {
height: 100%;
}
.el-header {
border-bottom: 1px lightgrey solid;
}
.el-aside {
background: grey;
}
.el-main {
background: #FFFFF;
}
.collapse-transition {
cursor: pointer;
}
.logo img {
width: 200px;
height: 60px;
/*margin-left: 10px;*/
}
.el-dropdown-link img {
width: 50px;
height: 50px;
border-radius: 50%;
flex: auto;
}
.el-header {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>
- 解决后端跨域问题: 安装django-cors-headers
pip3 install django-cors-headers
- 配置后端跨域app: devops_api/devops_api/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'rest_framework_swagger',
'django_filters',
'cmdb',
'system_config',
'corsheaders'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware'
]
CORS_ORIGIN_ALLOW_ALL = True
配置导航守卫,控制访问权限
目前虽然已经实现登录功能,即使没有登录情况下直接访问任何页面都还可以访问的,我们希望如果用户没有登录情况下,访问任何页面都重新导航到登录页面
- 退出登录功能完善: devops_web/src/views/Layout.vue
<template>
<div class="common-layout">
<el-container>
<el-aside :width="isCollapse ? '64px' : '200px'">
<el-menu
default-active="2"
background-color="#304156"
text-color="#FFFFFF"
active-text-color="#ffd04b"
class="el-menu"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
:collapse-transition="false"
router
>
<div class="logo">
<img src="../assets/logo.png" alt="">
</div>
<template v-for="menu in this.$router.options.routes" :key="menu">
<!-- 一级菜单 没有子路由的菜单-->
<!-- <el-menu-item v-if="!menu.children" :index="menu.path">-->
<!-- <el-icon><component :is="menu.icon" /></el-icon>-->
<!-- <span>{{menu.name}}</span>-->
<!-- </el-menu-item>-->
<!-- 单独处理仪表盘的菜单-->
<el-menu-item v-if="menu.path == '/'" :index="menu.children[0].path">
<el-icon><component :is="menu.children[0].icon" /></el-icon>
<span>{{menu.children[0].name}}</span>
</el-menu-item>
<!-- 处理有子路由的菜单 -->
<el-sub-menu v-else-if="menu.children" :index="menu.path">
<template #title>
<el-icon><component :is="menu.icon" /></el-icon>
<span>{{menu.name}}</span>
</template>
<el-menu-item v-for="child in menu.children" :key="child" :index="child.path">{{child.name}}</el-menu-item>
</el-sub-menu>
</template>
</el-menu>
</el-aside>
<el-container>
<el-header>
<!-- 导航栏折叠-->
<div class="toggleCollapse">
<el-icon :size="25" @click="toggleCollapse"><Fold /></el-icon>
</div>
<!-- 头像-->
<el-dropdown>
<span class="el-dropdown-link">
<img src="../assets/avatar.png" alt="">
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>密码修改</el-dropdown-item>
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<el-main>
<!-- 占位符,显示路由跳转后加载的内容-->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: 'Layout',
data() {
return {
isCollapse: false
}
},
methods: {
toggleCollapse() {
this.isCollapse = !this.isCollapse
},
//退出登录函数
logout() {
window.sessionStorage.clear()
this.$router.push('/login')
}
}
}
</script>
<style>
.common-layout, .el-container, .el-menu {
height: 100%;
}
.el-header {
border-bottom: 1px lightgrey solid;
}
.el-aside {
background: grey;
}
.el-main {
background: #FFFFF;
}
.collapse-transition {
cursor: pointer;
}
.logo img {
width: 200px;
height: 60px;
/*margin-left: 10px;*/
}
.el-dropdown-link img {
width: 50px;
height: 50px;
border-radius: 50%;
flex: auto;
}
.el-header {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>
- 配置导航守卫,登录token获取才能查看页面,否则不能正常访问页面: devops_web/src/router/index.js
...
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
// 添加导航守卫
router.beforeEach((to, from, next) => {
// 如果用户访问登录页,直接放行
if(to.path == '/login') {
return next()
}
// 从sessionStorage获取token值
const token = window.sessionStorage.getItem('token');
// 如果没有获取到token值,跳转到登录页
if (!token) {
return next('/login')
}
// 正常跳转
next()
});
export default router
- 页面token检查
后台基本布局
显示用户名
- 上述例子已经在保存token的时候保存了username
- 只需要在头像旁边配置username显示即可: devops_web/src/views/Layout.vue
<template>
<div class="common-layout">
<el-container>
<el-aside :width="isCollapse ? '64px' : '200px'">
<el-menu
default-active="2"
background-color="#304156"
text-color="#FFFFFF"
active-text-color="#ffd04b"
class="el-menu"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
:collapse-transition="false"
router
>
<div class="logo">
<img src="../assets/logo.png" alt="">
</div>
<template v-for="menu in this.$router.options.routes" :key="menu">
<!-- 一级菜单 没有子路由的菜单-->
<!-- <el-menu-item v-if="!menu.children" :index="menu.path">-->
<!-- <el-icon><component :is="menu.icon" /></el-icon>-->
<!-- <span>{{menu.name}}</span>-->
<!-- </el-menu-item>-->
<!-- 单独处理仪表盘的菜单-->
<el-menu-item v-if="menu.path == '/'" :index="menu.children[0].path">
<el-icon><component :is="menu.children[0].icon" /></el-icon>
<span>{{menu.children[0].name}}</span>
</el-menu-item>
<!-- 处理有子路由的菜单 -->
<el-sub-menu v-else-if="menu.children" :index="menu.path">
<template #title>
<el-icon><component :is="menu.icon" /></el-icon>
<span>{{menu.name}}</span>
</template>
<el-menu-item v-for="child in menu.children" :key="child" :index="child.path">{{child.name}}</el-menu-item>
</el-sub-menu>
</template>
</el-menu>
</el-aside>
<el-container>
<el-header>
<!-- 导航栏折叠-->
<div class="toggleCollapse">
<el-icon :size="25" @click="toggleCollapse"><Fold /></el-icon>
</div>
<!-- 头像-->
<el-dropdown>
<span class="el-dropdown-link">
<img src="../assets/avatar.png" alt="">
<span>{{username}}</span>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>密码修改</el-dropdown-item>
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<el-main>
<!-- 占位符,显示路由跳转后加载的内容-->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: 'Layout',
data() {
return {
isCollapse: false,
username: window.sessionStorage.getItem('username')
}
},
methods: {
toggleCollapse() {
this.isCollapse = !this.isCollapse
},
logout() {
window.sessionStorage.clear()
this.$router.push('/login')
}
}
}
</script>
<style>
.common-layout, .el-container, .el-menu {
height: 100%;
}
.el-header {
border-bottom: 1px lightgrey solid;
}
.el-aside {
background: grey;
}
.el-main {
background: #FFFFF;
}
.collapse-transition {
cursor: pointer;
}
.logo img {
width: 200px;
height: 60px;
/*margin-left: 10px;*/
}
//头像和用户名显示并排操作,需要username跟头像在两个不同的元素中才行
.el-dropdown-link {
display: flex;
align-items: center;
}
//缩小头像比例
.el-dropdown-link img {
width: 30px;
height: 30px;
border-radius: 50%;
flex: auto;
}
.el-header {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>
- 效果展示
修改密码
- 修改密码后端接口
- 前端需要使用的dialog对话框: https://element-plus.gitee.io/zh-CN/component/dialog.html
- 修改密码对话框添加: devops_web/src/views/Layout.vue
<template>
<div class="common-layout">
<el-container>
<el-aside :width="isCollapse ? '64px' : '200px'">
<el-menu
default-active="2"
background-color="#304156"
text-color="#FFFFFF"
active-text-color="#ffd04b"
class="el-menu"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
:collapse-transition="false"
router
>
<div class="logo">
<img src="../assets/logo.png" alt="">
</div>
<template v-for="menu in this.$router.options.routes" :key="menu">
<!-- 一级菜单 没有子路由的菜单-->
<!-- <el-menu-item v-if="!menu.children" :index="menu.path">-->
<!-- <el-icon><component :is="menu.icon" /></el-icon>-->
<!-- <span>{{menu.name}}</span>-->
<!-- </el-menu-item>-->
<!-- 单独处理仪表盘的菜单-->
<el-menu-item v-if="menu.path == '/'" :index="menu.children[0].path">
<el-icon><component :is="menu.children[0].icon" /></el-icon>
<span>{{menu.children[0].name}}</span>
</el-menu-item>
<!-- 处理有子路由的菜单 -->
<el-sub-menu v-else-if="menu.children" :index="menu.path">
<template #title>
<el-icon><component :is="menu.icon" /></el-icon>
<span>{{menu.name}}</span>
</template>
<el-menu-item v-for="child in menu.children" :key="child" :index="child.path">{{child.name}}</el-menu-item>
</el-sub-menu>
</template>
</el-menu>
</el-aside>
<el-container>
<el-header>
<!-- 导航栏折叠-->
<div class="toggleCollapse">
<el-icon :size="25" @click="toggleCollapse"><Fold /></el-icon>
</div>
<!-- 头像-->
<el-dropdown>
<span class="el-dropdown-link">
<img src="../assets/avatar.png" alt="">
<span>{{username}}</span>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="dialogVisible=true">密码修改</el-dropdown-item>
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<el-main>
<!-- 占位符,显示路由跳转后加载的内容-->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
<!-- 修改密码对话框 dialogVisible 在修改密码按钮处有click事件调起-->
<el-dialog
v-model="dialogVisible"
title="修改密码"
width="30%"
>
<el-form :model="UserPasswordForm" label-position="right" label-width="100px" :rules="rules" ref="UserPasswordForm">
<el-form-item label="原密码:" prop="old_password">
<el-input
v-model="UserPasswordForm.old_password"
type="password"
show-password
></el-input>
</el-form-item>
<el-form-item label="新密码:" prop="new_password">
<el-input
v-model="UserPasswordForm.new_password"
type="password"
show-password
></el-input>
</el-form-item>
<el-form-item label="再次确认:" prop="confirm_password">
<el-input
v-model="UserPasswordForm.confirm_password"
type="password"
show-password
></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="changePasswordSubmit">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script>
export default {
name: 'Layout',
data() {
// 新旧密码校验规则
const checkNewOldPassword = (rule, value, callback) => {
if (value == this.UserPasswordForm.old_password) {
callback(new Error('新密码不能与旧密码一样!'))
} else {
return callback()
}
};
const checkNewPassword = (rule, value, callback) => {
if (value != this.UserPasswordForm.new_password) {
callback(new Error('两次输入密码不一致!'))
} else {
return callback()
}
};
return {
isCollapse: false,
username: window.sessionStorage.getItem('username'),
dialogVisible: false,
UserPasswordForm: {
old_password: '',
new_password: '',
confirm_password: ''
},
rules: {
old_password: [
{required: true, message: '请输入原密码', trigger: 'blur'},
{min: 6, message: '用户名长度应不小于6个字符', trigger: 'blur'}
],
new_password: [
{required: true, message: '请输入新密码', trigger: 'blur'},
{min: 6, message: '用户名长度应不小于6个字符', trigger: 'blur'},
{validator: checkNewOldPassword, trigger: 'blur'}
],
confirm_password: [
{required: true, message: '请确认新密码', trigger: 'blur'},
{min: 6, message: '用户名长度应不小于6个字符', trigger: 'blur'},
{validator: checkNewPassword, trigger: 'blur'}
]
}
}
},
methods: {
toggleCollapse() {
this.isCollapse = !this.isCollapse
},
logout() {
window.sessionStorage.clear()
this.$router.push('/login')
},
changePasswordSubmit() {
// 提交前预验证
this.$refs.UserPasswordForm.validate((valid) => {
// 回调函数中valid布尔值
console.log(this.UserPasswordForm)
if (valid) {
//获取用户名
const username = window.sessionStorage.getItem('username')
this.UserPasswordForm['username'] = username
this.$http.post('/change_password/', this.UserPasswordForm)
.then(res => {
if (res.data.code == 200) {
this.$message.success(res.data.msg);
this.dialogVisible = false
}
})
}
})
}
}
}
</script>
<style>
.common-layout, .el-container, .el-menu {
height: 100%;
}
.el-header {
border-bottom: 1px lightgrey solid;
}
.el-aside {
background: grey;
}
.el-main {
background: #FFFFF;
}
.collapse-transition {
cursor: pointer;
}
.logo img {
width: 200px;
height: 60px;
/*margin-left: 10px;*/
}
.el-dropdown-link {
display: flex;
align-items: center;
}
.el-dropdown-link img {
width: 30px;
height: 30px;
border-radius: 50%;
flex: auto;
margin-right: 10px;
}
.el-header {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>
- 测试密码修改功能