123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- <template>
- <view class="calendar">
- <view class="table">
- <view class="chose-head">
- <view class="chose-item">
- <view class="btn" @click="yearsub">
- <image src="../../static/images/arrow_left12.png" mode=""></image>
- </view>
- <view class="year-td">
- <picker mode="selector" :range="years" @change="yearchange" :value="y">
- <view class="text">{{years[y]}}年</view>
- </picker>
- </view>
- <view class="btn" @click="yearadd">
- <image src="../../static/images/arrow_right12.png" mode=""></image>
- </view>
- </view>
-
- <view class="chose-item">
- <view class="btn" @click="monthsub">
- <image src="../../static/images/arrow_left12.png" mode=""></image>
- </view>
- <view class="month-td">
- <picker mode="selector" :range="months" @change="monthchange" :value="m">
- <view class="text">{{months[m]}}月</view>
- </picker>
- </view>
- <view class="btn" @click="monthadd">
- <image src="../../static/images/arrow_right12.png" mode=""></image>
- </view>
- </view>
- </view>
- <view class="week">
- <view class="item">日</view>
- <view class="item">一</view>
- <view class="item">二</view>
- <view class="item">三</view>
- <view class="item">四</view>
- <view class="item">五</view>
- <view class="item">六</view>
- </view>
- <view class="date-tr" v-for="(i,index) in dates" :key="index">
- <view v-for="(j,k) in i" :key="k" :style="{color:j[0]}" :class="j[2]=='#FF5C03'?'td active':'td'" @click="itemChose(j,index,k)">{{j[1]}}</view>
- </view>
- </view>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- year: 2022,
- month: 12,
- date: 19,
- /* 年月是当天的日期,日是这个月日历的第一天,
- 其实就是上个月的最后一个周日,这里是随便定义的,
- 后面在mounted里面根据当前日期赋值 */
- years: [], //存放1900到2100共200年
- months: [], //存放1到12月
- y: 0,
- m: 0, //picker的迭代器
- dates: [
- [],
- [],
- [],
- [],
- [],
- []
- ], //外层括号表示一个月,内层括号表示一周,每个元素是一天
- activeDateStr: '', // 当前选中的时间
- }
- },
-
- mounted() {
- for (let i = 1900; i <= 2100; i++) {
- this.years.push(i);
- }
- for (let i = 1; i <= 12; i++) {
- this.months.push(i);
- }
-
- //获取当前时间和月份
- var date = new Date();
- this.year = date.getFullYear();
- this.month = date.getMonth() + 1;
- let dayNum = date.getDate();
-
- for (let i = 0; i < 200; i++) {
- if (this.years[i] == this.year) {
- this.y = i;
- break;
- }
- }
- for (let i = 0; i < 12; i++) {
- if (this.months[i] == this.month) {
- this.m = i;
- break;
- }
- }
-
- //当前月份的天数和上个月的天数
- var maxdays = this.maxdformat();
- var maxday = maxdays[0];
- var premaxday = maxdays[1];
-
- //通过当月一号的星期来计算上个月的最后一个星期日时几号
- date.setDate(1);
- var weekday = date.getDay();
- this.date = premaxday - weekday + 1;
-
- //编排这个月的日历
- this.datesformat(maxday, premaxday);
-
- let mothnum = this.months[this.m]
- if(mothnum<10) {
- mothnum = '0'+mothnum
- }
- if(dayNum<10) {
- dayNum = '0'+dayNum
- }
- this.activeDateStr = this.years[this.y] + '-' + mothnum + '-' + dayNum
- },
- methods: {
- //编排日历
- datesformat(maxday, premaxday) {
- //获取当前日期,用来突出显示当前日期
- var date = new Date();
- var y = date.getFullYear();
- var m = date.getMonth() + 1;
- var d = date.getDate();
- var i = 0,
- j = 0;
- for (i; i < 3; i++) {
- for (j = 0; j < 7; j++) {
- let cache = ['#222222', '', '#fff']; //第一个元素用来定义字体颜色,第二个是日期,第三个元素是背景色,用来突出显示当前日期
- if (this.date > 21 && this.date <= premaxday) {
- cache[0] = '#BBBBBB';
- }
- /* 上个月的日期显示为灰色,只能判断前半个月,
- 因为如果到这个月的21号之后的话造成这个月的日期也变为灰色,
- 选21是因为前3周不可能到21号(1号在周日的话会放在第二周),
- 并且上个月的最后一个星期日必然是21号之后 */
- else if (this.year == y && this.month == m && this.date == d) {
- cache[2] = '#FF5C03'; // 当前日期背景颜色
- cache[0] = '#fff'; // 当前日期文字颜色
- }
- if (this.date <= premaxday) {
- cache[1] = this.date++;
- } else {
- this.date = 1;
- cache[1] = this.date++; //日期递增,如果超过上个月的最后一天的话重新从1号开始
- }
- this.dates[i].push(cache);
- }
- }
- for (i; i < 6; i++) {
- for (j = 0; j < 7; j++) {
- let cache = ['#222222', '', "#fff"]
- if (this.date < 14 || this.date == maxday + 1) {
- cache[0] = '#BBBBBB'
- } else if (this.year == y && this.month == m && this.date == d) {
- cache[2] = '#FF5C03'
- cache[0] = '#fff'; // 当前日期文字颜色
- }
- if (this.date <= maxday) {
- cache[1] = this.date++;
- } else {
- this.date = 1;
- cache[1] = this.date++;
- }
- /* 基本与上半月相似,下个月的日期显示为灰色,
- 选14是因为第4周的第一天最早是15号(1号在周日并放在第二周的情况),
- 并且下个月出现最多日期的情况(2月1号是周一)也不会有14天 */
- this.dates[i].push(cache);
- }
- }
- },
- //计算当月的天数和上个月的天数
- maxdformat() {
- var maxday = 30;
- var premaxday = 30; //都定义为30天,这样小月就不用判断了
- if (this.month == 2) {
- if (this.year % 400 == 0 || (this.year % 4 == 0 && this.year % 100 != 0)) { //二月判断平闰年
- maxday = 29;
- } else {
- maxday = 28;
- }
- } else if (this.month == 1 || this.month == 3 || this.month == 5 || this.month == 7 ||
- this.month == 8 || this.month == 10 || this.month == 12) { //给大月赋值
- maxday = 31;
- }
- //计算上个月的天数,月份+1直接用上面的
- if (this.month == 3) {
- if (this.year % 400 == 0 || (this.year % 4 == 0 && this.year % 100 != 0)) {
- premaxday = 29;
- } else {
- premaxday = 28;
- }
- } else if (this.month == 2 || this.month == 4 || this.month == 6 || this.month == 8 ||
- this.month == 9 || this.month == 11 || this.month == 1) {
- premaxday = 31;
- }
- return [maxday, premaxday];
- },
- //下一个月
- monthadd() {
- //月份加一,十二月下一个月是一月
- if (this.month == 12) {
- this.y++;
- this.year++;
- this.m = 0;
- this.month = 1;
- } else {
- this.m++;
- this.month++;
- }
- var maxdays = this.maxdformat();
- var maxday = maxdays[0];
- var premaxday = maxdays[1];
- //这个月的最后一个周日,就是下个月日历的第一天
- if (this.dates[5][0][1] > 14) {
- this.date = this.dates[5][0][1];
- } else {
- this.date = this.dates[4][0][1];
- }
- this.dates = [
- [],
- [],
- [],
- [],
- [],
- []
- ]; //日历初始化
- this.datesformat(maxday, premaxday); //编排下个月的日历
- },
- //上一个月
- monthsub() {
- if (this.month == 1) {
- this.m = 11;
- this.month = 12;
- this.y--;
- this.year--;
- } else {
- this.m--;
- this.month--;
- }
- var maxdays = this.maxdformat();
- var maxday = maxdays[0];
- var premaxday = maxdays[1];
- //根据上个月的最后一个周日,计算上个月日历的第一天
- if (this.dates[0][0][1] <= 28) {
- this.date = premaxday + this.dates[0][0][1] - 28;
- } else {
- this.date = premaxday + this.dates[0][0][1] - 35;
- }
- this.dates = [
- [],
- [],
- [],
- [],
- [],
- []
- ];
- this.datesformat(maxday, premaxday)
- },
- //下一年,就是把下一个月运行12次
- yearadd() {
- for (let c = 0; c < 12; c++) {
- this.monthadd();
- }
- },
- //上一年,就是把上一个月运行12次
- yearsub() {
- for (let c = 0; c < 12; c++) {
- this.monthsub();
- }
- },
- //picker直接选择年份,计算中间差几年,然后运行几次上一年或下一年
- yearchange(e) {
- this.y = e.target.value
- let d = this.year - this.years[this.y];
- if (d > 0) {
- for (let i = 0; i < d; i++) {
- this.yearsub();
- }
- } else {
- for (let i = 0; i < 0 - d; i++) {
- this.yearadd();
- }
- }
- this.y += d;
- },
- //picker直接选择月份
- monthchange(e) {
- this.m = e.target.value
- let d = this.month - this.months[this.m];
- if (d > 0) {
- for (let i = 0; i < d; i++) {
- this.monthsub();
- }
- } else {
- for (let i = 0; i < 0 - d; i++) {
- this.monthadd();
- }
- }
- this.m += d;
- },
- // 日期选择
- itemChose(day,w,k) {
- if(day[0] == '#222222'){ // 取消所有选中数据
- for(let i=0;i<6;i++) {
- for(let j=0;j<7;j++) {
- if(this.dates[i][j][0] != '#BBBBBB' && this.dates[i][j][2] == '#FF5C03') {
- this.dates[i][j][2] = '#fff'
- this.dates[i][j][0] = '#222222'
- }
- }
- }
- this.dates[w][k][2] = '#FF5C03'
- this.dates[w][k][0] = '#fff'
- let newValue = ['#fff', day[1], "#FF5C03"]
- this.$set(this.dates[w], k, newValue)
- }
- let mothnum = this.months[this.m]
- if(mothnum<10) {
- mothnum = '0'+mothnum
- }
- let dayNum = day[1]
- if(dayNum<10) {
- dayNum = '0'+dayNum
- }
- this.activeDateStr = this.years[this.y] + '-' + mothnum + '-' + dayNum
- }
- },
- }
- </script>
- <style scoped lang="scss">
- .calendar{
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- .chose-head{
- width: 100%;
- height: 88upx;
- border-bottom: 2upx solid #EEEEEE;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 97upx 0 67upx;
- .chose-item{
- display: flex;
- align-items: center;
- .btn{
- width: 40upx;
- height: 40upx;
- background: #F2F4F5;
- border-radius: 6upx;
- display: flex;
- align-items: center;
- justify-content: center;
- image{
- width: 11upx;
- height: 18upx;
- }
- }
- .year-td{
- width: 160upx;
- display: flex;
- align-items: center;
- justify-content: center;
- .text{
- font-size: 30upx;
- font-family: PingFang SC;
- font-weight: 500;
- color: #222222;
- }
- }
- .month-td{
- width: 100upx;
- display: flex;
- align-items: center;
- justify-content: center;
- .text{
- font-size: 30upx;
- font-family: PingFang SC;
- font-weight: 500;
- color: #222222;
- }
- }
- }
- }
- .table{
- width: 100%;
- .week{
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 20upx;
- .item{
- width: 10%;
- height: 60upx;
- line-height: 60upx;
- margin: 12upx 0;
- font-size: 26upx;
- font-family: PingFang SC;
- font-weight: 500;
- color: #222222;
- text-align: center;
- }
- }
- .date-tr{
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 20upx;
- .td{
- width: 10%;
- height: 60upx;
- line-height: 60upx;
- margin: 12upx 0;
- font-size: 26upx;
- text-align: center;
- font-family: PingFang SC;
- font-weight: 500;
- color: #222222;
- border-radius: 6upx;
- &.active{
- background-color: #FF5C03;
- }
- }
- }
- }
- }
-
- </style>
|