【uniapp3】分享一个自己写的h5日历组件
<template>
<view class="calendar">
<view class="wrapper">
<slot
name="top"
:nowMonthText="nowMonthText"
:pickerMonth="pickerMonth"
:prevMonth="prevMonth"
:nextMonth="nextMonth"
>
<view class="top">
<view class="month-box">
<view class="month-text">
<view class="uni-input" @tap="pickerMonth">{{
nowMonthText
}}</view>
</view>
<view class="back-today" @tap="goToday">回到今天</view>
</view>
<view class="top-left">
<view class="icon-arrow arrow-left" @tap="previousFn"></view>
<view class="icon-arrow arrow-right" @tap="nextFn"></view>
</view>
</view>
</slot>
<view class="calender-box">
<view class="head-title">
<view
class="head-title-item"
v-for="v in calenderTitleList"
:key="v"
>{{ v }}</view
>
</view>
<!-- 一行显示 -->
<swiper
v-if="showType === 1"
class="row-swiper"
circular
:disable-programmatic-animation="true"
:duration="duration"
:current="swiperCurrent"
@change="swipereChangFn"
>
<swiper-item
v-for="(v, index) in calenderRowDaysList"
:key="index"
:item-id="v.label"
>
<view class="row-days-list">
<view
class="days-list-item"
v-for="(item, i) in v.value"
:key="`${index}-${i}`"
:class="{
used: item.used,
}"
>
<view
class="label"
v-if="(isNowMonth && item.isNowMonth) || !isNowMonth"
:class="{
disabled: item.disabled,
}"
@tap="clickDay(item)"
>
<view
class="text"
:class="{
'active-item':
nowSelectDay && nowSelectDay['time'] === item.time,
'active-item--disabled':
nowSelectDay &&
nowSelectDay['time'] === item.time &&
item.disabled,
'today-text':
item.label === '今' &&
nowSelectDay &&
nowSelectDay['time'] !== item.time &&
!item.disabled,
}"
>
{{ item.label }}
</view>
<view
v-show="!item.disabled && item.state"
class="state-item text-state-item"
>
</view>
<view
class="item-adjust"
v-if="!item.disabled && item.adjust && item.adjust.value"
:class="{ 'text-state-leave': item.adjust.value == '1' }"
>
{{ item.adjust.value == "1" ? "休" : "课" }}
</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
<!-- 全行显示 -->
<swiper
v-else
class="all-swiper"
circular
:disable-programmatic-animation="true"
:duration="duration"
@change="swipereChangFn"
:current="swiperCurrent"
:class="{
'six-height':
swiperDaysList[0] && swiperDaysList[0].value.length / 7 === 6,
}"
>
<swiper-item
v-for="(v, index) in swiperDaysList"
:key="index"
:item-id="v.label"
>
<view class="days-list">
<view
class="days-list-item"
v-for="(item, i) in v.value"
:key="`${index}-${i}`"
:class="{
used: item.used,
}"
>
<view
class="label"
v-if="(isNowMonth && item.isNowMonth) || !isNowMonth"
:class="{
disabled: item.disabled,
}"
@tap="clickDay(item)"
>
<view
class="text"
:class="{
'active-item':
nowSelectDay && nowSelectDay['time'] === item.time,
'active-item--disabled':
nowSelectDay &&
nowSelectDay['time'] === item.time &&
item.disabled,
'today-text':
item.label === '今' &&
nowSelectDay &&
nowSelectDay['time'] !== item.time &&
!item.disabled,
}"
>
{{ item.label }}
</view>
<view
v-show="!item.disabled && item.state"
class="state-item"
></view>
<view
class="item-adjust"
v-if="!item.disabled && item.adjust && item.adjust.value"
:class="{ 'text-state-leave': item.adjust.value == '1' }"
>
{{ item.adjust.value == "1" ? "休" : "课" }}
</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
<view v-if="!hideArrow" class="arrow-wrapper" @click="showTypeChange">
<view
class="arrow-left"
:class="{ 'arrow-left--up': showType === 0 }"
></view>
<view
class="arrow-right"
:class="{ 'arrow-right--up': showType === 0 }"
></view>
</view>
</view>
<view class="content">
<slot :value="nowSelectDay"></slot>
</view>
</view>
<!-- 选择月份 -->
<uni-popup ref="monthPopup" :type="'bottom'">
<view class="month-popup-box">
<view class="month-top">
<view class="cancel-text" @tap="cancelDateFn">取消</view>
<view class="ok-text" @tap="sucessDate">完成</view>
</view>
<picker-view
:value="selectValue"
@change="bindChange"
class="picker-view"
>
<picker-view-column>
<view class="item" v-for="(item, index) in years" :key="index"
>{{ item }}年</view
>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item, index) in months" :key="index"
>{{ item }}月</view
>
</picker-view-column>
</picker-view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
props: {
isNowMonth: {
// 是否只显示当前月日历值
type: Boolean,
default: false,
},
limitNowMoth: {
// 限制只有当月
type: Boolean,
default: false,
},
showRowType: {
type: Boolean,
default: true,
},
dateStateList: {
// 日历中的状态 [{date:'2023/12/1',value:1}]
type: Array,
default: () => [],
},
dateAdjustList: {
// 日历中的调课状态 [{date:'2023/12/1',value:1}] 1为休,2为调课
type: Array,
default: () => [],
},
defaultValue: {
type: String,
default: "",
},
hideArrow: {
type: Boolean,
default: false,
},
},
emits: ["ok", "cancel", "changeMonth"],
data() {
const date = new Date();
const years = [];
const year = date.getFullYear();
const months = [];
const month = date.getMonth() + 1;
const day = date.getDate();
for (let i = 1990; i <= date.getFullYear() + 30; i++) {
years.push(i);
}
for (let i = 1; i <= 12; i++) {
months.push(i);
}
return {
monthValue: [years.findIndex((item) => item === year), month - 1], // 选择月份值
years,
year, //当前年
months,
month, // 当前月
day, // 当前日
selectValue: [], // 月份选择器选中的值
// 日历
calenderTitleList: ["一", "二", "三", "四", "五", "六", "日"],
swiperDaysList: [], // swiper全行显示列表 0-当月 1-下月 2-上月
swiperCurrent: 0, // swiper当前显示索引
duration: 500, // 动画时长
calenderRowDaysList: [], // rowSwiper行显示列表
nowSelectDay: null, // 当前选中值
showType: 0, // 0 全部行显示 1,1行显示
isJust: false, // 是否是校准
};
},
computed: {
nowMonthText() {
const [yearIndex, monthIndex] = this.monthValue;
let str = `${
this.years[yearIndex]
? this.years[yearIndex]
: this.years[this.years.length - 1]
}年${this.months[monthIndex]}月`;
this.$emit("changeMonth", [
this.years[yearIndex],
this.months[monthIndex].toString().padStart(2, "0"),
]);
return str;
},
},
watch: {
showRowType: {
handler(val) {
if (val) {
this.showType = 1;
} else {
this.showType = 0;
}
},
immediate: true,
},
defaultValue(val) {
if (val && val !== "") {
this.nowSelectDay = {
time: Date.parse(val),
};
}
},
},
mounted() {
this.updateCalender();
},
methods: {
showTypeChange() {
this.showType = 1 - this.showType;
// this.goToday();
this.updateCalender(false);
this.initCurrent();
},
// 点击天数
clickDay(item) {
if (item.disabled) return;
this.nowSelectDay = item;
this.$emit("ok", this.nowSelectDay);
},
pickerMonth() {
if (this.limitNowMoth) return