适用于vue、uniapp、微信小程序的日历插件(代码片段)
原文链接:日历插件
插件说明:
适用于vue、uniapp。可运行再pc、手机浏览器、手机微信浏览器、手机app。
最近公司开发约课系统,要求日历上能展示还剩多少人可预约。我想着百度一搜一大把啊,于是我找了一上午没找到合适的,于是我结合百度的和自己的需求写了一个。
效果:
样式啥的,完全可控,还能增加状态
开始:
html:
<div class="calendar">
<div class='tit flex_c_c'>
<div class='pre flex_c_c' @click='gotoPreMonth()'> < </div>
<div class='current flex_c_c'>{{currentYear}}年{{currentMonth}}月</div>
<div class='next flex_c_c' @click='gotoNextMonth()'> > </div>
</div>
<div class='content1'>
<div class="head">
<div class="list">日</div>
<div class="list">一</div>
<div class="list">二</div>
<div class="list">三</div>
<div class="list">四</div>
<div class="list">五</div>
<div class="list">六</div>
</div>
<div class="list" v-for="(item,index) in allArr" :key="index">
<div
v-if="item.state==1"
class="box succese"
>
<div>{{item.date}}</div>
<div class="t24">剩{{item.num}}人</div>
</div>
<div
v-else-if="item.num>0"
:class="'box have ' + (clickDate==item.date?'clickDate':'')"
@click="rlChange(item.date)"
>
<div>{{item.date}}</div>
<div class="t24">剩{{item.num}}人</div>
</div>
<div
v-else-if="item.num==0"
class="box nothing"
>
<div>{{item.date}}</div>
<div class="t24">剩{{item.num}}人</div>
</div>
<div
v-else
class="box gray"
>
<div>{{item.date}}</div>
</div>
</div>
</div>
</div>
html根据需求还需要修改,后面细说怎么根据需求修改
css:
// 日历less写法
.calendar{
width: 100%;
background: #fff;
border-radius: 8rpx;
box-shadow: 0 0 2px rgb(0 0 0 / 10%);
.tit{
font-size: 34rpx;
color: #2A2A2A;
padding: 25rpx 0;
border-bottom: 1px solid #c8c7cc;
.current{
margin: 0 25rpx;
line-height: 1;
}
.next{
line-height: 1;
}
.pre{
line-height: 1;
transform:rotate(180deg);
-ms-transform:rotate(180deg); /* IE 9 */
-moz-transform:rotate(180deg); /* Firefox */
-webkit-transform:rotate(180deg); /* Safari 和 Chrome */
-o-transform:rotate(180deg); /* Opera */
}
}
.content1{
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
.head{
width: 100%;
display: flex;
flex-wrap: wrap;
border-bottom: 1px solid #F5F5F5;
.list{
background: #fff;
}
}
.list{
width: calc(14.285% - 4px);
background: #f6f6f6;
height: 80rpx;
line-height: 1.2;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
flex-shrink: 0;
font-size: 32rpx;
/* background: rgb(224, 199, 199); */
margin: 2px;
.box{
font-size: 28rpx;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.have{
background: #fff;
}
.succese{
background: #0acf63;
}
.nothing{
opacity: 0.6;
}
.t24{
color: #f67a47;
}
.clickDate{
background: #007aff;
color: #fff;
}
}
.gray{
color: rgba(0,0,0,0.4);
}
}
}
先上一段不需要修改的js吧,这段代码我是用mixin导入到页面,当然也可以写成组件,这里我只讨论方法
const calendar = {
data () {
return {
clickDate: '',
currentYear: '',
currentMonth: '',
currentMonthDateLen: 0, // 当月天数
preMonthDateLen: 0, // 当月中,上月多余天数
allArr:[], // 当月所有数据
}
},
onShow() {
var date = new Date();
this.currentYear = date .getFullYear();
this.currentMonth = date .getMonth()+1;
},
methods: {
// 获取某年某月总共多少天
getDateLen(year, month) {
let actualMonth = month - 1;
let timeDistance = +new Date(year, month) - +new Date(year, actualMonth);
return timeDistance / (1000 * 60 * 60 * 24);
},
// 获取某月1号是周几
getFirstDateWeek(year, month) {
return new Date(year, month - 1, 1).getDay()
},
// 上月 年、月
preMonth(year, month) {
if (month == 1) {
return {
year: --year,
month: 12
}
} else {
return {
year: year,
month: --month
}
}
},
// 下月 年、月
nextMonth(year, month) {
if (month == 12) {
return {
year: ++year,
month: 1
}
} else {
return {
year: year,
month: ++month
}
}
},
// 获取当月中,上月多余数据,返回数组
getPreArr(){
let preMonthDateLen = this.getFirstDateWeek(this.currentYear, this.currentMonth) // 当月1号是周几 == 上月残余天数)
let preMonthDateArr = [] // 定义空数组
if (preMonthDateLen > 0) {
let { year, month } = this.preMonth(this.currentYear, this.currentMonth) // 获取上月 年、月
let date = this.getDateLen(year, month) // 获取上月天数
for (let i = 0; i < preMonthDateLen; i++) {
preMonthDateArr.unshift({ // 尾部追加
month: 'pre', // 只是为了增加标识,区分当、下月
date: date
})
date--
}
}
this.preMonthDateLen=preMonthDateLen
return preMonthDateArr
},
// 获取当月中,下月多余数据,返回数组
getNextArr() {
let nextMonthDateLen = 42 - this.preMonthDateLen - this.currentMonthDateLen // 下月多余天数
let nextMonthDateArr = [] // 定义空数组
if (nextMonthDateLen > 0) {
for (let i = 1; i <= nextMonthDateLen; i++) {
nextMonthDateArr.push({
month: 'next',// 只是为了增加标识,区分当、上月
date: i
})
}
}
return nextMonthDateArr
},
// 整合当月所有数据
getAllArr(currentMonthDateArr){
let preArr = this.getPreArr()
let currentArr = currentMonthDateArr
let nextArr = this.getNextArr()
let allArr = [...preArr, ...currentArr, ...nextArr]
this.allArr=allArr
},
// 点击 上月
gotoPreMonth(){
this.clickDate = ''
let { year, month } = this.preMonth(this.currentYear, this.currentMonth)
this.currentYear= year,
this.currentMonth= month
this.getCurrentArr()
},
// 点击 下月
gotoNextMonth() {
this.clickDate = ''
let { year, month } = this.nextMonth(this.currentYear, this.currentMonth)
this.currentYear= year
this.currentMonth= month
this.getCurrentArr()
},
},
}
export default calendar;
好了,接下来就是正题了
// 获取当月数据,返回数组
getCurrentArr(){
//发起ajax请求
this.$axios.post(
'/api/xxxxxxxxxx'
).then((response)=>{
//获取到这样的一个月的数据
//date:日期,state:日期状态(预约成功、是否可预约等状态),num:剩余数量(根据需求更改)。字段和字段个数可自定义、新增、修改,如有改动字段,HTML需要跟着修改相应字段
// let data = [
// {date:'2021-12-5', state:0, num: 4},
// {date:'2021-12-8', state:1, num: 4},
// {date:'2021-12-9', state:0, num: 0},
// {date:'2021-12-10', state:0, num: 10},
// {date:'2021-12-11', state:0, num: 10},
// {date:'2021-12-26', state:0, num: 0},
// {date:'2021-12-27', state:0, num: 5},
// ]
})
let currentMonthDateLen = this.getDateLen(this.currentYear, this.currentMonth) // 获取当月天数
//由于后端传来的日期是断断续续的,我们需要当月不间断的数据,所以没办法自己重新循环整合数据,如果后端传的是连续一个月的就不需要整合了
let currentMonthDateArr = [] // 定义空数组
if (currentMonthDateLen > 0) {
for (let i = 1; i <= currentMonthDateLen; i++) {
currentMonthDateArr.push({
month: 'current', // 只是为了增加标识,区分上下月
date: i,
state: null,
num: null
})
for (let a = 0; a < data.length; a++) {
const element = data[a];
if(this.currentYear+'-'+this.currentMonth+'-'+i == data[a].date){
currentMonthDateArr[i-1].state = data[a].state
currentMonthDateArr[i-1].num = data[a].num
continue
}
}
}
}
//如果是连续一个月的数据到这里之上的都可以不需要
this.currentMonthDateLen=currentMonthDateLen
//参数说明:后端传来的连续数据或自己整合的连续数据
this.getAllArr(currentMonthDateArr)
},
到这里,就结束了js
下面我们再来看看html(文章前面能复制,这里只是说明)
根据需求修改
最后,这套代码已经满足我现在的需求了,当然还有很多地方需要完善,欢迎评论区留言,希望能帮助一部分码农