Vue日期時間選擇器元件使用方法詳解
阿新 • • 發佈:2021-08-18
本文例項為大家分享了日期時間選擇器元件的具體程式碼,供大家參考,具體內容如下
1.效果圖如下
單選日期選擇器
多選日期選擇器
日期時間選擇器
2.準備
Date原型格式化工具方法
Date.prototype.format = function(fmt) { //author: meizz var o = { "M+": this.getMonth() + 1,//月份 "d+": this.getDate(),//日 "h+": this.getHours(),//小時 "m+": this.getMinutes(),//分 "s+": this.getSeconds(),//秒 "q+": Math.floor((this.getMonth() + 3) / 3),//季度 S: this.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace( RegExp.$1,(this.getFullYear() + "").substr(4 - RegExp.$1.length) ); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace( RegExp.$1,RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) ); return fmt; };
根據傳入時間日期解析出該月份,獲取該月的第一天和最後一天的時間戳,和該月時間戳對應的星期
【注意】
- 一定要解析該月份第一天的零點零分,大部分日期解析為那天的8點,但有些日期會解析為那天的零點零分,這樣就會出現時間戳錯誤,導致獲取該月份天數錯誤
- 因為一般顯示該月份是包含上月或者下個月的一些在該月星期的日期,所以也要計算出該月包含的幾個星期的天
getMonthDay() { //該月第一天 var monthFirst = new Date(this.year + "-" + this.month + "-01 00:00"); var w = monthFirst.getDay(); //下個月第一天減去1s為該月最後一天時間 this.startDay = monthFirst.getTime() - w * 24 * 3600 * 1000; if (this.month == 12) { this.endDay = new Date(this.year + 1 + "-01-01 00:00").getTime() - 1000; } else { this.endDay = new Date(this.year + "-" + (this.month + 1) + "-01 00:00").getTime() - 1000; } //計算該月包含的星期,並獲取對應星期的第一天 var monthDay = (this.endDay + 1000 - this.startDay) / (24 * 3600 * 1000); this.weekNum = Math.ceil(monthDay / 7); //獲取對應的該月天數 this.monthList = []; for (var i = 0; i < this.weekNum; i++) { var item = []; for (var j = 0; j < 7; j++) { item.push( this.startDay + i * 24 * 3600 * 1000 * 7 + j * 24 * 3600 * 1000 ); } this.monthList.push(item); } },
3.具體實現
S樣式
.date-picker-boVvHlSPYOSg { position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 5; } .date-picker { background-color: white; position: fixed; display: block; padding: 4px; z-index: 6; border: solid 1px gainsboro; border-radius: 2px; .picker-top { display: flex; flex-direction: row; align-items: center; height: 30px; line-height: 30px; .picker-arrow { display: inline-flex; align-items: center; justify-content: center; width:30px; height: 30px; cursor: pointer; .iconfont { color: #8a8a8a; } .iconfont:active,.iconfont:hover { color: #388dea; } } .date-text { flex: 1; font-weight: bold; display: inline-block; text-align: center; font-size: 14px; } } .picker-content { display: block; border-top: solid 1px gainsboro; border-bottom: solid 1px gainsboro; height: 160px; table { width: 100%; border-collapse: collapse; border-spacing: 0; font-size: 12px; line-height: 20px !important; thead > tr { background-color: #cedeee; th { text-align: center; font-weight: normal; } } tbody { tr { td { font-weight: 600; cursor: pointer; text-align: center; } td.gray { font-weight: normal; color: #8a8a8a; } td.active { color: white; background: #388dea; } } } } } .picker-content1 { @extend .picker-content; display: flex; flex-direction: row; table { width: calc(100% - 40px); } .hour-list { display: inline-block; list-style: none; padding: 0; margin: 0; height: 100%; overflow-x: hidden; width: 40px; font-size:12px; overflow-y: auto; li { padding: 0; margin: 0; display: flex; align-items: center; padding: 0 4px; height:20px; cursor: pointer; } li:not(:last-child) { border-bottom: solid 1px gainsboro; } li.active { color: white; background: #388dea; } } .hour-list::-webkit-scrollbar { background: transparent; height: 8px; width:8px; border: none; } .hour-list::-webkit-scrollbar-thumb { background: lightgray; border-radius:5px; } //設定滾動條 end } .picker-footer { display: block; line-height: 30px; text-align: right; white-space: nowrap; button { outline: none; border: solid 1px gainsboro; border-radius: 2px; color: #8a8a8a; height: 24px; font-size: 12px; background-color: #f3f3f3; } button:active,button:hover { border-color: #388dea; color: #388dea; background-color: #d9edf6; } } }
單選日期選擇器DatePicker
<template> <div style="display:inline-block"> <span @click="showPicker">{{getLangText(label.datePicker)}}</span> <div class="date-picker-bg" v-show="isShow" @click="closePicker"></div> <div class="date-picker" v-show="isShow" :style="{width:'220px',top:pickerTop>0?pickerTop+'px':''}" > <div class="picker-top"> <span class="picker-arrow" @click="preYear">‹ ‹</span> <span class="picker-arrow" @click="preMonth">‹</span> <span class="date-text">{{year}}-{{month>9?month:"0"+month}}</span> <span class="picker-arrow" @click="nextMonth">›</span> <span class="picker-arrow" @click="nextYear">››</span> </div> <!--生成對應的月份星期表格 start--> <div class="picker-content"> <table> <thead> <tr> <th v-for="(item,idx) in weekList" :key="'week'+idx">{{getLangText(item)}}</th> </tr> </thead> <tbody> <tr v-for="idx in weekNum" :key="'weekNum'+idx"> <td v-for="m in 7" :key="'monthDay'+idx+'_'+m" :class="[new Date(monthList[idx-1][m-1]).getMonth()+1==month?'':'gray',selectDate==monthList[idx-1][m-1]?'active':'']" @click="onSelectDate(monthList[idx-1][m-1])" @dblclick="onConfirmDate(monthList[idx-1][m-1])" >{{new Date(monthList[idx-1][m-1]).getDate()}}</td> <!--日期為該月為深色否則為淺色--> </tr> </tbody> </table> </div> <!--生成對應的月份星期表格 end--> <div class="picker-footer"> <button @click="closePicker">{{getLangText(label.close)}}</button> <button @click="setNow">{{getLangText(label.today)}}</button> <!-- <button @click="confirmPicker">{{getLangText(label.ok)}}</button> --> </div> </div> </div> </template> <script> Date.prototype.format = function(fmt) { //author: meizz var o = { "M+": this.getMonth() + 1,RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) ); return fmt; }; export default { name: "DatePicker",props: { langType: { type: String,default: window.localStorage.getItem("langType") },date: { type: String,default: new Date().format("yyyy-MM-dd") },isScroll: { type: Boolean,default: false },isShow:{ type:Boolean,default:false } },data: () => ({ label: { ok: { zh: "確定",en: "OK" },close: { zh: "關閉",en: "close" },today: { zh: "今天",en: "today" },datePicker: { zh: "日期選擇",en: "DatePicker" } },weekList: [ { zh: "日",en: "Sun" },{ zh: "一",en: "Mon" },{ zh: "二",en: "Tue" },{ zh: "三",en: "Wed" },{ zh: "四",en: "Thu" },{ zh: "五",en: "Fir" },{ zh: "六",en: "Sat" } ],year: new Date().getFullYear(),month: new Date().getMonth() + 1,day: new Date().getDate(),startDay: 0,endDay: 0,weekNum: 0,selectDate: new Date(new Date().format("yyyy-MM-dd 00:00")).getTime(),monthList: [],pickerTop: 0 }),watch: { year() { this.getMonthDay(); },month() { this.getMonthDay(); } },methods: { getLangText(item) { if (item) { if (this.langType == "en") { if (item.en && item.en.length > 1) { return item.en.substring(0,1).toUpperCase() + item.en.substring(1); } else if (item.en && item.en.length == 1) { return item.en.toUpperCase(); } else { return "--"; } } else { return item.zh ? item.zh : "--"; } } else { return "--"; } },preYear() { this.year = this.year - 1; },nextYear() { this.year = this.year + 1; },nextMonth() { if (this.month == 12) { this.year = this.year + 1; this.month = 1; } else { this.month++; } },preMonth() { if (this.month == 1) { this.year = this.year - 1; this.month = 12; } else { this.month--; } },showPicker(e) { if (this.isScroll) { this.pickerTop = e.clientY + e.offsetY; var h = document.getElementById("app").offsetHeight; if (this.pickerTop > h - 230) { this.pickerTop = h - 230; } } this.$emit("update:is-show",true); var time = new Date(this.date).getTime(); this.year = new Date(time).getFullYear(); this.month = new Date(time).getMonth() + 1; this.day = new Date(time).getDate(); this.selectDate = new Date( new Date(time).format("yyyy-MM-dd 00:00") ).getTime(); },onConfirmDate(time) { this.onSelectDate(time); this.confirmPicker(); },closePicker() { this.$emit("update:is-show",false); },setNow() { this.year = new Date().getFullYear(); this.month = new Date().getMonth() + 1; this.day = new Date().getDate(); this.selectDate = new Date( new Date().format("yyyy-MM-dd 00:00") ).getTime(); },confirmPicker() { this.$emit("update:date",new Date(this.selectDate).format("yyyy-MM-dd")); this.$emit( "picker-result",new Date(this.selectDate + this.selectHour * 3600000).format( "yyyy-MM-dd hh:00" ) ); this.closePicker(); },getMonthDay() { var monthFirst = new Date(this.year + "-" + this.month + "-01 00:00"); var w = monthFirst.getDay(); this.startDay = monthFirst.getTime() - w * 24 * 3600 * 1000; if (this.month == 12) { this.endDay = new Date(this.year + 1 + "-01-01 00:00").getTime() - 1000; } else { this.endDay = new Date(this.year + "-" + (this.month + 1) + "-01 00:00").getTime() - 1000; } var monthDay = (this.endDay + 1000 - this.startDay) / (24 * 3600 * 1000); this.weekNum = Math.ceil(monthDay / 7); this.monthList = []; for (var i = 0; i < this.weekNum; i++) { var item = []; for (var j = 0; j < 7; j++) { item.push( this.startDay + i * 24 * 3600 * 1000 * 7 + j * 24 * 3600 * 1000 ); } this.monthList.push(item); } },onSelectDate(time) { this.selectDate = time; this.year = new Date(time).getFullYear(); this.month = new Date(time).getMonth() + 1; this.day = new Date(time).getDate(); this.$emit("update:date",new Date(time).format("yyyy-MM-dd")); } },mounted() { this.getMonthDay(); } }; </script> <style lang="scss" scoped> </style>
多選日期選擇器DatePicker1
<template>
<div style="display:inline-block">
<span @click="showPicker">日期選擇</span>
<div class="date-picker-bg" v-show="isShow" @click="closePicker"></div>
<div class="date-picker" v-show="isShow" style="width:220px">
<div class="picker-top">
<span class="picker-arrow" @click="preYear">‹ &lsaquo;</span>
<span class="picker-arrow" @click="preMonth">‹</span>
<span class="date-text">{{year}}-{{month>9?month:"0"+month}}</span>
<span class="picker-arrow" @click="nextMonth">&rsaquoVvHlSPYOSo;</span>
<span class="picker-arrow" @click="nextYear">››</span>
</div>
<!--生成對應的月份星期表格 start-->
<div class="picker-content">
<table>
<thead>
<tr>
<th v-for="(item,getSelectDate(monthList[idx-1][m-1])?'active':'']"
@click="onSelectDate(monthList[idx-1][m-1])"
>{{new Date(monthList[idx-1][m-1]).getDate()}}</td>
<!--日期為該月為深色否則為淺色-->
</tr>
</tbody>
</table>
</div>
<!--生成對應的月份星期表格 end-->
<div class="picker-footer">
<button @click="onFullMonth">整月</button>
<button @click="onSelectDate(new Date(new Date().format('yyyy-MM-dd 00:00')).getTime())">今天</button>
<button @click="closePicker">關閉</button>
</div>
</div>
</div>
</template>
<script>
Date.prototype.format = function(fmt) {
//author: meizz
var o = {
"M+": this.getMonth() + 1,default: "zh"
},default: ""
},data: () => ({
weekList: [
{ zh: "日",result: []
}),watch: {
date() {
this.parseDate();
},year() {
this.getMonthDay();
},preMonth() {
if (this.month == 1) {
this.year = this.year - 1;
this.month = 12;
} else {
this.month--;
}
},getSelectDate(time) {
for (var i = 0; i < this.result.length; i++) {
if (time == this.result[i]) {
return true;
}
}
return false;
},showPicker(e) {
this.$emit("update:is-show",true);
var time = new Date().getTime();
this.year = new Date(time).getFullYear();
this.month = new Date(time).getMonth() + 1;
this.day = new Date(time).getDate();
this.selectDate = new Date(
new Date(time).format("yyyy-MM-dd 00:00")
).getTime();
},onSelectDate(time) {
this.selectDate = time;
this.year = new Date(time).getFullYear();
this.month = new Date(time).getMonth() + 1;
this.day = new Date(time).getDate();
var tag = true;
//已選擇就取消選擇
for (var i = 0; i < this.result.length; i++) {
if (this.result[i] == time) {
tag = false;
this.result.splice(i,1);
break;
}
}
//未選擇就新增日期
if (tag) {
this.result.push(time);
this.result = this.result.sort(function(a,b) {
return a - b;
});
}
var list = [];
for (var i = 0; i < this.result.length; i++) {
if (this.result[i] > 0) {
list.push(new Date(this.result[i]).format("yyyy-MM-dd"));
}
}
if (list.length > 0) {
this.$emit("update:date",list.join(",") + "(共" + list.length + "天)");
} else {
this.$emit("update:date","");
}
this.$emit("picker-result",this.result);
},onFullMonth() {
this.$emit("update:date",this.year + "年" + this.month + "月份");
this.$emit("picker-result",30);
},parseDate() {
if (this.date) {
var str = this.date;
if (this.date.indexOf("(") > 0) {
str = this.date.substring(0,this.date.indexOf("("));
}
if (str) {
var list = str.split(",");
var result = [];
for (var i = 0; i < list.length; i++) {
result.push(
new Date(
new Date(list[i]).format("yyyy-MM-dd 00:00:00")
).getTime()
);
}
this.result = result;
}
}
}
},mounted() {
this.getMonthDay();
this.parseDate();
}
};
</script>
<style lang="scss" scoped>
</style>
日期時間選擇器
<template> <div style="display:inline-block"> <span @click="showPicker">{{getLangText(label.datetimePicker)}}</span> <div class="date-picker-bg" v-show="isShow" @click="closePicker"></div> <div class="date-picker" v-show="isShow" style=" width: 260px;"> <div class="picker-top"> <span class="picker-arrow" @click="preYear">‹ ‹</span> <span class="picker-arrow" @click="preMonth">‹</span> <span class="date-text">{{year}}-{{month>9?month:"0"+month}}</span> <span class="picker-arrow" @click="nextMonth">›</span> <span class="picker-arrow" @click="nextYear">››</span> </div> <div class="picker-content1"> <table> <thead> <tr> <th v-for="(item,selectDate==monthList[idx-1][m-1]?'active':'']" @click="onSelectDate(monthList[idx-1][m-1])" @dblclick="onConfirmDate(monthList[idx-1][m-1])" >{{new Date(monthList[idx-1][m-1]).getDate()}}</td> </tr> </tbody> </table> <ul class="hour-list"> <li v-for="n in 24" :key="'hourList'+n" @click="onSelectHour(n-1)" :class="[selectHour==n-1?'active':'']" @dblclick="onConfirmHour(n-1)" >{{n-1}}:00</li> </ul> </div> <div class="picker-footer"> <button @click="closePicker">{{getLangText(label.close)}}</button> <button @click="setNow">{{getLangText(label.today)}}</button> <!-- <button @click="confirmPicker">{{getLangText(label.ok)}}</button> --> </div> </div> </div> </template> <script> Date.prototype.format = function(fmt) { //author: meizz var o = { "M+": this.getMonth() + 1,RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) ); return fmt; }; export default { name: "DateTimePicker",datetime: { type: String,default: new Date().format("yyyy-MM-dd hh:00") },data: () => ({ label: { ok: { zh: "確定",today: { zh: "現在",en: "now" },datetimePicker: { zh: "日期時間選擇",en: "datetimePicker" } },selectHour: new Date().getHours() }),showPicker() { this.$emit("update:is-show",true); var time = new Date(this.datetime).getTime(); this.year = new Date(time).getFullYear(); this.month = new Date(time).getMonth() + 1; this.day = new Date(time).getDate(); this.selectDate = new Date( new Date(time).format("yyyy-MM-dd 00:00") ).getTime(); this.selectHour = new Date(time).getHours(); },onConfirmHour(n) { this.onSelectHour(n); this.confirmPicker(); },setNow() { this.year = new Date().getFullYear(); this.month = new Date().getMonth() + 1; this.day = new Date().getDate(); this.selectDate = new Date( new Date().format("yyyy-MM-dd 00:00") ).getTime(); this.selectHour = new Date().getHours(); },confirmPicker() { this.$emit( "update:datetime",new Date(this.selectDate + this.selectHour * 3600000).format( "yyyy-MM-dd hh:00" ) ); this.$emit( "picker-result",getMonthDay() { var monthFirst = new Date(this.year + "-" + this.month + "-01 00:00"); var w = monthFirst.getDay(); this.startDay = monthFirst.getTime() - w * 24 * 3600 * 1000; if (this.month == 12) { this.endDay = new Date(this.year + 1 + "-01-01 00:00").getTime() - 1000; } else { this.endDay = new Date(this.year + "-" + (this.month + 1) + "-01 00:00").getTime() - 1000; } var monthDay = (this.endDay + 1000 - this.startDay) / (24 * 3600 * 1000); this.weekNum = Math.ceil(monthDay / 7); this.monthList = []; for (var i = 0; i < this.weekNum; i++) { var item = []; www.cppcns.com for (var j = 0; j < 7; j++) { item.push( this.startDay + i * 24 * 3600 * 1000 * 7 + j * 24 * 3600 * 1000 ); } this.monthList.push(item); } },onSelectHour(n) { this.selectHour = n; this.$emit( "update:datetime",new Date(this.selectDate + this.selectHour * 3600000).format( "yyyy-MM-dd hh:00" ) ); },onSelectDate(time) { this.selectDate = time; this.year = new Date(time).getFullYear(); this.month = new Date(time).getMonth() + 1; this.day = new Date(time).getDate(); this.$emit( "update:datetime",new Date(time + this.selectHour * 3600000).format("yyyy-MM-dd hh:00") ); } },mounted() { this.getMonthDay(); } }; </script> <style lang="scss" scoped> </style>
使用Picker
<template> <section style="padding:16px;"> <p>date1:{{date1}}</p> <date-picker :date.sync="date1" :is-show.sync="showDate1"></date-picker> <p>date2:{{date2}}</p> <date-picker1 :date.sync="date2" :is-show.sync="showDate2"></date-picker1> <p>date3:{{date3}}</p> <datetime-picker :datetime.sync="date3" :is-show.sync="showDate3"></datetime-picker> </section> </template> <script> Date.prototype.format = function(fmt) { //author: meizz var o = { "M+" : this.getMonth()+1,//月份 "d+" : this.getDate(),//日 "h+" : this.getHours(),//小時 "m+" : this.getMinutes(),//分 "s+" : this.getSeconds(),//秒 "q+" : Math.floor((this.getMonth()+3)/3),//季度 "S" : this.getMilliseconds() //毫秒 }; if(/(y+)/.test(fmt)) fmt=fmt.replace(RegExp.$1,(this.getFullYear()+"").substr(4 - RegExp.$1.length)); for(var k in o) if(new RegExp("("+ k +")").test(fmt)) fmt = fmt.replace(RegExp.$1,(RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); return fmt; } import DateTimePicker from "./DateTimePicker"; import DatePicker from "./DatePicker"; import DatePicker1 from "./DatePicker1"; export default { name:"PickerTest",components:{ 'date-picker':DatePicker,'datetime-picker':DateTimePicker,'date-picker1':DatePicker1 },data:()=>({ showDate1:false,showDate2:false,showDate3:false,date1:new Date().format("yyyy-MM-dd"),date2:new Date().format("yyyy-MM-dd"),date3:new Date().format("yyyy-MM-dd hh:mm:ss"),}) } </script> <style> </style>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。