vue实现时间选择器,精确到秒
生活随笔
收集整理的這篇文章主要介紹了
vue实现时间选择器,精确到秒
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
時間組件代碼:
/**時間選擇器,精確到秒* <iic-datetime v-model="time"></iic-datetime>* time: new Date()*/ Vue.component("iic-datetime", {props: {value: {type: [Date, String],default: ""},dateFormat: {//時間到天的格式type: String,default: "yyyy-MM-dd"},timeFormat: {//時間從小時到秒的格式type: String,default: "hh:mm:ss"}},mounted: function() {var dateNode = this.$refs.dateTimeRef;var timeNode = this.$refs.timeRef;var inputTimeNode = this.$refs.inputTimeRef;var that = this;window.addEventListener("click", function(e){if (dateNode.contains(e.target)) {if (!timeNode.contains(e.target) && !inputTimeNode.contains(e.target)) {that.timePanelStatus = false;}} else {that.panelState = false;}});if (this.value) {this.initDate( new Date(this.value) );}},destroyed: function() {window.removeEventListener("click", this.eventListener);},data: function() {return {fullTimeValue: "",//顯示日期加精確到秒的時間dateValue: "", // 輸入框顯示日期timeValue: "",//時間選項timePanelStatus: true,//時間選擇面板是否展示date: new Date().getDate(), // 當前日期panelState: false, // 初始值,默認panel關閉tmpMonth: new Date().getMonth(), // 臨時月份,可修改month: new Date().getMonth(),tmpYear: new Date().getFullYear(), // 臨時年份,可修改weekList: [{ label: "周一", value: 0 },{ label: "周二", value: 1 },{ label: "周三", value: 2 },{ label: "周四", value: 3 },{ label: "周五", value: 4 },{ label: "周六", value: 5 },{ label: "周天", value: 6 }], // 周monthList: [{ label: "一月", value: 0 },{ label: "二月", value: 1 },{ label: "三月", value: 2 },{ label: "四月", value: 3 },{ label: "五月", value: 4 },{ label: "六月", value: 5 },{ label: "七月", value: 6 },{ label: "八月", value: 7 },{ label: "九月", value: 8 },{ label: "十月", value: 9 },{ label: "十一月", value: 10 },{ label: "十二月", value: 11 }], // 月hourList: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],//小時nowValue: 0, // 當前選中日期值choseHour: 0,//選中的小時choseMine: 1,choseSec: 1,panelType: "date" // 面板狀態}},watch: {choseHour: function(){this.freshDate();},choseMine: function(){this.freshDate();},choseSec: function(){this.freshDate();}},computed: {minuList: function(){var minuList = [];for (var i = 1; i <= 59; i++){minuList.push(i);}return minuList;},secList: function(){var secList = [];for (var i = 1; i <= 59; i++){secList.push(i);}return secList;},dateList: function(){//獲取當月的天數var currentMonthLength = new Date(this.tmpYear, this.tmpMonth + 1, 0).getDate();//先將當月的日期塞入dateListvar dateList = Array.from({ length: currentMonthLength },function (val, index) {return {currentMonth: true,value: index + 1};});// 獲取當月1號的星期是為了確定在1號前需要插多少天var startDay = new Date(this.tmpYear, this.tmpMonth, 1).getDay();// 確認上個月一共多少天var previousMongthLength = new Date(this.tmpYear, this.tmpMonth, 0).getDate();// 在1號前插入上個月日期for (var i = 0, len = startDay; i < len; i++) {dateList = [{ previousMonth: true, value: previousMongthLength - i }].concat(dateList);}// 補全剩余位置,至少14天,則 i < 15for (var j = 1, item = 1; j < 15; j++, item++) {dateList[dateList.length] = { nextMonth: true, value: j };}return dateList;},changeTmpMonth: function() {return this.monthList[this.tmpMonth].label;},// 通過改變this.tmpYear則可以改變年份數組yearList: function() {return Array.from({ length: 12 }, function(value, index){return this.tmpYear + index;});}},methods: {initDate: function(initDate){this.choseHour = initDate.getHours();this.choseMine = initDate.getMinutes();this.choseSec = initDate.getSeconds();this.fullTimeValue = this.formatDate(initDate.getTime());var dateTimeArr = this.fullTimeValue.split(" ");this.dateValue = dateTimeArr[0];this.timeValue = dateTimeArr[1];},setDateWithNow: function(){this.initDate( new Date() );},togglePanel: function(){this.panelState = !this.panelState;},hourScroll: function(evt){var scrollTop = evt.target.scrollTop;this.choseHour = window.parseInt(scrollTop / 20);},minuScroll: function(evt){var scrollTop = evt.target.scrollTop;this.choseMine = window.parseInt(scrollTop / 20) + 1;},secScroll: function(evt){var scrollTop = evt.target.scrollTop;this.choseSec = window.parseInt(scrollTop / 20) + 1;},openPanel: function(){this.panelState = !this.panelState;this.panelType = "date";},openTime: function(){this.timePanelStatus = true;},selectYear: function(item){this.tmpYear = item;this.panelType = "month";},selectMonth: function(item){this.tmpMonth = item.value;this.panelType = "date";},freshDate: function(item){if (item) {// 賦值 當前 nowValue,用于控制樣式突出顯示當前月份日期this.nowValue = item.value;// 選擇了上個月if (item.previousMonth) this.tmpMonth--;// 選擇了下個月if (item.nextMonth) this.tmpMonth++;}//計算出選中時間對象var selectDay = new Date(this.tmpYear, this.tmpMonth, this.nowValue, this.choseHour, this.choseMine, this.choseSec);// 格式日期為字符串后,賦值給 inputthis.fullTimeValue = this.formatDate(selectDay.getTime());var dateTimeArr = this.fullTimeValue.split(" ");this.dateValue = dateTimeArr[0];this.timeValue = dateTimeArr[1];this.$emit("input", selectDay);},// 日期格式方法formatDate: function(date) {fmt = this.dateFormat + " " + this.timeFormat;if (date === null || date === "null") {return "--";}date = new Date(Number(date));var o = {"M+": date.getMonth() + 1, // 月份"d+": date.getDate(), // 日"h+": date.getHours(), // 小時"m+": date.getMinutes(), // 分"s+": date.getSeconds(), // 秒"q+": Math.floor((date.getMonth() + 3) / 3), // 季度S: date.getMilliseconds() // 毫秒};if (/(y+)/.test(fmt))fmt = fmt.replace(RegExp.$1,(date.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;},validateDate: function(item) {if (this.nowValue === item.value && item.currentMonth) {return true;}},left: function() {if (this.panelType === "year") this.tmpYear--;else {if (this.tmpMonth === 0) {this.tmpYear--;this.tmpMonth = 11;} else this.tmpMonth--;}},leftBig: function() {if (this.panelType === "year") {this.tmpYear -= 12;} else {this.tmpYear--;}},right: function() {if (this.panelType === "year") {this.tmpYear++;} else {if (this.tmpMonth === 11) {this.tmpYear++;this.tmpMonth = 0;} else this.tmpMonth++;}},rightBig: function() {if (this.panelType === "year") {this.tmpYear += 12;} else {this.tmpYear++;}},},template:`<div ref="dateTimeRef" class="iic-input-date"><input class="input date-value" v-model="fullTimeValue" @click="openPanel"/><div class="date-panel" v-show="panelState"><div><input class="input input-date" v-model="dateValue"/><input class="input input-time" v-model="timeValue" ref="inputTimeRef" @click="openTime"/></div><div class="topbar"><span @click="leftBig"><<</span><span @click="left"><</span><span class="year" @click="panelType = \'year\'">{{tmpYear}}</span><span class="month" @click="panelType = \'month\'">{{changeTmpMonth}}</span><span @click="right">></span><span @click="rightBig">>></span></div><div v-show="timePanelStatus" ref="timeRef" class="time-zone"><div class="scroll-content"><div @scroll="hourScroll" class="scroll-wrapper"><ul ref="hourScollRef" class="time-scroll"><li v-for="hour in hourList" :class="{'active': choseHour === hour}">{{hour}}</li></ul></div></div><div class="scroll-content"><div @scroll="minuScroll" class="scroll-wrapper"><ul ref="minuScrollRef" class="time-scroll"><li v-for="minu in minuList" :class="{'active': choseMine === minu}">{{minu}}</li></ul></div></div><div class="scroll-content"><div @scroll="secScroll" class="scroll-wrapper"><ul ref="secScrollRef" class="time-scroll"><li v-for="sec in secList" :class="{'active': choseSec === sec}">{{sec}}</li></ul></div></div><div class="bottom"><button class="btn-ok" @click="timePanelStatus = false;">確認</button></div></div><div class="type-year" v-show="panelType === \'year\'"><ul class="year-list"><li v-for="(item, index) in yearList":key="index"@click="selectYear(item)"><span :class="{selected: item === tmpYear}" >{{item}}</span></li></ul></div><div class="type-year" v-show="panelType === \'month\'"><ul class="year-list"><li v-for="(item, index) in monthList":key="index"@click="selectMonth(item)"><span :class="{selected: item.value === tmpMonth}" >{{item.label}}</span></li></ul></div><div class="date-group" v-show="panelType === \'date\'"><span v-for="(item, index) in weekList" :key="index" class="weekday">{{item.label}}</span><ul class="date-list"><li v-for="(item, index) in dateList"v-text="item.value":class="{preMonth: item.previousMonth, nextMonth: item.nextMonth,selected: date === item.value && month === tmpMonth && item.currentMonth, invalid: validateDate(item)}":key="index"@click="freshDate(item)"></li></ul></div><div class="bottom"><button @click="setDateWithNow">當前時間</button><button @click="togglePanel">確認</button></div></div></div>` });2:在vue實例中使用:
<div id="date"><iic-datetime v-model="time"></iic-datetime></div><script>new Vue({el: "#date",data: {time: new Date()},watch: {time: function(oldVal, newVal){console.info(oldVal);console.info(newVal);}},});</script>樣式:
<style>/* datetime */ .iic-input-date .topbar {padding-top: 8px;} .iic-input-date .topbar span {display: inline-block;width: 20px;height: 30px;line-height: 30px; color: #515a6e;cursor: pointer;} .iic-input-date .topbar span:hover {color: #2d8cf0;} .iic-input-date .topbar .year, .topbar .month {width: 60px;} .iic-input-date .year-list {height: 200px;width: 210px;} .iic-input-date .year-list .selected {background: #2d8cf0;border-radius: 4px;color: #fff;} .iic-input-date .year-list li {display: inline-block;width: 70px;height: 50px;line-height: 50px;border-radius: 10px;cursor: pointer;} .iic-input-date .year-list span {display: inline-block;line-height: 16px;padding: 8px;} .iic-input-date .year-list span:hover { background: #e1f0fe;} .iic-input-date .weekday {display: inline-block; font-size: 13px;width: 30px; color: #c5c8ce;text-align: center;} .iic-input-date {width: 260px;text-align: center;font-family: "Avenir", Helvetica, Arial, sans-serif;position: relative;} .iic-input-date .date-panel {box-shadow: 0 0 8px #ccc;background: #fff;} .iic-input-date ul {list-style: none; padding: 0;margin: 0;} .iic-input-date .date-list { width: 210px;text-align: left;height: 180px; overflow: hidden;margin-top: 4px;} .iic-input-date .date-list li { display: inline-block;width: 28px;height: 28px; line-height: 30px; text-align: center;cursor: pointer; color: #000;border: 1px solid #fff; border-radius: 4px;} .iic-input-date .date-list .selected {border: 1px solid #2d8cf0;} .iic-input-date .date-list .invalid { background: #2d8cf0; color: #fff;} .iic-input-date .date-list .preMonth, .iic-input-date .date-list .nextMonth { color: #c5c8ce;} .iic-input-date .date-list li:hover {background: #e1f0fe;} .iic-input-date .date-panel .date-group{margin-left: 5px;} .iic-input-date .input { display: inline-block; box-sizing: border-box; width: 45%; height: 32px;line-height: 1.5;padding: 4px 7px;font-size: 12px;border: 1px solid #dcdee2;border-radius: 4px;color: #515a6e;background-color: #fff;background-image: none;cursor: text;transition: border 0.2s ease-in-out, background 0.2s ease-in-out,box-shadow 0.2s ease-in-out;margin-bottom: 6px;} .iic-input-date .date-value{width: 100%;} .iic-input-date .input-date{left: 0;position: absolute; top: 36px;} .iic-input-date .input-time{right: 0;position: absolute; top: 36px;} .iic-input-date .time-zone{ top: 73px;position: absolute;width: 115px;height: 130px;background-color: white;white-space: nowrap;border: 1px solid #e4e7ed;right: 0;} .iic-input-date .time-zone::before{content: "";top: 50%;position: absolute;margin-top: -15px;height: 32px;z-index: -1;left: 0;right: 0;box-sizing: border-box;padding-top: 6px;text-align: left;border-top: 1px solid #e4e7ed;border-bottom: 1px solid #e4e7ed;} .iic-input-date .scroll-content{overflow: hidden;height: 100px;width: 35px;display: inline-block;} .iic-input-date .scroll-wrapper{overflow-y: scroll;display: inline-block;height: 100%;} .iic-input-date .time-scroll::before, .iic-input-date .time-scroll::after{content: "";display: block;width: 100%;height: 40px;} .iic-input-date .bottom{height: 30px;border-top: 1px solid #e4e4e4;padding: 4px;text-align: right;box-sizing: border-box;position: relative;} .iic-input-date .bottom > button{border: 1px solid #dcdfe6;cursor: pointer;background-color: #fff;border-radius: 3px;font-size: 12px;} .iic-input-date .time-zone .time-scroll{width: 35px;display: inline-block;overflow: hidden;} .iic-input-date .time-scroll > li{height: 20px;cursor: pointer;color: #606266;font-size: 12px; line-height: 20px;} .iic-input-date .time-scroll .active{color: #409eff;} .iic-input-date .time-scroll >li:hover{background-color: #f5f7fa;} .fadeDownBig-enter-active, .fadeDownBig-leave-active, .fadeInDownBig { -webkit-animation-duration: 0.5s; animation-duration: 0.5s; -webkit-animation-fill-mode: both; animation-fill-mode: both;} .fadeDownBig-enter-active {-webkit-animation-name: fadeInDownBig; animation-name: fadeInDownBig;} .fadeDownBig-leave-active {-webkit-animation-name: fadeOutDownBig; animation-name: fadeOutDownBig;} @-webkit-keyframes fadeInDownBig {from {opacity: 0.8;-webkit-transform: translate3d(0, -4px, 0);transform: translate3d(0, -4px, 0);}to {opacity: 1;-webkit-transform: none;transform: none;} } @keyframes fadeInDownBig {from {opacity: 0.8;-webkit-transform: translate3d(0, -4px, 0);transform: translate3d(0, -4px, 0);}to {opacity: 1;-webkit-transform: none;transform: none;} } @-webkit-keyframes fadeOutDownBig {from {opacity: 1;}to {opacity: 0.8;-webkit-transform: translate3d(0, -4px, 0);transform: translate3d(0, -4px, 0);} } @keyframes fadeOutDownBig {from {opacity: 1;}to {opacity: 0;} } </style>效果圖:
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的vue实现时间选择器,精确到秒的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux通过命令行本地目录取消svn关
- 下一篇: vue实现表格组件,带分页