首页 前端知识 日期-日历-选择器实现(图文并茂)

日期-日历-选择器实现(图文并茂)

2024-09-18 02:09:23 前端知识 前端哥 15 8 我要收藏

文章目录

    • 日历模板效果图展示
    • 功能点介绍
    • 完整代码(cv即可)
      • index.wxml
      • index.wxss
      • index.js
    • 日期时间选择器效果图展示
    • 1、使用小程序原生的picker
      • ①普通选择器:mode = selector
      • ②多列选择器:mode = multiSelector
      • ③时间选择器:mode = time
      • ④日期选择器(上面有效果图)
      • ⑤省市区选择器:mode = region
    • 2、如何使用原生的picker年月日 时分秒=共同选择
      • 效果图
      • 完整代码
        • index.wxml
        • index.js
        • dateTimePicker.js

日历模板效果图展示

在这里插入图片描述

功能点介绍

   相当于留言谱,用于记录留言的历史纪录功能。主要实现的功能点在于-前端页面日历的动态搭建,哪一年哪一月哪一日对应的历史纪录。进行显示-当点击回忆录时跳转页面或者模态框实现显示。扩展-页面还可以整的更好看些,作为打卡等,本猿能力有限。

完整代码(cv即可)

微信小程序前端-跟vuejs基本没有多大差别-view改成div即可。也就是说都适用。

index.wxml

<view class="calendar">
  <view class="calendarTop">
    <text class="calendarTopL" catchtap="prev">{{'<'}}< /text>
        <text class="calendarTopC">{{nowYear}}{{nowMonthStr}}</text>
        <text class="calendarTopR" catchtap="next">{{'>'}}</text>
  </view>
  <view class="calendarWeek">
    <text class="calendarWeekItem" wx:for="{{weekList}}" wx:key="item">{{item}}</text>
  </view>
  <view class="calendarDate">
    <text class="calendarDateItem {{item.now ? 'dateItemNow' : ''}} {{item.gray ? 'dateItemGray' : ''}}" wx:for="{{month}}" bindtap="memoirbtn" data-time="{{item.timeDate}}" wx:key="index">{{item.text}}
      <text class="memoirNow">{{item.memoir}}</text>
    </text>
  </view>
</view>

index.wxss

.calendar {
  width: 100%;
  border-top: 1rpx solid #00000005;
  background-color: #FFF2C7;
  margin: 0 auto;
}

.calendarTop {
  padding-top: 22rpx;
  display: flex;
  justify-content: center;
  position: relative;
}

.calendarTopL {
  font-size: 32rpx;
  font-weight: 400;
  color: #333333;
  height: 36rpx;
  line-height: 36rpx;
  position: absolute;
  left: 34rpx;
  top: 22rpx;
}

.calendarTopC {
  font-size: 26rpx;
  font-weight: 600;
  color: #333333;
  height: 36rpx;
  line-height: 36rpx;
}

.calendarTopR {
  font-size: 32rpx;
  font-weight: 400;
  color: #333333;
  height: 36rpx;
  line-height: 36rpx;
  position: absolute;
  right: 34rpx;
  top: 22rpx;
}

.calendarWeek {
  display: flex;
  flex-direction: row;
  padding-top: 24rpx;
}

.calendarWeekItem {
  width: 60rpx;
  height: 60rpx;
  font-size: 20rpx;
  font-weight: 400;
  color: #999999;
  line-height: 60rpx;
  text-align: center;
  margin-left: 40rpx;
}

