前端 在处理一些后台管理系统的时候 为了个人用户信息的安全 会由原始的默认密码 在用户第一次登录的时候 要求用户强制更改密码
先分析一下 临界点
1.第一次登录
2.强制更改
3.界面显示问题
先简单看下效果图吧
接下来分析一下思路
1.标识的话(是否第一次登录)最好是由后台接口提供 当然 前端也可以自己存储 不过不建议
2.如果是第一次登录 显示第一次登录弹框 隐藏菜单(根据需求而定)
3.如果不是 正常显示首页
接下来看下代码(vue2+element+vuex) vuex存储 是为了aside显示隐藏
<template>
<div class="syMain">
<img src="@/assets/syBanner.png" alt="" />
<div class="elDelogLogin">
<el-dialog
ref="dailog"
width="40%"
title="初始密码修改"
:show-close="false"
:visible="dialogTableVisible"
>
<div>
<el-steps :active="active" align-center>
<el-step title="初次登录" />
<el-step title="修改初始密码" />
<el-step title="完成" />
</el-steps>
<div v-if="active == 1" class="topTip">
您好,为了您的账号安全,请点击下一步修改初始密码
</div>
<div v-if="active != 3" style="width: 60%; margin: 0 auto;text-align:center">
<el-form
ref="form"
:model="form"
status-icon
:rules="rules"
>
<el-form-item
v-show="active == 1"
label="登陆账号"
>
<el-input
v-model="name"
:disabled="true"
size="medium"
/>
</el-form-item>
<template v-if="active==2">
<el-form-item
label="原密码"
prop="originPwd"
class="password-item"
>
<el-input
type="password"
v-model="form.originPwd"
autocomplete="off"
:show-password="true"
>
</el-input>
</el-form-item>
<el-form-item
label="新密码"
prop="newPwd"
class="password-item"
>
<el-input
type="password"
v-model="form.newPwd"
autocomplete="off"
:show-password="true"
></el-input>
</el-form-item>
<el-form-item
label="确认新密码"
prop="confirmPwd"
class="password-item"
>
<el-input
type="password"
v-model="form.confirmPwd"
:show-password="true"
autocomplete="off"
></el-input>
</el-form-item>
</template>
</el-form>
<div v-if="active!=1" slot="footer" class="dialog-footer">
<el-button @click="resetForm('form')">上一步</el-button>
<el-button type="primary" @click="submitForm('form')">下一步</el-button>
</div>
<div v-else slot="footer" class="dialog-footer">
<el-button type="primary" style="width:75%" @click="nextTip">下一步</el-button>
</div>
</div>
<div v-if="active === 3" class="ImgTip">
<div style="margin:20px 0">
<img v-if="isSuccess===true" src="@/images/chenggong.png" alt="">
<img v-else src="@/images/filer.png">
</div>
<p v-if="isSuccess === true">修改密码成功</p>
<p v-else>网络开小差了,导致密码修改失败,请重新修改</p>
<el-button
v-if="isSuccess === true"
type="primary"
@click="returnDialogTableVisible"
>重新登录</el-button
>
<el-button v-else type="primary" @click="again">重新修改</el-button>
</div>
<div v-if="active == 2" class="tip">
<h4>温馨提示</h4>
<p>1、密码长度不能低于6个字符</p>
<p>2、密码必须由数字、英文字符组成</p>
</div>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import {
mapGetters} from "vuex"
import {
changePassword,OneLoginChecked} from "@/api/user"
import md5 from 'js-md5'
export default {
computed:{
...mapGetters(['name'])
},
data() {
// 是否包含一位数字
const regNumber = /(?=.*[\d])/;
// 是否包含一位字母
const regLetter = /(?=.*[a-zA-Z])/;
// 是否包含一位特殊字符
// const regCharacter = /(?=.*[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、])/
// 校验新密码
const validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('新密码不能为空!请重新输入'))
} else {
if (value.length > 16) {
callback(new Error('密码长度不超过16个字符。'))
} else if (value.length < 6) {
callback(new Error('密码长度不低于6个字符。'))
} else {
if (!/^[a-zA-Z\d]{
1}/.test(value)) {
callback(new Error('密码必须以英文字母或数字开头!'))
} else {
if (!regNumber.test(value)) {
callback(new Error('密码必须由数字,英文字母组成!'))
} else if (!regLetter.test(value)) {
callback(new Error('密码必须由数字,英文字母组成!'))
} else{
callback()
}
}
}
}
}
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'));
} else if (value !== this.form.newPwd) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
};
return {
currentRole: "adminDashboard",
dialogTableVisible: false,
form: {
confirmPwd: "",
newPwd: "",
originPwd: "",
},
isSuccess: false,
active: 1,
rules: {
newPwd: [{
required: true,validator: validatePass, trigger: "blur" }],
confirmPwd: [{
required: true,validator: validatePass2, trigger: "blur" }],
originPwd:[
{
required: true, message: '请输入原始密码', trigger: 'blur' },
]
},
};
},
methods:{
nextTip() {
this.active += 1
},
resetForm() {
this.active -= 1
},
again() {
this.active = 1
},
returnDialogTableVisible() {
this.$store.dispatch('isShowSider', true).then(() => {
this.dialogTableVisible = false
this.$store.dispatch("LogOut").then(() => {
this.$store.dispatch("tagsView/removeVisitedViews").then(()=>{
this.$router.replace({
path: '/login'});
location.reload();
})
});
})
},
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
const params = {
confirmPwd:md5(this.form.confirmPwd),
newPwd:md5(this.form.newPwd),
originPwd:md5(this.form.originPwd)
}
changePassword(params).then(res=>{
if(res.code==0){
this.isSuccess = true
}else{
this.isSuccess = false
}
this.active = 3
})
} else {
return false
}
})
}
},
created(){
OneLoginChecked().then(res => {
const {
code,data} = res
if (code == 0) {
if(data==true){
this.$store.dispatch('isShowSider', true).then(() => {
this.dialogTableVisible = false
})
}else{
this.$store.dispatch('isShowSider', false).then(() => {
this.dialogTableVisible = true
})
}
}
})
}
};
</script>
<style lang="scss" scoped>
.syMain {
// background: #f0f7ff;
// text-align: center;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
.topTip{
text-align: center;
line-height: 30px;
color:red;
font-weight: 700;
margin: 10px 0;
}
.tip{
color:red;
margin-top: 20px;
p{
margin:5px
}
}
.ImgTip{
text-align: center;
margin:0 auto;
p{
margin:20px 0;
}
}
}
</style>
交互效果是直接基于首页来做的 其实这里有一个弊端 就是假设用户第一次进来的不是在首页 此时是拦截不到的 但通常来说 绝大多数 进来的都是在首页 当然 如果第一次进来不是首页 那么则可以通过router.beforeEach进行拦截 具体视情况而定吧 希望对大家有所帮助