前言
这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战。恰逢掘金
八月更文挑战,今天向大家分享一些使用Vue实现用户注册,同时校验数据格式并实时显示密码强度,希望这个小demo能够给初学Vue的小伙伴一点小启发,帮助大家更好地去理解和学习。加油,共勉!
页面样式展示
需求分析
除了默认的性别为男以外,其他字段都是必填项,否则点击注册按钮时不予提交,与此同时提醒用户填写,并将鼠标聚焦到对应未填写的输入框上,填写格式错误时亦是如此。
例如:
年龄通过监听输入的出生年月,等到输入完立即自动计算得出,此字段不需要用户填写,可设置为 disabled 。
效果:
当用户按下按键输入密码的同时就开始实时监听判断,密码长度必须大于等于 6 位且不超过 16 位,满足条件就能看到密码强度显示效果,否则将无效。
示例:
代码实现
HTML 结构 + 简单的内联 CSS 样式
<div id="register">
<table>
<tr>
<th>用户名:</th>
<td><input type="text" id="username" placeholder="请输入用户名" autocomplete="off" v-model="user.username"/></td>
</tr>
<tr>
<th>姓名:</th>
<td><input type="text" id="name" placeholder="请输入姓名" autocomplete="off" v-model="user.name"/></td>
</tr>
<tr>
<th>性别:</th>
<td>
<label>
<input type="radio" name="sex" value="1" checked v-model="user.gender"/>
男
</label>
<label>
<input type="radio" name="sex" value="0" v-model="user.gender"/>
女
</label>
</td>
</tr>
<tr>
<th>出生年月:</th>
<td>
<label>
<input type="date" id="birthday" placeholder="请选择出生年月" v-model="user.birthday"/>
</label>
</td>
</tr>
<tr>
<th>年龄:</th>
<td>
<input type="number" id="age" disabled v-model="user.age"/>
</td>
</tr>
<tr>
<th>手机号码:</th>
<td>
<input type="tel" id="mobile" placeholder="请输入电话号码" autocomplete="off" v-model="user.mobile"/>
</td>
</tr>
<tr>
<th>密码:</th>
<td><input type="password" id="password" placeholder="请输入密码" autocomplete="off" v-model="user.password" v-on:keyup="strengthShow"/></td>
</tr>
<tr>
<th style="width: max-content;"></th>
<td>
<span id="weak">弱</span>
<span id="medium">中</span>
<span id="strong">强</span>
</td>
</tr>
<tr>
<th style="width: max-content;"></th>
<td><span style="color: red; font-size: smaller;">{{msg}}</span></td>
</tr>
<tr>
<th style="width: max-content;"></th>
<td>
<button @click="checkForm">注册</button>
<button onclick="history.back()" style="display: inline-block;margin-left: 70px">返回</button>
</td>
</tr>
</table>
</div>
这里不做过多的解释,代码并不复杂,主要是密码强度显示条样式:
#weak,
#medium,
#strong {
display: inline-block;
height: 15px;
width: 48px;
border-top: 4px solid gainsboro;
margin-left: 3px;
font-size: 12px;
text-align: center;
}
Vue 部分
var vm = new Vue({
el: '#register',
data: {
user: {
username: null,
name: null,
gender: 1,
birthday: null,
age: 0,
mobile: null,
password: null
},
msg: null
},
methods: {
checkForm: function () {
const emptyKey = isEmptyInput();
switch (emptyKey) {
case 'username':
msgForUser('用户名不能为空!', emptyKey);
break;
case 'name':
msgForUser('姓名不能为空!', emptyKey);
break;
case 'birthday':
msgForUser('出生年月不能为空!', emptyKey);
break;
case 'mobile':
msgForUser('手机号码不能为空!', emptyKey);
break;
case 'password':
msgForUser('密码不能为空!', emptyKey);
break;
default:
// 非空验证判断完毕,对电话号码的格式的正则验证
if(!(/^1([345789])\d{9}$/.test(this.user.mobile))) {
this.msg = '手机号码格式有误!';
}else if(this.user.password.length < 6 || this.user.password.length > 16) {
this.msg = '密码长度必须在6-16位之间!'
}else { // 都验证完了之后,将注册信息请求到后端,注册一个新用户
const user = this.user;
$.ajax({
type: 'POST',
url: './registerUser',
data: user,
success: function (data) {
handleRegister(data);
},
error: function (error) {
alert(error);
}
});
}
}
},
strengthShow: function () { // 密码强度实时显示
// 弱密码:全是数字或全是字母,6-16个字符
const weakReg = /^[0-9]{6,16}$|^[a-zA-Z]{6,16}$/;
// 中密码:数字和26个英文字母,6-16个字符
const mediumReg = /^[A-Za-z0-9]{6,16}$/;
// 强密码:由数字、26个英文字母或者下划线组成的字符串,6-16个字符
const strongReg = /^\w{6,16}$/;
var password = this.user.password;
if(null !== password) {
if(password.length >= 6 && password.length <= 16) {
if(password.match(weakReg)) {
$('#weak').css('borderTopColor', 'yellow');
}else if(password.match(mediumReg)) {
$('#weak').css('borderTopColor', 'yellow');
$('#medium').css('borderTopColor', 'blue');
}else if(password.match(strongReg)) {
$('#weak').css('borderTopColor', 'yellow');
$('#medium').css('borderTopColor', 'blue');
$('#strong').css('borderTopColor', 'green');
}
}else {
$('#weak').css('borderTopColor', 'gainsboro');
$('#medium').css('borderTopColor', 'gainsboro');
$('#strong').css('borderTopColor', 'gainsboro');
}
}
}
},
watch: {
// 监视对象中属性值变化
user: {
handler: function () {
var birthday = this.user.birthday;
if(birthday !== null) {
var gap = getGrowAge(birthday);
// 截取岁之前的数字,作为计算的年龄
var index = gap.indexOf('岁');
this.user.age = parseInt(gap.substring(0,index));
}
this.msg = null;
},
deep: true
}
}
});
Vue 代码中定义了一个用户对象以及给用户的提醒信息,定义了两个方法,其中一个方法用于表单验证,并通过 @click="checkForm" 也就是 v-on:click="checkForm" 简写,注册按钮绑定了一个点击事件,点击按钮后从上往下一一进行验证。
上述代码中包含了三个封装后的函数,通过对注册用户对象的循环,判断属性值是否为 null 或者为 空格字符串,出现任意一种情况,就结束循环返回属性名,并通过 msgForUser() 函数将提醒信息反馈给用户,并通过属性名找到 input 表单实现聚焦,等待用户再次输入。第三个函数,显示注册成功与否的消息,并实现页面等待跳转。
三个函数具体实现如下:
// 进行表单判断,验证用户输入
function msgForUser(text, id) {
vm.msg = text;
const obj = $(`#${id}`);
obj.focus();
}
// 判断是否表单是否为空,返回 key
function isEmptyInput() {
const entries = Object.entries(vm.user);
var key = null;
for(const [k, v] of entries) {
if(v === null || (v.toString()).match(/^[ ]*$/)) {
key = k;
break;
}
}
return key;
}
// 将注册成功与否的消息显示,并在 750 毫秒后跳转到菜单首页
function handleRegister(data) {
alert(data.msg);
setTimeout(function () {
// 登录成功后跳转到首页
window.location.href = '../index.html';
},750);
}
v-model="user.password" v-on:keyup="strengthShow" 密码通过双向绑定,可以通过添加键盘按下事件动态地监听密码状态,并实时显示密码强度。
那如何根据输入的出生日期动态计算年龄呢?
顺手写一个工具函数,将当前时间转换为秒减去生日转换后的秒数,再用得到的差转化为相差的年数、月数、小时数甚至分秒数。注意闰年的情况,获取不同年份下不同月份的天数。
// 获取出生年龄,周岁、月、天、时、分、秒
function getGrowAge(birthday){
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
var myDate = new Date(birthday);
var myYear = myDate.getFullYear();
var myMonth = myDate.getMonth() + 1;
var myDay = myDate.getDate();
var myHour = myDate.getHours();
var myMinute = myDate.getMinutes();
var mySecond = myDate.getSeconds();
var gapSecond = second - mySecond;
if(gapSecond < 0){
minute -= 1;
gapSecond = 60 - mySecond + second;
}
//gapSecond = gapSecond<10? ("0"+gapSecond): gapSecond;
var gapMinute = minute - myMinute;
if(gapMinute < 0){
hour -= 1;
gapMinute = 60 - myMinute + minute;
}
//gapMinute = gapMinute<10? ("0"+gapMinute): gapMinute;
var gapHour = hour - myHour;
if(gapHour < 0){
day -= 1;
gapHour = 24 - myHour + hour;
}
//gapHour = gapHour<10? ("0"+gapHour): gapHour;
var gapDay = day - myDay;
if(gapDay < 0){
month -= 1;
gapDay = getDaysOfMonth(birthday) - myDay + day;
}
//gapDay = gapDay<10? ("0"+gapDay): gapDay;
var gapMonth = month - myMonth;
if(gapMonth < 0){
year -= 1;
gapMonth = 12 - myMonth + month;
}
//gapMonth = gapMonth<10? ("0"+gapMonth): gapMonth;
var gapYear = year - myYear;
if(gapYear < 0){
gapYear = 0;
}
var dateStr = (gapYear>0?gapYear:'0') + '岁' +
(gapMonth>0?gapMonth:'0') + '月' +
(gapDay>0?gapDay:'0') + '天' +
(gapHour>0?gapHour:'0') + '时' +
(gapMinute>0?gapMinute:'0') + '分' +
(gapSecond>0?gapSecond:'0') + '秒';
return dateStr;
}
// 获取当月的天数
function getDaysOfMonth(dateStr){
var date = new Date(dateStr);
var year = date.getFullYear();
var mouth = date.getMonth() + 1;
var day = 0;
if(mouth == 2) {
day= isLeapYear(year) ? 29 : 28;
} else if(mouth == 1 || mouth == 3 || mouth == 5 ||
mouth == 7 || mouth == 8 || mouth == 10 || mouth == 12) {
day= 31;
} else {
day= 30;
}
return day;
}
// 判断是否为闰年
function isLeapYear(year){
return (year%4==0 && year%100!=0)||(year%400==0);
}
将写好的函数放到一个 js 文件中,在该页面中引入即可,并配合 Vue 的数据绑定,轻松实现理想中的效果,是不是很简单呢?!
结尾
撰文不易,欢迎大家点赞、评论,你的关注、点赞是我坚持的不懈动力,感谢大家能够看到这里!Peace & Love。