<template>
<div class="data-picker" v-show-date-pannel>
<input type="text" :value="formatDate" />
<div class="pannel" v-if="pannelVisible">
<div class="pannel-header">
<span @click="preYear"><<</span>
<span @click="preMonth"><</span>
<span
>{{ time.year }}年{{
(time.month + 1).toString().padStart(2, "0")
}}月</span
>
<span @click="nextMonth">></span>
<span @click="nextYear">>></span>
</div>
<div class="pannel-content">
<div>
<span>日</span>
<span>一</span>
<span>二</span>
<span>三</span>
<span>四</span>
<span>五</span>
<span>六</span>
</div>
<div v-for="i in 6" :key="i">
<span
v-for="j in 7"
:class="{
notCurrentMonth: !isCurrentMonth(
currentDateList[(i - 1) * 7 + (j - 1)]
),
isSelected: isSelected(currentDateList[(i - 1) * 7 + (j - 1)]),
today: isTody(currentDateList[(i - 1) * 7 + (j - 1)]),
}"
:key="j"
@click="setDay(currentDateList[(i - 1) * 7 + (j - 1)])"
>{{ currentDateList[(i - 1) * 7 + (j - 1)].getDate() }}</span
>
</div>
</div>
</div>
</div>
</template>
<script>
const getYearMonthDay = function (val) {
const year = new Date(val).getFullYear();
const month = new Date(val).getMonth();
const day = new Date(val).getDate();
return {
year,
month,
day,
};
};
export default {
props: ["value"],
data() {
const { year, month, day } = getYearMonthDay(this.value);
return {
pannelVisible: false,
time: { year, month },
};
},
computed: {
formatDate() {
const { year, month, day } = getYearMonthDay(this.value);
const m = (month+1).toString().padStart(2, "0");
return `${year}-${m}-${day}`;
},
// 需要循环的数据
currentDateList() {
const { year, month } = this.time;
// 求出当月第一天的时间 ---> 格林威治时间
const firstMonthDay = new Date(year, month, 1);
// 求出第一天是星期几
const firstMonthWeek = firstMonthDay.getDay();
// 求出42天中的第一天
const currenFirstDay =
firstMonthDay - firstMonthWeek * 24 * 60 * 60 * 1000;
// 循环42天加入数组
const dateArr = [];
for (let index = 0; index < 42; index++) {
const day = new Date(currenFirstDay + index * 24 * 60 * 60 * 1000);
dateArr.push(day);
}
return dateArr;
},
// 是否是当月
isCurrentMonth() {
return function (date) {
const { year, month } = getYearMonthDay(date);
// const { year: y, month: m } = getYearMonthDay(new Date());
const { year: y, month: m } = this.time;
return year === y && month === m;
};
},
// 是否是选中的那一天
isSelected() {
return function (date) {
const { year, month, day } = getYearMonthDay(date);
const { year: y, month: m, day: d } = getYearMonthDay(this.value);
return year === y && month === m && day === d;
};
},
// 是否是当天
isTody() {
return function (date) {
const { year, month, day } = getYearMonthDay(date);
const { year: y, month: m, day: d } = getYearMonthDay(new Date());
return year === y && month === m && day === d;
};
},
},
methods: {
showPannel() {
this.pannelVisible = true;
},
hidePannel() {
this.pannelVisible = false;
},
// 上一年
preYear() {
const date = new Date(this.time.year, this.time.month, 1);
this.time = getYearMonthDay(date.setFullYear(this.time.year - 1));
},
// 上一个月
preMonth() {
const date = new Date(this.time.year, this.time.month, 1);
this.time = getYearMonthDay(date.setMonth(this.time.month - 1));
},
// 下一年
nextYear() {
const date = new Date(this.time.year, this.time.month, 1);
this.time = getYearMonthDay(date.setFullYear(this.time.year + 1));
},
// 下一个月
nextMonth() {
const date = new Date(this.time.year, this.time.month, 1);
this.time = getYearMonthDay(date.setMonth(this.time.month + 1));
},
// 设置值
setDay(val) {
const { year, month, day } = getYearMonthDay(val);
this.$emit("input", val);
this.pannelVisible = false;
},
},
directives: {
showDatePannel: {
bind(el, binding, vnode) {
function handler(e) {
if (el.contains(e.target)) {
!vnode.context.pannelVisible && vnode.context.showPannel();
} else {
vnode.context.pannelVisible && vnode.context.hidePannel();
}
}
el.handler = handler;
document.addEventListener("click", el.handler);
},
unbind(el, binding, vnode) {
document.removeEventListener("click", el.handler);
},
},
},
};
</script>
<style lang="less" scoped>
@import "~@/styles/var.less";
.data-picker {
width: 210px;
.pannel .pannel-header {
display: flex;
justify-content: space-around;
span {
cursor: pointer;
box-sizing: border-box;
}
}
.pannel .pannel-content div {
display: flex;
span {
flex: 1;
text-align: center;
border-radius: 50%;
cursor: pointer;
box-sizing: border-box;
}
.notCurrentMonth {
color: @gray;
}
.isSelected {
color: #fff;
background-color: @primary;
}
.today {
color: @primary;
}
}
}
</style>
vue写一个日期选择器组件
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- Date Pickers Vue构建的日期选择组件,喜欢的话希望能点一下star 项目描述 一个简单的时间选择器,...
- "TypeError: Cannot read property '0' of null"this.dateRan...
- 今天青石的票圈出镜率最高的,莫过于张艺谋的新片终于定档了。 一张满溢着水墨风的海报一次次的出现在票圈里,也就是老谋...