- 需求: 点击按钮弹出模态框,用户利用date+time控件输入时间;点击提交时,若输入格式完整,则添加一条记录到页面并关闭模态框;若输入格式有误,则模态框不关闭,且显示警告文字;当用户重新输入时警告文字消失
- 美化: 从左到右排列记录,间距适当,队列末尾放置+号按钮,并添加浅色虚线背景框,弹出的模态框居中显示,尺寸适宜
- 技术: HTML + Bootstrap + CSS + Vue.js
HTML代码:
<div class="container-fluid" id="example">
<!-- Bootstrap网格系统布局,使一行排列4项 -->
<div class="row">
<!-- Vue.js v-for循环实现数据叠加 -->
<div class="col-3" v-for="(item, index) in items" :key="index">
<div class="jumbotron p-3 board">
<h6 class="text-center">第 {{ index+1 }} 次计时</h6>
<br>
<p>开始时间:{{ item.startTime }}</p>
<p>结束时间:{{ item.endTime }}</p>
</div>
</div>
<div class="col-3">
<div class="addBtn">
<!-- Bootstrap modal组件,弹出模态框 -->
<a href="#addModal" data-toggle="modal" data-backdrop="static"><i class="fas fa-plus-circle"></i></a>
</div>
</div>
</div>
<!-- 模态框内容 -->
<div class="modal" id="addModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content modalContent">
<div class="modal-header">
<h6 class="modal-title">添加记录</h6>
<button class="close" data-dismiss="modal"><span>×</span></button>
</div>
<div class="modal-body">
<!-- input group组件 -->
<div class="input-group my-3">
<div class="input-group-prepend">
<span class="input-group-text">开始时间:</span>
</div>
<!-- Vue.js v-model双向绑定表单数据,v-on绑定focus事件 -->
<input type="datetime-local" class="form-control" placeholder="YYYY-MM-DD hh:mm" v-model="stVal" @focus.stop="onFocus">
</div>
<div class="input-group my-3">
<div class="input-group-prepend">
<span class="input-group-text">结束时间:</span>
</div>
<input type="datetime-local" class="form-control" placeholder="YYYY-MM-DD hh:mm" v-model="etVal" @focus.stop="onFocus">
</div>
</div>
<div class="modal-footer">
<!-- 格式有误时的警告文字,v-show切换是否可见 -->
<span class="text-danger" v-show="isShow">时间格式有误,请重新输入!</span>
<!-- 提交按钮绑定click事件 -->
<button class="btn btn-primary" @click.stop="onSubmit">提交</button>
<button class="btn btn-secodary" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
</div>
CSS代码:
#example {
width: 100vw;
height: 100vh;
line-height: 1;
padding: 3rem;
}
.board, .addBtn {
width: 260px;
height: 130px;
}
.addBtn {
border: 3px dotted #e9ecef; /* 画虚线框 */
background-color: rgba(233, 236, 239, .3);
text-align: center;
line-height: 130px; /* 使图标居中 */
}
.addBtn i {
color: #e9ecef;
font-size: 3rem; /* 调整图标尺寸 */
}
.modalContent {
width: 400px;
}
JS代码:
//由于本案未在vue中引入jquery,所以要将关闭模态框的modal()方法重新定义一个js方法
var mh = {
modalHide: function(){
$('#addModal').modal('hide');
}
};
var vm = new Vue({
el: '#example',
data: {
items: [
{
startTime: '2018-11-09 16:53',
endTime: '2018-11-11 18:34'
},
{
startTime: '2018-11-12 15:52',
endTime: '2018-12-12 14:25'
},
],
stVal: '', //使输入框初始值为空
etVal: '',
isShow: false //默认警告文字不可见
},
methods: {
//验证格式的方法
testPattern: function(t){
var reg = /[0-9]{4}-[0-9]{2}-[0-9]{2}\s+[0-9]{2}:[0-9]{2}/; //简单位数验证:YYYY-MM-DD hh:mm
return reg.test(t); //参数匹配正则表达式,返回true
},
//“提交”按钮点击事件
onSubmit: function(){
var st = this.stVal.replace(/T/, ' '); //将从输入框获取的值中的T替换为空格
var et = this.etVal.replace(/T/, ' ');
if(this.testPattern(st) && this.testPattern(et)){ //仅当输入的起止时间都符合格式要求时
this.items.push(
{
startTime: st,
endTime: et //将数据添加到数组,并在页面显示新增的记录
},
);
mh.modalHide(); //同时关闭模态框
}
else{
this.isShow = true; //若格式有误则显示警告文字
};
},
//输入框获取焦点事件
onFocus: function(){
this.isShow = false; //切换警告文字为不可见
}
}
})
效果示例: