vue移动端日历显示查看每日详情列表
效果图
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0808e91e7607290914f2869a8ae13d93.png)
#
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/484495ac295b4a1df78c0f86b51969a9.png)
使用cmd命令
npm install v-calendar
package.json和package-lock.json配置信息如下
在页面中引入并注册组件
import { setupCalendar, DatePicker } from "v-calendar";
import { mapGetters, mapActions } from "vuex";
setupCalendar(Vue, {
locale: "zh-CN"
});
components: {
// "v-calendar": VCalendar
"v-date-picker": DatePicker
},
现在就可以使用该组件了,页面代码如下
正常情况下,如果只是普通的日历展示,没有要查询某个日期的某些内容的需求,以下代码就可以满足
<v-date-picker
class="calendar"
v-model="selectedDate"
:disabled-dates="{ start: new Date().getTime() + 8*24*60*60*1000, end: null }"
:attributes="attrs"
is-expanded
is-inline
is-required
@update:fromPage="updatePage"
>
</v-date-picker>
不可以满足的,这里是查询某个日期详情的并在该日期下有标识代码
<template>
<app-container class="appointment-calendar">
<v-date-picker
class="calendar"
v-model="selectedDate"
:disabled-dates="{ start: new Date().getTime() + 8*24*60*60*1000, end: null }"
:attributes="attrs"
is-expanded
is-inline
is-required
@update:fromPage="updatePage"
>
<template v-slot:day-content="{day, dayEvents, attributes, attributesMap}">
<div
@click="chooseDay(day, dayEvents, attributes, attributesMap)"
class="customer-day vc-day-content vc-rounded-full"
:class="[{'is-today': day.isToday}, {'select-day': day.dateTime == selectedDate}]"
>
<span class="label">{{day.label}}</span>
<span
class="count"
v-if="attributesMap && attributesMap['count'].customData[day.dateTime]"
>{{attributesMap['count'].customData[day.dateTime]}}</span>
<span class="dot" v-if="attributesMap && attributesMap['count']"></span>
</div>
</template>
</v-date-picker>
<div class="main">
<div class="main-time">
<div>
<p>上午</p>
<button @click="addScheduling(1)" v-show="isScheduling">添加排班</button>
</div>
<div style="height:auto;" v-if="workAmList.length!==0">
<p
class="workTime fl"
v-for="item in workAmList"
:key="item.workHeaderId"
@click="schedulingInfo(item.workHeaderId)"
>
{{item.workStartTime}}~{{item.workEndTime}}
<img
@click.stop="deleteworkHeader(item.workHeaderId)"
src="../../assets/images/common/delete.png"
alt
/>
</p>
</div>
<div>
<p>下午</p>
<button @click="addScheduling(2)" v-show="isScheduling">添加排班</button>
</div>
<div style="height:auto;" v-if="workPmList.length!==0">
<p
class="workTime fl"
v-for="item in workPmList"
:key="item.workHeaderId"
@click="schedulingInfo(item.workHeaderId)"
>
{{item.workStartTime}}~{{item.workEndTime}}
<img
@click.stop="deleteworkHeader(item.workHeaderId)"
src="../../assets/images/common/delete.png"
alt
/>
</p>
</div>
</div>
</div>
</app-container>
</template>
样式文件: 这里我们用的是cass ,使用了两个样式文件
<style lang="scss" rel="stylesheet/scss">
.appointment-calendar {
.calendar {
border: none !important;
background-color: #ffffff !important;
border: none;
border: 0.05rem solid rgba(45, 141, 247, 0.07);
.vc-day-content {
font-weight: normal;
}
.vc-weekday {
font-weight: normal;
}
.vc-title {
font-size: 0.8rem;
font-weight: normal;
}
}
}
.main-time {
margin: 1rem 0;
height: 5rem;
border: 0.05rem solid rgba(45, 141, 247, 0.07);
border-bottom: none;
div {
height: 2.5rem;
line-height: 2.5rem;
position: relative;
border-bottom: 0.05rem solid rgba(45, 141, 247, 0.07);
overflow: hidden;
p {
float: left;
margin-left: 1rem;
}
.workTime {
height: 1.5rem;
border-radius: 1rem;
line-height: 1.5rem;
background: #eee;
margin: 0.5rem;
opacity: 0.6;
padding: 0 0.3rem;
position: relative;
img {
position: absolute;
width: 1rem;
height: 1rem;
top: -0.2rem;
}
}
button {
height: 1.5rem;
float: right;
position: absolute;
top: 50%;
margin-top: -0.75rem;
right: 1rem;
background: linear-gradient(
145deg,
rgba(17, 218, 199, 1) 0%,
rgba(45, 141, 247, 1) 100%
);
border-radius: 0.5rem;
border: none;
color: #fff;
}
}
}
</style>
<style scoped lang="scss" rel="stylesheet/scss">
.customer-day {
position: relative;
.label {
/*padding-top: 0.15rem;*/
}
.count {
position: absolute;
top: -3px;
right: -5px;
width: 14px;
height: 14px;
font-size: 10px;
line-height: 1.65;
border-radius: 100%;
background: #ff7d00;
color: #ffffff;
text-align: center;
}
.dot {
position: absolute;
width: 4px;
height: 2px;
background: #ff7d00;
bottom: 0;
}
}
.is-today {
background-color: #eeee !important;
}
.select-day {
background-color: $themeColor !important;
color: #ffffff !important;
}
</style>
data() {
return {
selectedDate: "",
attrs: [],
currentSchedule: {
date: "",
count: 0,
items: []
},
scheduleMonthMap: {},
scheduleDayMap: {},
doctorDetailId: this.$route.query.id, //上一页面传过来的医生id
workAmPm: 0,
workAmList: [], //上午返回的排班列表
workPmList: [], //下午返回的排班列表
isScheduling: false //不可选日期排班按钮是否显示
};
},
watch: {
selectedDate(newVal) {
newVal && this.loadScheduleByDay(newVal);
}
},
这里是methods事件
进入日历或切换月份的触发事件
// 月份更新获取排班情况和预约数量
updatePage(e) {
this.$indicator.open();
this.$api
.workHeaderList({
doctorDetailId: this.doctorDetailId,
monthYear: this.getTimeSlot(e.year, e.month)
})
.then(
data => {
this.$indicator.close();
console.log(data);
this.loadAttrs(data.data || []);
// // selectedDate为空说明是初始化,则把其置为今天, 触发watch加载当天排班情况
if (!this.selectedDate) {
this.selectedDate = new Date().setHours(0, 0, 0, 0);
}
},
err => {
this.$indicator.close();
err.msg && this.$messagebox.alert(err.msg);
}
);
},
getTimeSlot(year, month) {
if (month.length == 1) {
month = "0" + moth;
}
return year + "-" + month;
},
// 更新日历数据
loadAttrs(data) {
let dates = [];
let customData = {};
data.forEach(item => {
dates.push(new Date(item).getTime());
customData[item.date + ""] = item.count;
});
this.attrs = [
{
key: "count",
dates: dates,
customData: customData
}
];
},
chooseDay(day) {
this.selectedDate = day.dateTime;
},
// 加载某一天的排班
loadScheduleByDay(timeStamp) {
this.workAmList = [];
this.workPmList = [];
let dateStr = this.$utils.getDateObj(timeStamp).dateStr.slice(0, 10);
this.$indicator.open();
this.$api
.workHeaderDateList({
doctorDetailId: this.doctorDetailId,
selDate: dateStr
})
.then(
data => {
this.$indicator.close();
data.data.forEach(item => {
let dataEntity = {};
dataEntity.workStartTime = this.$utils.getDateObj(item.workStartTime).dateStr.slice(10, 16); //处理后台数据返回时间格式问题
dataEntity.workEndTime = this.$utils.getDateObj(item.workEndTime).dateStr.slice(10, 16);//处理后台数据返回时间格式问题
dataEntity.workHeaderId = item.workHeaderId;
if (item.workAmPm == 1) {
this.workAmList.push(dataEntity);
} else {
this.workPmList.push(dataEntity);
}
});
console.log(data);
this.scheduleDayMap[dateStr] = data.data || [];
},
err => {
this.$indicator.close();
err.msg && this.$messagebox.alert(err.msg);
}
);
},
因为频繁进入到页面,页面会自动缓存,这里是一个bug所以要在路由守卫中,使用KeepAlive,暂时就到这里了