spring boot 与 iview 前后端分离架构之首页退出和修改密码的实现(二十三)
公众号
大家可以直接微信扫描上面的二维码关注我的公众号,然后回复【bg23】 里面就会给到源代码的下载地址同时会附上相应的视频教程,并定期在我的公众号上给大家推送相应的技术文章,欢迎大家关注我的公众号。
首页退出和修改密码的实现
通过上一章节我们已经实现了动态加载菜单栏和,动态显示我们的面包屑导航了,但是我们的首页还缺少退出以及修改密码的选项,因此本章将为大家讲解如何实现退出和修改密码的实现。
添加修改密码的mock数据
由于我们现在的前端一直都是使用的mock数据,因此我们需要添加修改密码的mock数据,在我们的以下目录底下新增一个user.changePassword.js文件
{
"code": 200,
"msg": "密码更新成功",
"obj": null
}
接着在mock.js文件中引入修改密码的mock,新增代码如下:
import changePassword from './json/user/user.changePassword'
Mock.mock('/user/changePassword', 'post', changePassword);
修改密码的实现
接着我们在main目录底下创建一个changePassword.vue实现密码的修改,代码如下:
<template>
<Modal v-model="show" title="修改密码" @on-ok="ok" :loading="loading" :mask-closable="false">
<Form ref="changePasswordForm" :model="changePasswordForm" :rules="changePasswordFormRule">
<FormItem label="当前密码" prop="oldPassword">
<Input type="password" :maxlength=50 v-model="changePasswordForm.oldPassword" placeholder="请输入当前密码"/>
</FormItem>
<FormItem label="新密码" prop="newPassword">
<Input type="password" :maxlength=50 v-model="changePasswordForm.newPassword" placeholder="请输入新密码"/>
</FormItem>
<FormItem label="新密码二次确认" prop="checkNewPassword">
<Input type="password" :maxlength=50 v-model="changePasswordForm.checkNewPassword" placeholder="请再次输入上面的密码"/>
</FormItem>
</Form>
</Modal>
</template>
<script>
import {changePassword} from '../../api/sys/user/user.api'
export default {
name: "addDict",
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
show: this.value,
loading: true,
changePasswordForm: {
oldPassword: '',
newPassword: '',
checkNewPassword: ''
},
changePasswordFormRule: {
oldPassword: [
{required: true, message: '请输入旧的密码', trigger: 'blur'},
{type: 'string', max: 50, min: 6, message: '密码最小长度为6', trigger: 'blur'}
],
newPassword: [
{required: true, message: '请输入新密码', trigger: 'blur'},
{type: 'string', max: 50, min: 6, message: '密码最小长度为6', trigger: 'blur'}
],
checkNewPassword:[
{required: true, message: '请再次输入密码', trigger: 'blur'},
{type: 'string', max: 50, min: 6, message: '密码最小长度为6', trigger: 'blur'},
{
validator:this.validatorPassword({
response: 'exist'
}), trigger: 'blur'
}
]
}
}
},
methods: {
ok() {
this.$refs['changePasswordForm'].validate((valid) => {
if (valid) {
changePassword(this.changePasswordForm).then(res => {
if (res.code == 200) {
this.$Message.success(res.msg);
// 提交表单数据成功则关闭当前的modal框
this.closeModal(false);
} else {
this.$Message.error( res.msg);
}
})
}
setTimeout(() => {
this.loading = false;
this.$nextTick(() => {
this.loading = true;
});
}, 1000);
})
},
closeModal(val) {
this.$emit('input', val);
},
validatorPassword(){
let _this = this;
return function (rule, value, callback) {
let newPassword = _this.changePasswordForm.newPassword;
let checkNewPassword = _this.changePasswordForm.checkNewPassword;
if(newPassword!=''&&checkNewPassword!=''){
if(newPassword!=checkNewPassword){
callback(new Error("两次输入的密码不匹配"));
}else{
callback();
}
}else{
callback();
}
}
}
},
watch: {
value(val) {
this.show = val;
},
show(val) {
//当重新显示增加数据的时候重置整个form表单
if (val) {
this.$refs['changePasswordForm'].resetFields();
} else {// 反之则关闭页面
this.closeModal(val);
}
}
}
}
</script>
接着我们改造我们的main.vue页面,改造完成以后的代码如下:
<template>
<div class="layout">
<Layout>
<!-- Header 表示头部的位置-->
<Header id="layout-header-scroll">
<Menu mode="horizontal" theme="dark" active-name="1">
<div class="layout-logo">
[外链图片转存失败(img-RxJEOSUf-1562209731086)(https://mp.csdn.net/assets/logo.png)]
</div>
<div class="layout-nav">
<Dropdown @on-click="userAction">
<a href="javascript:void(0)" style="color: white">
{{this.nickName}}
</a>
<DropdownMenu slot="list">
<DropdownItem name="regPass">修改密码</DropdownItem>
<DropdownItem name="loginOut" divided>退出登录</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<div class="layout-nav">
<language @on-lang-change="setLanguage" style="margin-right: 10px;" :lang="local"/>
</div>
<div class="layout-nav">
<template v-for="item in menuList">
<Submenu :name="item.meta.code" v-if="item.children.length>0">
<template slot="title">
<Icon :type="item.meta.icon"/>
{{item.meta.title}}
</template>
<template v-for="childrenItem in item.children">
<MenuItem :name=childrenItem.meta.code :to="item.path+'/'+childrenItem.path">
<Icon :type=childrenItem.meta.icon>
</Icon>
{{childrenItem.meta.title}}
</MenuItem>
</template>
</Submenu>
<MenuItem :name="item.meta.code" v-else>
<Icon :type="item.meta.icon"/>
{{item.meta.title}}
</MenuItem>
</template>
</div>
</Menu>
</Header>
<!-- 此处表示的是左侧的菜单栏的布局 -->
<Layout>
<Sider hide-trigger :style="{background: '#fff'}">
<Menu active-name="1-2" theme="light" width="auto" :open-names="['system-manage']">
<template v-for="item in menuList">
<Submenu :name=item.meta.code>
<template slot="title">
<Icon :type=item.meta.icon></Icon>
{{item.meta.title}}
</template>
<template v-for="childrenItem in item.children">
<MenuItem :name=childrenItem.meta.code :to="item.path+'/'+childrenItem.path">
<Icon :type=childrenItem.meta.icon>
</Icon>
{{childrenItem.meta.title}}
</MenuItem>
</template>
</Submenu>
</template>
</Menu>
</Sider>
<Layout :style="{padding: '0 24px 24px'}">
<!-- 此处是面包屑导航条 -->
<Breadcrumb :style="{margin: '24px 0'}">
<BreadcrumbItem>
<Icon type="ios-home-outline"></Icon>
首页
</BreadcrumbItem>
<BreadcrumbItem v-for="item in breadCrumbList" v-bind:key="item.name" v-if="item.meta && item.meta.title">
<Icon :type="item.icon"></Icon>
{{showBreadcrumbItem(item)}}
</BreadcrumbItem>
</Breadcrumb>
<!-- 此处存放的是文本内容的区域 -->
<Content :style="{padding: '24px', minHeight: '280px', background: '#fff'}">
<router-view/>
</Content>
</Layout>
</Layout>
</Layout>
<changePassword v-model="showChangePassword"></changePassword>
</div>
</template>
<script>
import Language from '../../components/language';
import {mapMutations, mapActions} from 'vuex';
import changePassword from './changePassword';
export default {
components: {
Language,
changePassword
},
data() {
return {
local: localStorage.getItem("lang"),
showChangePassword: false
}
},
methods: {
...mapMutations([
'setBreadCrumb'
]),
...mapActions([
'handleLogOut'
]),
/**
* 顶部跟随着滚动条的变化而滚动
*/
handleScroll() {
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop >= 60) {
document.querySelector('#layout-header-scroll').style.top = scrollTop + 'px';
} else {
document.querySelector('#layout-header-scroll').style.top = '0px';
}
},
userAction(name) {
// 实现退出登录
if (name == 'loginOut') {
this.handleLogOut();
this.turnToView('login');
// 实现修改密码
} else if (name == 'regPass') {
this.showChangePassword = true;
}
},
setLanguage(lang) {
this.local = lang
localStorage.setItem('lang', lang)
},
showBreadcrumbItem(item) {
return (item.meta && item.meta.title) || item.name
},
turnToView(name) {
this.$router.push({
name: name
})
}
},
watch: {
'$route'(newRoute) {
this.setBreadCrumb(newRoute.matched)
}
},
computed: {
breadCrumbList() {
return this.$store.state.app.breadCrumbList
},
menuList() {
return this.$store.getters.menuList;
},
nickName() {
return this.$store.getters.nickName;
}
},
mounted() {
/**
* 监听滚动条的滚动事件
*/
window.addEventListener('scroll', this.handleScroll)
}
}
</script>
<style scoped>
.layout-header {
position: relative;
z-index: 999;
height: 60px;
}
.layout {
border: 1px solid #d7dde4;
background: #f5f7f9;
position: relative;
border-radius: 4px;
overflow: hidden;
}
.layout-logo {
width: 100px;
height: 30px;
border-radius: 10px;
float: left;
position: relative;
left: 20px;
top: 5px;
}
.layout-nav {
width: auto;
float: right;
margin: 0 auto;
margin-right: 20px;
}
</style>
最后我们运行我们的项目,大家会看到如下的页面则说明我们的集成以及成功了。
到此为止我们就完成了首页面包屑的实现了。
上一篇文章地址:spring boot+iview 前后端分离架构之首页菜单栏的实现(二十二)
下一篇文章地址:spring boot+iview 前后端分离架构之后端鉴权体系的实现(二十四)