.calendarDate {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.calendarDateItem {
  width: 100rpx;
  height: 200rpx;
  font-size: 26rpx;
  font-weight: bold;
  color: #333333;
  line-height: 60rpx;
  text-align: center;
  border: 1rpx solid rgba(0, 0, 0, 0.4);
}

.memoirNow {
  display: flex;
  width: 100%;
  height: 140rpx;
  background: #FCC001;
}

.dateItemNow {
  background: #2E8CFF;
  color: #FFFFFF;
}

.dateItemGray {
  color: #CCCCCC;
}

index.js

Page({
  /**
   * 页面的初始数据
   */
  data: {
    weekList: ['一', '二', '三', '四', '五', '六', '日'], //一周
    month: [
      {
        // text   此值为日期值,类型为number
        // now    此值为今天,在本月的周末为false,其它时候为true,类型为布尔
        // gray   此值为日期置灰,本月中的上月和下月日期以及本月的周末,类型为布尔
      }
    ],//一个月所有数据
    nowYear: 0,//选择的年
    nowMonth: 0,//选择的月
    nowMonthStr: '',//转换格式的月
    today: 0,//今天
    memorandum: [{ "creationTime": "2022-12-12" }, { "creationTime": "2022-12-16" }, { "creationTime": "2022-12-03" }],  //为了演示,此为模拟数据,也可从后端获取数据源
  },
  //回忆录 进行点击查看内容-(作为参考)
  // memoirbtn(e) {
  //   //根据前端传过来的时间,还有用户标识,进行表查询,最终跳转页面-显示到前端页面上内容
  //   var index = e.currentTarget.dataset.time;
  //   console.log("传过来的值是想要的" + index);
  //   if (index != "") {
  //     wx.navigateTo({
  //       url: '/pages/time_record/index?dateTime=' + index,
  //     })
  //   } else {
  //     wx.showToast({
  //       title: '当日未建立任务点',
  //       icon: 'error',
  //       duration: 1500
  //     })
  //   }
  // },
  // 获取当前年月日
  gainDate() {
    let d = Reflect.construct(Date, []);
    this.setData({
      nowYear: d.getFullYear(),
      nowMonth: d.getMonth() + 1,
      today: d.getDate(),
      nowMonthStr: (d.getMonth() + 1).toString().padStart(2, '0')
    })
  },
  // 上个月
  prev() {
    if (this.data.nowMonth > 1) {
      this.setData({
        nowMonth: this.data.nowMonth - 1,
        nowMonthStr: (this.data.nowMonth - 1).toString().padStart(2, '0')
      })
    } else {
      this.setData({
        nowYear: this.data.nowYear - 1,
        nowMonth: 12,
        nowMonthStr: "12"
      })
    };
    this.todayProminent()
    this.dateInit()
  },
  // 下个月
  next() {
    if (this.data.nowMonth < 12) {
      this.setData({
        nowMonth: this.data.nowMonth + 1,
        nowMonthStr: (this.data.nowMonth + 1).toString().padStart(2, '0')
      })
    } else {
      this.setData({
        nowYear: this.data.nowYear + 1,
        nowMonth: 1,
        nowMonthStr: "01"
      })
    }
    this.todayProminent()
    this.dateInit()
  },
  //今天日期凸显
  todayProminent() {
    // 将今天置为0
    this.setData({
      today: 0
    })
    let d = Reflect.construct(Date, []);
    if (d.getFullYear() == this.data.nowYear && d.getMonth() + 1 == this.data.nowMonth) {
      this.setData({
        today: d.getMonth() + 1 > this.data.nowMonth + 1 ? 0 : d.getDate()
      })
    }
  },
  // 日历主体
  dateInit() {
    let now = Reflect.construct(Date, [this.data.nowYear, this.data.nowMonth - 1]); //当前月份的一号
    let startWeekNow = now.getDay(); //当前月份的一号对应的星期
    let end = Reflect.construct(Date, [Reflect.construct(Date, [this.data.nowYear, this.data.nowMonth]) - 10]);// 当前月份的最后一号
    let endWeekNow = end.getDay(); //当前月份的最后一天对应的星期
    let dayNumNow = Reflect.construct(Date, [this.data.nowYear, this.data.nowMonth, 0]).getDate(); //当前月有多少天
    let dayNumPrev = Reflect.construct(Date, [this.data.nowYear - 1 ? this.data.nowYear : this.data.nowYear - 1, this.data.nowMonth - 1 ? this.data.nowMonth - 1 : 12, 0]).getDate(); //上个月有多少天

    let prevMonthShow = []; //上个月日期展示的数据
    let nowMonthShow = []; //本月日期展示的数据
    let nextMonthShow = []; //下个月日期展示的数据
    //进行判断是否有内容  先确认当今是几年几月,然后调用后端方法,查询出全部数据,进行匹配
    console.log("当前年月" + this.data.nowYear + "-" + this.data.nowMonth)
    var memoir = "";
    var timeDate = "";
    var times = "";
    //标记几年几月几日,标记是否有值
    for (let i = 1; i < (startWeekNow ? startWeekNow : 7); i++) {
      if (this.data.nowMonth == 1) {
        timeDate = (this.data.nowYear - 1) + "-" + 12
      } else {
        timeDate = (this.data.nowYear) + "-" + (this.data.nowMonth - 1)
      }
      if ((dayNumPrev - i + 1) < 10) {
        times = "0" + (dayNumPrev - i + 1);
      } else {
        times = dayNumPrev - i + 1
      }
      timeDate = timeDate + "-" + times;
      memoir = this.creationTime(timeDate);
      prevMonthShow.unshift( //头部添加
        {
          text: dayNumPrev - i + 1, //30   29  28
          now: false,
          gray: true,
          timeDate: timeDate,
          memoir: memoir
        }
      )
    };
    for (let i = 1; i <= dayNumNow; i++) {
      if (i < 10) {
        times = "0" + i;
      } else {
        times = i;
      }
      timeDate = this.data.nowYear + "-" + this.data.nowMonth + "-" + times;
      memoir = this.creationTime(timeDate);
      if (this.data.today == i) {
        nowMonthShow.push(
          {
            text: i,
            now: true,
            gray: false,
            timeDate: timeDate,
            memoir: memoir
          }
        )
      } else {
        nowMonthShow.push(
          {
            text: i,
            now: false,
            gray: false,
            timeDate: timeDate,
            memoir: memoir
          }
        )
      }
    };
    for (let i = 1; i <= (endWeekNow ? 7 - endWeekNow : 0); i++) {
      if (this.data.nowMonth == 12) {
        timeDate = (this.data.nowYear + 1) + "-" + "01"
      } else {
        timeDate = (this.data.nowYear) + "-" + (this.data.nowMonth + 1)
      }
      if (i < 10) {
        times = "0" + i;
      } else {
        times = i;
      }
      timeDate = timeDate + "-" + times;
      memoir = this.creationTime(timeDate);
      nextMonthShow.push(
        {
          text: i,
          now: false,
          gray: true,
          timeDate: timeDate,
          memoir: memoir
        }
      )
    };
    this.setData({
      month: [...prevMonthShow, ...nowMonthShow, ...nextMonthShow]
    })

  },
  creationTime(timeDate) {
    var memoir = "";
    let memorandum = this.data.memorandum || [];
    console.log("后端传过来的值为:" + memorandum.length);
    memorandum.forEach(element => {
      //把标准时间转换成自己想要的格式类型
      var dateee = new Date(element.creationTime).toJSON();
      var time1 = new Date(+new Date(dateee) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')
      //进行转换-例如2022-12-12 12:12:36 转成 2022-12-12 省略时分秒
      var date2 = /\d{4}-\d{1,2}-\d{1,2}/g.exec(time1)
      if ((new Date(date2).getTime()) == (new Date(timeDate).getTime())) {
        memoir = "回忆录";
      }
    });
    return memoir;
  },
  // duckMemorandum() {  //初始化数据-(作为参考)
  //   var that = this;
  //   wx.request({
  //     url: 'http://localhost:8081/duckMemorandum/list',
  //     method: 'GET',
  //     data: {
  //       userId: 1
  //       //需要传入用户id
  //     },
  //     // 请求成功时的处理
  //     success: function (res) {
  //       // 一般在这一打印下看看是否拿到数据
  //       console.log(res.data)
  //       if (res.data.code = 200) {
  //         that.setData({
  //           memorandum: [...res.data.data]
  //         })

  //       }
  //     },
  //     // 请求失败时的一些处理
  //     fail: function () {
  //       wx.showToast({
  //         icon: "none",
  //         mask: true,
  //         title: "接口调用失败,请稍后再试。",
  //       });
  //     }
  //   })
  // },
  /**
 * 生命周期函数--监听页面加载
 */
  onLoad(options) {
    // this.duckMemorandum();
    this.gainDate();
    this.dateInit()
  },
})

日期时间选择器效果图展示

在这里插入图片描述

1、使用小程序原生的picker

从底部弹起的滚动选择器。

①普通选择器:mode = selector

选择器用mode来区别,默认是普通选择器,e.detail.value拿到的值是选择了项的索引index,再通过array拿到值.在data里面做初始化的时候,将备选项加入array即可.
选择时触发bindPickerChange事件,获取index.
index.wxml

 <picker bindchange="pickChange" value="{{index}}" range="{{array}}">
    <view>
        当前选择的国家:{{array[index]}}
    </view>
  </picker>

index.js

Page({
  data:{
    array:['中国','美国','日本','韩国'],
    index:0
  },
  pickChange:function(e){
    this.setData({
      index:e.detail.value
    });
  }
})

②多列选择器:mode = multiSelector

在这里插入图片描述

index.wxml

<view>
  <view class="section__title">多列选择器</view>
  <picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange"
    value="{{multiIndex}}" range="{{newArr}}">
    <view class="picker">
      当前选择: <van-button type="primary">
        {{newArr[0][multiIndex[0]]}}{{newArr[1][multiIndex[1]]}}{{newArr[2][multiIndex[2]]}}</van-button>
    </view>
  </picker>
</view>

index.js

Page({
  /**
   * 页面的初始数据
   */
  data: {
    multiArray: [{
      id: 1,
      label: "河南省",
      children: [{
        id: 2,
        label: "郑州市",
        children: [{
          id: 3,
          label: "中原区",
        },
        {
          id: 4,
          label: "二七区",
        },
        {
          id: 5,
          label: "金水区",
        },
        ],
      },
      {
        id: 7,
        label: "商丘市",
        children: [{
          id: 8,
          label: "民权县",
        },
        {
          id: 9,
          label: "柘城县",
        },
        {
          id: 10,
          label: "宁陵县",
        },
        ],
      },
      ],
    },
    {
      id: 17,
      label: "浙江省",
      children: [{
        id: 18,
        label: "杭州市",
        children: [{
          id: 19,
          label: "西湖区",
        },
        {
          id: 20,
          label: "萧山区",
        },
        ],
      },
      {
        id: 21,
        label: "金华市",
        children: [{
          id: 22,
          label: "金东区",
        },
        {
          id: 23,
          label: "婺城区",
        },
        ],
      },
      ],
    },
    ],
    multiIndex: [0, 0, 0],
    multiIds: [],
    newArr: [],
  },

  bindMultiPickerChange(e) {
    console.log(this.data.multiIds);
  },
  bindMultiPickerColumnChange(e) {
    let data = {
      newArr: this.data.newArr,
      multiIndex: this.data.multiIndex,
      multiIds: this.data.multiIds,
    };
    data.multiIndex[e.detail.column] = e.detail.value;

    let searchColumn = () => {
      let arr1 = [];
      let arr2 = [];
      this.data.multiArray.map((v, vk) => {
        if (data.multiIndex[0] === vk) {
          data.multiIds[0] = {
            ...v,
          };
          v.children.map((c, ck) => {
            arr1.push(c.label);
            if (data.multiIndex[1] === ck) {
              data.multiIds[1] = {
                ...c,
              };
              c.children.map((t, vt) => {
                arr2.push(t.label);
                if (data.multiIndex[2] === vt) {
                  data.multiIds[2] = {
                    ...t,
                  };
                }
              });
            }
          });
        }
      });
      data.newArr[1] = arr1;
      data.newArr[2] = arr2;
    };
    switch (e.detail.column) {
      case 0:
        // 每次切换还原初始值
        data.multiIndex[1] = 0;
        data.multiIndex[2] = 0;
        // 执行函数处理
        searchColumn();
        break;
      case 1:
        data.multiIndex[2] = 0;
        searchColumn();
        break;
    }
    this.setData(data);
  },

  multiArrayshow() {
    let state = {
      arr: [],
      arr1: [],
      arr2: [],
      arr3: [],
      multiIds: []
    }
    this.data.multiArray.map((v, vk) => {
      state.arr1.push(v.label);
      if (this.data.multiIndex[0] === vk) {
        state.multiIds[0] = v;
      }
      if (state.arr2.length <= 0) {
        v.children.map((c, ck) => {
          state.arr2.push(c.label);
          if (this.data.multiIndex[1] === ck) {
            state.multiIds[1] = c;
          }
          if (state.arr3.length <= 0) {
            c.children.map((t, tk) => {
              state.arr3.push(t.label);
              if (this.data.multiIndex[2] === tk) {
                state.multiIds[2] = t;
              }
            });
          }
        });
      }
    });
    state.arr[0] = state.arr1;
    state.arr[1] = state.arr2;
    state.arr[2] = state.arr3;
    this.setData({
      newArr: state.arr,
      multiIds: state.multiIds,
    });
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.multiArrayshow();
  },
});

index.wcss

.section__title{
  display: flex;
  align-content: center;
  justify-content: center;
  font-size: 42rpx;
  font-weight: bold;
}
.picker{
  font-size: 36rpx;
  color: red;
  background: black;
}

③时间选择器:mode = time

mode = time时,是时间选择器.start,end分别是有效时间范围的开始和结束.格式hh:mm
选择时触发bindTimeChange事件,获取time.
在这里插入图片描述

index.wxml

<view class="title_rq">
  <picker mode="time" name="creationTime" value="{{creationTime}}" start="00:00" end="24:60" bindchange="bindDateChange">
    {{creationTime}}
  </picker>
</view>

index.js

Page({

  /**
   * 页面的初始数据
   */
  data: {
    creationTime: "请选择时间" 
  },

  // 点击日期组件确定事件 
  bindDateChange: function (e) {
    this.setData({
      creationTime: e.detail.value
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

})

index.wcss

.title_rq {
  position: absolute;
  top: 12%;
  left: 5%;
  width: 90%;
  height: 70rpx;
  background: #f3e306;
  border: 1rpx solid black;
  font-size: 36rpx;
  color: #3D3D3D;
}

④日期选择器(上面有效果图)

mode = date时,是时间选择器.start,end分别是有效日期范围的开始和结束.格式yyyy-MM-dd
选择时触发bindDateChange事件,获取date
index.wxml

<view class="title_rq">
  <picker mode="date" name="creationTime" value="{{creationTime}}" start="1920-01-01" end="2099-01-01" bindchange="bindDateChange">
    {{creationTime}}
  </picker>
</view>

index.js

Page({

  /**
   * 页面的初始数据
   */
  data: {
    creationTime: "请选择日期" 
  },

  // 点击日期组件确定事件 
  bindDateChange: function (e) {
    this.setData({
      creationTime: e.detail.value
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

})

index.wcss

.title_rq {
  position: absolute;
  top: 12%;
  left: 5%;
  width: 90%;
  height: 70rpx;
  background: #f3e306;
  border: 1rpx solid black;
  font-size: 36rpx;
  color: #3D3D3D;
}

⑤省市区选择器:mode = region

之前单独做过一栏:可供参考:
简易实现
java前后端实现
java-vue前后端实现

2、如何使用原生的picker年月日 时分秒=共同选择

思路:加一起就行了

效果图

在这里插入图片描述

完整代码

index.wxml
<view class="container">
  <view class="tui-picker-name">日期时间选择器(精确到秒)</view>
  <picker mode="multiSelector" value="{{dateTime}}" bindchange="changeDateTime" bindcolumnchange="changeDateTimeColumn" range="{{dateTimeArray}}">
    <view class="tui-picker-detail">
      选择日期时间: {{dateTimeArray[0][dateTime[0]]}}-{{dateTimeArray[1][dateTime[1]]}}-{{dateTimeArray[2][dateTime[2]]}} {{dateTimeArray[3][dateTime[3]]}}:{{dateTimeArray[4][dateTime[4]]}}:{{dateTimeArray[5][dateTime[5]]}}
    </view>
  </picker>
</view>
index.js
var dateTimePicker = require('../../utils/dateTimePicker.js');


Page({
  data: {
    dateTimeArray: null,
    dateTime: null,
    startYear: 2000,
    endYear: 2050
  },
  onLoad(){
    // 获取完整的年月日 时分秒,以及默认显示的数组
    var obj = dateTimePicker.dateTimePicker(this.data.startYear, this.data.endYear);  
    this.setData({
      dateTime: obj.dateTime,
      dateTimeArray: obj.dateTimeArray,
    });
  },


  changeDateTime(e){
    this.setData({ dateTime: e.detail.value });
  },


  changeDateTimeColumn(e){
    var arr = this.data.dateTime, dateArr = this.data.dateTimeArray;


    arr[e.detail.column] = e.detail.value;
    dateArr[2] = dateTimePicker.getMonthDay(dateArr[0][arr[0]], dateArr[1][arr[1]]);


    this.setData({
      dateTimeArray: dateArr,
      dateTime: arr
    });
  },
})
dateTimePicker.js
function withData(param){
  return param < 10 ? '0' + param : '' + param;
}
function getLoopArray(start,end){
  var start = start || 0;
  var end = end || 1;
  var array = [];
  for (var i = start; i <= end; i++) {
    array.push(withData(i));
  }
  return array;
}
function getMonthDay(year,month){
  var flag = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0), array = null;


  switch (month) {
    case '01':
    case '03':
    case '05':
    case '07':
    case '08':
    case '10':
    case '12':
      array = getLoopArray(1, 31)
      break;
    case '04':
    case '06':
    case '09':
    case '11':
      array = getLoopArray(1, 30)
      break;
    case '02':
      array = flag ? getLoopArray(1, 29) : getLoopArray(1, 28)
      break;
    default:
      array = '月份格式不正确,请重新输入!'
  }
  return array;
}
function getNewDateArry(){
  // 当前时间的处理
  var newDate = new Date();
  var year = withData(newDate.getFullYear()),
      mont = withData(newDate.getMonth() + 1),
      date = withData(newDate.getDate()),
      hour = withData(newDate.getHours()),
      minu = withData(newDate.getMinutes()),
      seco = withData(newDate.getSeconds());


  return [year, mont, date, hour, minu, seco];
}
function dateTimePicker(startYear,endYear,date) {
  // 返回默认显示的数组和联动数组的声明
  var dateTime = [], dateTimeArray = [[],[],[],[],[],[]];
  var start = startYear || 1978;
  var end = endYear || 2100;
  // 默认开始显示数据
  var defaultDate = date ? [...date.split(' ')[0].split('-'), ...date.split(' ')[1].split(':')] : getNewDateArry();
  // 处理联动列表数据
  /*年月日 时分秒*/ 
  dateTimeArray[0] = getLoopArray(start,end);
  dateTimeArray[1] = getLoopArray(1, 12);
  dateTimeArray[2] = getMonthDay(defaultDate[0], defaultDate[1]);
  dateTimeArray[3] = getLoopArray(0, 23);
  dateTimeArray[4] = getLoopArray(0, 59);
  dateTimeArray[5] = getLoopArray(0, 59);


  dateTimeArray.forEach((current,index) => {
    dateTime.push(current.indexOf(defaultDate[index]));
  });


  return {
    dateTimeArray: dateTimeArray,
    dateTime: dateTime
  }
}
module.exports = {
  dateTimePicker: dateTimePicker,
  getMonthDay: getMonthDay
}

在这里插入图片描述

各位看官》创作不易,点个赞!!!
诸君共勉:万事开头难,只愿肯放弃。

免责声明:本文章仅用于学习参考

转载请注明出处或者链接地址:https://www.qianduange.cn//article/18403.html
标签
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!