9 Star 18 Fork 3

Neho / vuejs_time_picker

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
timePicker.vue 12.67 KB
一键复制 编辑 原始数据 按行查看 历史
Neho 提交于 2017-11-13 15:19 . 基于vuejs开发的移动端日历组件
<template>
<div class="timepicker" v-if="show">
<div class="timepicker-box">
<div class="box-header">
<div class="header-year">
<span>{{activeDay.year}}</span>
</div>
<div class="header-month-date">
<span class="month">{{activeDay.month}}</span>
<span class="day">{{activeDay.day}}</span>
<span>{{activeDay.week}}</span>
</div>
</div>
<div class="box-section">
<div class="section-slider">
<div class="slider-year-month">
<span class="year">{{queryYear}}</span>
<span class="month">{{queryMonth}}</span>
<i class="iconfont pre" @click="getPreMonthDayList">&#xe63a;</i>
<i class="iconfont next" @click="getNextMonthDayList">&#xe663;</i>
</div>
<div class="slider-week">
<span class="week-item" :key="key" v-for="(item, key) in weekList">{{item.name}}</span>
</div>
<div class="slider-day">
<div class="day-item"
:class="{'day-item-current': item._d.getDate() === activeDay.day && item._d.getMonth() + 1 === activeDay.month && item._d.getFullYear() === activeDay.year,'not-current-month':!item.current}"
:key="key" v-for="(item, key) in activeDayList"
@click="item.current ? drawCalendar(item._d) : ''">
<span>{{item._d.getDate()}}</span>
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="footer-btn">
<span @click="handlerCancel">取消</span>
</div>
<div class="footer-btn">
<span @click="handlerComfirm">确认</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "timepicker",
data() {
return {
/*
* 星期数组
* */
weekList: [
{
name: ""
},
{
name: ""
},
{
name: ""
},
{
name: ""
},
{
name: ""
},
{
name: ""
},
{
name: ""
}
],
/*
* 正在渲染的日历
* */
activeDayList: [],
/*
* 选取的日期
* */
activeDay: new Object(),
/*
* 相对正在选取的日期的月前进数
* */
step: 0,
queryYear: null,
queryMonth: null
};
},
computed: {},
props: {
show: {
type: Boolean,
required: true
}
},
methods: {
/*
* 计算一个月的天数
* */
calDayGenerator(year, month) {
const actualMonth = month - 1;
const timeDistance =
+new Date(year, month) - +new Date(year, actualMonth);
return timeDistance / (1000 * 60 * 60 * 24);
},
/*
* 计算某年某某日星期几
* */
calWeekGenerator(year, month, day) {
const actualMonth = month - 1;
let date = new Date();
date.setFullYear(year);
date.setMonth(actualMonth);
date.setDate(day);
return date.getDay();
},
/*
* 生成某年月天数日期对象数组
* */
dayListGenerator(year, month) {
const dayNum = this.calDayGenerator(year, month);
const actualMonth = month - 1;
let dayList = new Array();
for (let i = 1; i < dayNum + 1; i++) {
let currentDay = {
_d: new Date(year, actualMonth, i),
current: true
};
dayList.push(currentDay);
}
return dayList;
},
/*
* 生成某年月缺少前一个月的时间对象数组
* */
preDayListGenerator(year, month) {
let preDayNum, preSurplusDayNum, actualPreMonth;
if (month === 1) {
preDayNum = this.calDayGenerator(year - 1, 12);
preSurplusDayNum = this.calWeekGenerator(year, month, 1);
actualPreMonth = month - 2;
} else {
preDayNum = this.calDayGenerator(year, month - 1);
preSurplusDayNum = this.calWeekGenerator(year, month, 1);
actualPreMonth = month - 2;
}
let preDayList = new Array();
for (let i = 1; i < preDayNum + 1; i++) {
let currentDay = {
_d: new Date(year, actualPreMonth, i),
current: false
};
preDayList.push(currentDay);
}
return preSurplusDayNum === 0 ? [] : preDayList.slice(-preSurplusDayNum);
},
/*
* 生成某年月应该添加后一个月的时间对象数组
* */
nextDayListGenerator(year, month) {
const preSurplusDayNum = this.calWeekGenerator(year, month, 1);
const dayNum = this.calDayGenerator(year, month);
const NextDayNum = this.calDayGenerator(year, month + 1);
const NextSurplusDayNum = 7 * 6 - (preSurplusDayNum + dayNum);
const actualNextMonth = month;
let nextDayList = new Array();
for (let i = 1; i < NextDayNum + 1; i++) {
let currentDay = {
_d: new Date(year, actualNextMonth, i),
current: false
};
nextDayList.push(currentDay);
}
return nextDayList.slice(0, NextSurplusDayNum);
},
/*
* 将上个月当前月和下个月的时间对象合并
* */
combineDayListGenerator(year, month) {
const pre = this.preDayListGenerator(year, month);
const current = this.dayListGenerator(year, month);
const next = this.nextDayListGenerator(year, month);
const total = pre.concat(current).concat(next);
return total;
},
/*
* 获取前一个月日历
* */
getPreMonthDayList() {
this.activeDayList = [];
this.step = this.step - 1;
let queryYear =
this.activeDay.month + this.step > 0
? this.activeDay.year
: this.activeDay.year -
(parseInt(Math.abs(this.activeDay.month + this.step) / 12) + 1);
let queryMonth =
this.activeDay.month + this.step > 0
? this.activeDay.month + this.step
: 12 - Math.abs(this.activeDay.month + this.step) % 12;
this.queryYear = queryYear;
this.queryMonth = queryMonth;
this.drawDayList(queryYear, queryMonth);
},
/*
* 获取下个月日历
* */
getNextMonthDayList() {
this.activeDayList = [];
this.step = this.step + 1;
let queryYear =
this.activeDay.month + this.step < 13
? this.activeDay.year
: (this.activeDay.month + this.step) % 12 === 0
? this.activeDay.year +
parseInt((this.activeDay.month + this.step) / 12) -
1
: this.activeDay.year +
parseInt((this.activeDay.month + this.step) / 12);
let queryMonth =
this.activeDay.month + this.step < 13
? this.activeDay.month + this.step
: (this.activeDay.month + this.step) % 12 === 0
? 12
: (this.activeDay.month + this.step) % 12;
this.queryYear = queryYear;
this.queryMonth = queryMonth;
this.drawDayList(queryYear, queryMonth);
},
/*
* 绘制日期
* */
drawDayList(year, month) {
this.activeDayList = this.combineDayListGenerator(year, month);
},
/*
* 绘制日历
* */
drawCalendar(d) {
let currentYear = d.getFullYear(),
currentMonth = d.getMonth() + 1,
currentDay = d.getDate(),
currentWeek;
this.step = 0;
switch (d.getDay()) {
case 0:
currentWeek = "周日";
break;
case 1:
currentWeek = "周一";
break;
case 2:
currentWeek = "周二";
break;
case 3:
currentWeek = "周三";
break;
case 4:
currentWeek = "周四";
break;
case 5:
currentWeek = "周五";
break;
case 6:
currentWeek = "周六";
break;
default:
break;
}
this.activeDay = {
_d: d,
year: currentYear,
month: currentMonth,
week: currentWeek,
day: currentDay
};
this.drawDayList(currentYear, currentMonth);
this.$emit("handlerSelect", d);
},
/*
* 用户确认
* */
handlerComfirm() {
this.$emit("handlerComfirm", this.activeDay._d);
this.$emit("update:show", false);
},
/*
* 用户取消
* */
handlerCancel() {
this.$emit("handlerCancel");
this.$emit("update:show", false);
}
},
created() {
this.queryYear = new Date().getFullYear();
this.queryMonth = new Date().getMonth() + 1;
this.drawCalendar(new Date());
}
};
</script>
<style lang="less" scoped>
.timepicker {
position: fixed;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99;
.timepicker-box {
position: absolute;
display: flex;
flex-direction: column;
top: 50%;
left: 50%;
width: 75%;
height: 75%;
transform: translate(-50%, -50%);
background: #fff;
z-index: 100;
.box-header {
box-sizing: border-box;
flex-basis: 22%;
display: flex;
flex-direction: column;
padding: 10px 10px;
background: #5caeff;
.header-year {
flex-basis: 30%;
display: flex;
align-items: center;
overflow-y: hidden;
span {
flex: 1;
font-size: 14px;
color: #fff;
}
}
.header-month-date {
flex-grow: 2;
display: flex;
align-items: center;
overflow-y: hidden;
span {
flex-grow: 0;
font-size: 25px;
color: #fff;
padding: 0px 3px;
}
.month {
&::after {
content: "月";
}
}
.day {
&::after {
content: "日";
}
}
}
}
.box-section {
position: relative;
flex: 1;
.section-slider {
position: absolute;
display: flex;
flex-direction: column;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
padding: 10px 15px;
.slider-year-month {
position: relative;
flex-basis: 10%;
display: flex;
align-items: center;
justify-content: center;
span {
flex: 0;
font-size: 14px;
font-weight: 600;
}
.year {
&::after {
content: "年";
}
}
.month {
&::after {
content: "月";
}
}
i {
font-size: 16px;
}
.pre {
position: absolute;
top: 50%;
left: 0%;
transform: translateY(-50%);
}
.next {
position: absolute;
top: 50%;
right: 0%;
transform: translateY(-50%);
}
}
.slider-week {
flex-basis: 10%;
display: flex;
align-items: center;
.week-item {
flex: 1;
font-size: 14px;
text-align: center;
}
}
.slider-day {
flex: 1;
display: flex;
flex-wrap: wrap;
.day-item {
flex-basis: 14.285%;
display: flex;
align-items: center;
justify-content: center;
span {
flex: 1;
text-align: center;
font-size: 14px;
}
}
.day-item-current {
span {
border-radius: 100%;
color: #fff;
background: #5caeff;
}
}
.not-current-month {
span {
color: gray;
}
}
}
}
}
.box-footer {
flex-basis: 10%;
display: flex;
box-shadow: 0px -1px 0px #eee;
.footer-btn {
flex: 1;
text-align: center;
span {
font-size: 16px;
}
&:not(:last-child) {
box-shadow: 1px 0px 0px #eee;
}
}
}
}
}
</style>
JavaScript
1
https://gitee.com/Daniel_Deng_Haibiao/vuejs_time_picker.git
git@gitee.com:Daniel_Deng_Haibiao/vuejs_time_picker.git
Daniel_Deng_Haibiao
vuejs_time_picker
vuejs_time_picker
master

搜索帮助