vue 密码强弱设置
resetPass.vue
<style scoped lang="scss">
@import "~@a/style/variables.scss";
.password-score {
display: flex;
border-radius: 4px;
p {
width: 33.3%;
text-align: center;
height: 20px;
line-height: 20px;
font-size: $font-sm;
color: $white;
background-color: #ccc;
&.weak {
border-radius: 4px 0 0 4px;
}
&.strong {
border-radius: 0 4px 4px 0;
}
&.weak.active {
background-color: #f05050;
}
&.middle.active {
background-color: #ffbd4a;
}
&.strong.active {
background-color: #81c868;
}
}
}
</style>
<template>
<yv-dialog title="重置密码" :visible.sync="visible">
<yv-form ref="passwordForm" :model="passwordForm" :rules="passwordFormRule" label-width="100px">
<yv-form-item label="用户名">
<yv-tag type="info">root</yv-tag>
</yv-form-item>
<yv-form-item label="密码" prop="password">
<yv-input style="width: 330px;margin-right: 12px" v-model="passwordForm.password" :type="passwordType"
autocomplete="new-password" :maxlength="30" @change="changePasswordWarning" />
<yv-checkbox v-model="showPassword" @change="changePassword">显示密码</yv-checkbox>
<template slot="tips">
<p class="w400">密码8-30位字符,需同时包含大小写、英文、数字,不能为键盘上连续3位及以上字符,不可包含空格及以下字符# $ % & * < ></p>
<div v-if="showPasswordWarning" class="password-score mt8" style="width: 310px">
<p :class="['weak', this.passwordScore <= 60 ? 'active' : '']">弱</p>
<p :class="['middle', this.passwordScore > 60 && this.passwordScore < 70 ? 'active' : '']">中</p>
<p :class="['strong', this.passwordScore >= 70 ? 'active' : '']">强</p>
</div>
</template>
</yv-form-item>
<yv-form-item label="重复密码" prop="password1">
<yv-input style="width: 330px;margin-right: 12px" v-model="passwordForm.password1" :type="passwordType"
autocomplete="new-password" :maxlength="30" />
</yv-form-item>
</yv-form>
<div slot="footer" class="dialog-footer">
<yv-button size="small" @click="cancelDialog">取 消</yv-button>
<yv-button type="primary" size="small" @click="saveDialog" :loading="saving">
<span v-if="saving">提交中...</span>
<span v-else>确定</span>
</yv-button>
</div>
</yv-dialog>
</template>
<script>
import ApiInstance from '@/api/module/instance'
import { validatePasswordUtil, calcPwdScore } from '@util'
export default {
name: "InstanceResetPassword",
data() {
const validatePassword = (rule, value, callback) => {
if (!value) {
return callback(new Error('密码不能为空'))
} else {
if (validatePasswordUtil(value)) {
callback()
} else {
return callback(new Error('密码格式不正确'))
}
}
}
const validatePassword1 = (rule, value, callback) => {
if (this.passwordForm.password !== value) {
return callback(new Error('两次密码输入不一致'))
}
callback()
}
return {
visible: false,
saving: false,
id:'',
passwordForm: {
username: 'root',
password: '',
password1: ''
},
passwordType: 'password',
showPassword: false,
showPasswordWarning: false,
passwordScore: 0,
passwordFormRule: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 8, max: 17, message: '长度在 8 到 17 个字符', trigger: 'blur' },
{validator: validatePassword, trigger: 'blur'}
],
password1: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{ min: 8, max: 17, message: '长度在 8 到 17 个字符', trigger: 'blur' },
{validator: validatePassword1, trigger: 'blur'}
],
}
}
},
methods: {
changePasswordWarning (val) {
if (val) {
this.showPasswordWarning = true
if (validatePasswordUtil(val)) {
this.passwordScore = calcPwdScore(val)
} else {
this.passwordScore = 59
}
} else {
this.showPasswordWarning = false
}
},
changePassword (val) {
if (val) {
this.passwordType = 'text'
} else {
this.passwordType = 'password'
}
},
cancelDialog() {
this.$refs.passwordForm.resetFields()
this.visible = false
},
saveDialog() {
this.$refs.passwordForm.validate(valid => {
if (valid) {
this.saving = true
ApiInstance.resetPassword(this.id, this.passwordForm).then(() => {
this.$refs.passwordForm.resetFields()
this.visible = false
}).finally(() => {
this.saving = false;
})
}
})
},
}
}
</script>
utils/index.js
// 深拷贝对象
export function deepClone(obj) {
const _toString = Object.prototype.toString
// null, undefined, non-object, function
if (!obj || typeof obj !== 'object') {
return obj
}
// DOM Node
if (obj.nodeType && 'cloneNode' in obj) {
return obj.cloneNode(true)
}
// Date
if (_toString.call(obj) === '[object Date]') {
return new Date(obj.getTime())
}
// RegExp
if (_toString.call(obj) === '[object RegExp]') {
const flags = []
if (obj.global) {
flags.push('g') }
if (obj.multiline) {
flags.push('m') }
if (obj.ignoreCase)