class="picker-button iconfont icon-prev-year"
@click="onChangeYear('prev')"
/>
class="picker-button iconfont icon-prev-month"
@click="onChangeMonth('prev')"
/>
>{{showDate.year }}年{{showDate.month + 1 }}月
>
class="picker-button iconfont icon-next-month"
@click="onChangeMonth('next')"
/>
class="picker-button iconfont icon-next-year"
@click="onChangeYear('next')"
/>
v-for="week in ['日','一','二','三','四','五','六']"
:key="week"
>
{{week }}
v-for="date in showDay"
:key="date.getTime()"
:class="{
'other-month': !isCur(date).month,
'is-selected':isCur(date).select,
'is-today':isCur(date).today,
}"
@click="onChooseDate(date)"
>
{{date.getDate() }}
export default {
model: {
prop:"date",
event:"choose-date",
},
directives: {
"click-outside": {
bind(el, binding, vnode) {
const vm = vnode.context;
// 某个区域点击 专门用指令
document.onclick =function (e) {
const dom = e.target;
// console.log(dom)
const isElSon = el.contains(dom);
// console.log(isElSon)
if (isElSon && !vm.showPanel) {
vm.changePanel(true);
}else if (!isElSon &&vm.showPanel) {
vm.changePanel(false);
}
// 重点:整个picker的div是块级元素,点击并排的空白区域,也属于picker,所以改成inline-block
// 另外,因为上面的input宽度不够(也没有设置宽度,由内容撑开的),可以看到父元素的背景色(pink),将panel设置成绝对定位脱离文档流,
//那么父元素就只会罩在input上面了,大功告成
};
},
},
},
props: {
date: {
type:Date,
default: () =>new Date(),
},
},
computed: {
chooseDate() {
const {year,month,day } =this.getYearMonthDay(this.date);
return `${year}-${month +1}-${day}`;
},
showDay() {
const {year,month } =this.showDate;
// console.log(year, month);
const firstDay =new Date(year,month,1);// 重点。获取某年某个月的第一天,+之前可以打印出星期
const week =firstDay.getDay();// 获取星期
const startDay =firstDay -week *24 *60 *60 *1000;// 其实就是标记初始位。开始时间不能是1号
// console.log(firstDay, startDay, week);
//console.log(year,month)
const arr = [];
for (let i =0;i <42;i++) {
arr.push(new Date(startDay +i *24 *60 *60 *1000));
}
return arr;
},
},
data() {
return {
showPanel:false,
showDate: {
year:0,
month:0,
day:0,
},
};
},
methods: {
getYearMonthDay(date) {
const year = date.getFullYear();
const month = date.getMonth();
const day = date.getDate();
return {
year,
month,
day,
};
},
changePanel(flag) {
this.showPanel = flag;
},
getShowDate(date) {
const {year,month,day } =this.getYearMonthDay(date);
this.showDate = {
year,
month,
day,
};
},
isCur(date) {
const chooseDate =new Date(this.chooseDate);
const {year:showYear,month:showMonth } =this.showDate;
const {
year:chooseYear,
month:chooseMonth,
day:chooseDay,
} =this.getYearMonthDay(chooseDate);
const {
year:curYear,
month:curMonth,
day:curDay,
} =this.getYearMonthDay(new Date());
const {year,month,day } =this.getYearMonthDay(date);
return {
month:year ===showYear &&month ===showMonth,
select:
year ===chooseYear &&month ===chooseMonth &&day ===chooseDay,
today:year ===curYear &&month ===curMonth &&day ===curDay,
};
},
onChooseDate(date) {
this.$emit("choose-date", date);
this.changePanel(false);
this.getShowDate(date);
},
onChangeMonth(type) {
const moveMonth = type ==="prev" ? -1 :1;
const {year,month,day } =this.showDate;
const showDate =new Date(year,month,day);
showDate.setMonth(month +moveMonth);
const {year:showYear,month:showMonth } =this.getYearMonthDay(
showDate
);
this.showDate.year =showYear;
this.showDate.month =showMonth;
// const maxMonth = 11;
// const minMonth = 0;
// let { year, month } = this.showDate;
// month += moveMonth;
// if (month < minMonth) {
// month = maxMonth;
// year--;
// }else if(month>maxMonth){
// month=minMonth
// year++
// }
// this.showDate.year = year;
// this.showDate.month = month;
},
onChangeYear(type) {
const moveYear = type ==="prev" ? -1 :1;
this.showDate.year +=moveYear;
},
},
created() {
//console.log(this.date);
this.getShowDate(this.date);
},
};
@import "./assets/font.css";
.date-picker {
display:inline-block;
background-color:pink;
}
.picker-input {
position:relative;
}
.picker-input input {
height:40px;
line-height:40px;
padding:0 30px;
border:1px solid #dcdfe6;
border-radius:4px;
outline:none;
cursor:pointer;
}
.picker-input .input-prefix {
position:absolute;
left:5px;
top:50%;
transform:translateY(-50%);
width:25px;
text-align:center;
background-color:#fff;
color:#c0c4cc;
/* background-color: red; */
}
.picker-panel {
position:absolute;
width:322px;
height:329px;
margin-top:5px;
border:1px solid #e4e7ed;
border-radius:4px;
box-shadow:0 2px 12px 0 rgba(0,0,0,0.1);
background-color:#fff;
}
.picker-panel .picker-arrow {
position:absolute;
left:30px;
top: -12px;
/* bottom: 100%; */
width:0;
height:0;
border:6px solid transparent;
border-bottom-color:#ebeef5;
/* border: 6px solid transparent; */
/* border-top-color: red; */
/* border-bottom-color: #fff; */
/* border-left-color: violet;
border-right-color: turquoise; */
}
.picker-panel .picker-arrow::after {
position:absolute;
left: -6px;
top: -5px;
content:"";
display:block;
width:0;
height:0;
border:6px solid transparent;
border-bottom-color:#fff;
}
.picker-panel .picker-header {
display:flex;
align-items:center;
justify-content:center;
padding:15px 0 15px 0;
}
.picker-panel .picker-button {
margin:0 5px;
font-size:14px;
cursor:pointer;
}
.picker-panel .picker-date {
margin:0 60px;
user-select:none;
}
.picker-panel .picker-content {
padding:0 10px 10px 10px;
color:#606266;
user-select:none;
}
.picker-panel .picker-weeks {
display:flex;
justify-content:space-around;
align-items:center;
height:40px;
/* line-height: 40px; */
border-bottom:1px solid #ebeef5;
}
.picker-panel .picker-days {
display:flex;
justify-content:space-around;
flex-wrap:wrap;
}
.picker-panel .picker-days div {
width:30px;
height:30px;
line-height:30px;
margin:4px 6px;
font-size:12px;
cursor:pointer;
text-align:center;
}
.picker-panel .picker-days div:hover {
color:#409eff;
}
.picker-panel .picker-days div.is-today {
color:#409eff;
font-weight:700;
}
.picker-panel .picker-days div.is-selected {
border-radius:50%;
background-color:#409eff;
color:#fff;
}
.picker-panel .picker-days div.other-month {
color:#c0c4cc;
}
网友评论