Applet WeChat: componente de calendario de escritura a mano

1. Introducción

Recientemente, la compañía va a hacer un pequeño programa para el check-in en el hotel. Es inevitable que se use el calendario, y el pequeño programa no tiene un componente de calendario incorporado. Miré a Internet y no había un calendario que fuera muy adecuado para mis necesidades, así que escribí uno yo mismo.

En segundo lugar, el código

1. Análisis de principios

Solo hay dos cosas que necesita saber para escribir un calendario:

  1. ¿Cuántos días hay en un mes?
  2. El primer día de cada mes es el día de la semana.

2. Análisis funcional

Dado que es un calendario de check-in del hotel, se deben implementar las siguientes funciones:

  1. Calendario de representación, generalmente a partir de este mes, hasta el calendario medio año después
  2. La fecha pasada no es seleccionable
  3. Haga clic para obtener la fecha de entrada, la fecha de salida y cambiar el color de la fecha correspondiente y el color de todo el período de tiempo

3. Análisis de datos

Según la implementación de la función final, la estructura de datos de cada mes que generé es la siguiente:

{
    year: 2018,
    month: 3,
    fullMonth: '03',
    allDays:[
        {
            day: 1,
            fullDay: '01',
            fullDate: '2018-03-01'
        },
        {
            day: 2,
            fullDay: '02',
            fullDate: '2018-03-02'
        },
        //......
        //(后面的数据同上)
    ]
}

año es el año, mes es el mes, día es la fecha y fullDate es la fecha completa.
FullMonth y fullDay eran originalmente dos datos innecesarios, pero se usaron cuando se hizo clic en la fecha para cambiar el color, porque el applet no proporcionaba un buen filtro para procesar los datos. Por supuesto, este problema también está relacionado con mi nivel personal. Si hay un gran dios que tiene una mejor manera, por favor deje un mensaje para decirme. Realmente quiero eliminar estos dos datos.

4. Análisis de código

// calendar.js文件

Page({
  data: {
    week_list: ['日','一','二','三','四','五','六'],
    startDate: '',
    endDate: '',
    date_click: 0
  },
  // 获取每月总天数
  getAllDaysOfMonth(year,month) {
    return new Date(year,month,0).getDate();
  },
  // 获取每月第一天是星期几
  getFirstDayOfMonth(year,month) {
    return new Date(year, month - 1, 1).getDay();
  },
  // 计算本月前空了几格
  getEmptyGrids(year,month) {
    // FirstDayOfMonth代表本月的第一天是星期几
    const FirstDayOfMonth = this.getFirstDayOfMonth(year, month);
    let emptyGrids = [];
    
    // 有空格的情况
    if (FirstDayOfMonth > 0) {
      for (let i = 0; i < FirstDayOfMonth; i++) {
        emptyGrids.push({
          'num': '',
          'fullDate': 'x'  //x是我自己定义的一个值,代表没有日期
        });
      }
      // 将空格放入数组
      return emptyGrids;
    }else{
      // 否则返回一个新数组
      return [];
    }
  },
  // 计算本月日历
  getDaysOfThisMonth(year,month) {
    let days = [];
    const AllDaysOfMonth = this.getAllDaysOfMonth(year, month);

    let fullMonth = month.toString().length === 1 ? `0${month}`:month;
    for (let i = 0; i < AllDaysOfMonth; i++) {
      let day = i+1,
          fullDay = day;

      fullDay = fullDay.toString().length === 1 ? `0${day}` : fullDay;
      days.push({
        day,
        fullDay,
        'fullDate': `${year}-${fullMonth}-${fullDay}`
      });
    }
    // 返回每个月的具体日期
    return days;
  },
  // 循环渲染日历
  // 从本月开始渲染,n代表包括本月开始连续渲染几个月
  fillCalendar(n) {
    let year = this.data.cur_year,
        month = this.data.cur_month,
        fullMonth,
        canlendar_data = [];

    // 计算年月以及具体日历
    for (let i = this.data.cur_month; i < this.data.cur_month + n; i++) {
      let EmptyGrids = this.getEmptyGrids(year, month);
      let DaysOfThisMonth = this.getDaysOfThisMonth(year, month);

      // 把空格和具体日历合为一个数组
      let allDays = [...EmptyGrids, ...DaysOfThisMonth];

      // 对年份和月份的计算做一些判断
      if (month > 12) {
        year++;
        month = 1;
        fullMonth = '01'
        canlendar_data.push({
          year, 
          month, 
          fullMonth,
          allDays });
        month++;
      }else{
        fullMonth = month.toString().length === 1 ? `0${month}` : month;
        canlendar_data.push({ 
          year, 
          month, 
          fullMonth,
          allDays });
        month++;
        
      }

    }

    this.setData({
      canlendar_data
    })
  },
  onLoad() {
    const date = new Date();
    const cur_year = date.getFullYear();
    const cur_month = date.getMonth() + 1;
    const cur_day = date.getDate();
    this.setData({
      date,
      cur_year,
      cur_month,
      cur_day
    })

    let month = this.data.cur_month.toString().length === 1 ? `0${this.data.cur_month}` : this.data.cur_month;
    let day = this.data.cur_day.toString().length === 1 ? `0${this.data.cur_day}` : this.data.cur_day;
    let nowDate = `${cur_year}-${month}-${day}`;

    this.setData({
      nowDate
    })

    this.fillCalendar(6);
  },
  // 点击日期
  chooseDate(e) {
    const year_click = e.currentTarget.dataset.year;
    const month_click = e.currentTarget.dataset.month;
    const day_click = e.currentTarget.dataset.day;
    console.log(year_click,month_click,day_click);
    // 如果是空格或者以前的日期就直接返回
    if(day_click === ''||`${year_click}-${month_click}-${day_click}` < this.data.nowDate) {
      return;
    }

    // 获取点击对象的id
    let id = e.currentTarget.dataset.id;
    
    // data_click为0代表选择的是入住日期,否则就是离店日期
    if (this.data.date_click == 0){
      // 选择入住日期
      this.setData({
        startDate: `${year_click}-${month_click}-${day_click}`,
        date_click: 1
      })
    }else {
      let newDay = new Date(Date.parse(id));
      let oldDay = new Date(Date.parse(this.data.startDate));

      // 判断第二次点击的日期在第一次点击的日期前面还是后面
      if (newDay > oldDay) {
        this.setData({
          endDate: `${year_click}-${month_click}-${day_click}`,
          date_click: 2
        })
      }else{
        this.setData({
          startDate: `${year_click}-${month_click}-${day_click}`,
          endDate: '',
          date_click: 1
        })
      }
    }
  }
})
<!-- calendar.wxml文件 -->

<view class="container">
  <view id="week">
    <view class="week-item {{idx===0||idx===6?'relax':''}}" wx:for="{{week_list}}" wx:for-index="idx">{{item}}</view>
  </view>
  <scroll-view scoll-y="true">
    <view class="month-block" wx:for="{{canlendar_data}}" wx:for-item="canlendar_item">
      <view class="month-title">{{canlendar_item.year}}年{{canlendar_item.month}}月</view>
      <view class="month-content">
        <view class="month-day {{item.fullDate<nowDate?'gray':''}} {{startDate===item.fullDate?'startActive':''}} {{endDate===item.fullDate?'endActive':''}} {{item.fullDate>startDate&&item.fullDate<endDate&&startDate!==''&&endDate!==''?'midActive':''}}" bindtap="chooseDate" data-year="{{canlendar_item.year}}" data-month="{{canlendar_item.fullMonth}}" data-day="{{item.fullDay}}" data-id="{{item.fullDate}}" wx:for="{{canlendar_item.allDays}}">{{item.day}}</view>
      </view>
    </view>
  </scroll-view>
</view>

{{idx === 0 || idx === 6? 'relax': ''}} es cambiar el color del sábado y domingo,
{{item.fullDate <nowDate? 'gray': ''}} es cambiar El color de la fecha pasada,
{{startDate === item.fullDate? 'StartActive': ''}} juzga que la fecha en la que se hizo clic es la fecha de registro,
{{endDate === item.fullDate? 'EndActive': ''}} juzga el clic ¿Es la fecha de salida,
{{item.fullDate> startDate && item.fullDate <endDate && startDate! == '' && endDate! == ''? 'MidActive': ''}} cambia el color de la fecha entre la fecha de entrada y la fecha de salida

4. Conclusión

En este punto, se completa un calendario simple. Por supuesto, este calendario no puede satisfacer todas las necesidades comerciales, pero la función básica de representación de calendario y la función de selección de clic están disponibles. Por lo tanto, una pequeña parte se puede cambiar según los requisitos del negocio. Espero que pueda dejar un mensaje para señalar mi problema, y ​​seguiré mejorando este código de calendario.

Supongo que te gusta

Origin www.cnblogs.com/10manongit/p/12722340.html
Recomendado
Clasificación