小程序组件实现周日历功能,课程表、食谱等功能可能会用到的日历简单实现

一、功能演示说明

        先详细的展示功能图片以及功能说明,以确保大家看到这里能确定功能是否是自己想要的。这是一个可以实现课程表、食谱等一些功能的周日历,并且注意这是一个【组件】,同时我也建议把这种功能写成组件化,方便复用。

        具体的功能,我们可以点选日期获得该日期的详细标志,例如我们点了如下图所示的’2018-12‘的周二,在我们的调用界面中的js代码中回调方法就可以获取到该日的具体日期数值。   点击上一周下一周可以切换周,并且不是本周时默认选中值为周一,回到本周时,默认选中值为当日日期。     

  图中一些其它的东西,设置  加号大家可以忽略,这是在工作中涉及到的其它关于食谱的功能。只要知道在下面该组件的代码中不会有这些额外的东西存在。

 

二、组件代码分段说明

        为了清晰,这里详细说明文涉及件名称,和每个文件内容的详情,以及写代码时的思路。尽量做到代码直接复制出去是可用的。也可以提供一些思路供大家参考,然后可以自己实现该功能。

时间工具

        写这个功能时为了分割开逻辑和布局,我首先想到用一个日期时间工具类来完成日期数据的处理。这里处理方式并不复杂,简单的一个方法,为界面提供了想要的展示数据。   

        看到下面代码貌似有点多,不要慌,里面包含我后续一些工具方法放在里面,实际在该组件中产生用到的只有【第一个方法】,没错就只有第一个方法,整理了时间数据。这里也写了详细的代码说明,就是获取周和日的对应列表,以便对应的每个item里显示周几,和几号的信息。在使用该类方法时记得引用(例 :var util = require("../../utils/time-utils.js") )根据你的类对应的路径

 

/**
 * 获取该周的所要显示的周和日期的对应数据,数据结构如下
 * var weekDay = {week: '',day: ''}
 * 参数:selectWeek  0为本周,数字代表前几周或者后几周,例如1是下一周
 */
function getWeekDayList(selectWeek) {
  // 1.获取周一对应得时间
  // 2.用循环七次添加周一到周日对应得周几和几号
  var selectWeekTime = getCurrentTimeStamp() + (selectWeek * 7) * 24 * 60 * 60 * 1000
  var mondayTime = selectWeekTime - (getWeekNumber(selectWeekTime) - 1) * 24 * 60 * 60 * 1000
  var timeBean = {
    selectDay: 0,
    yearMonth: '',
    weekDayList: []
  }

  for (var i = 0; i < 7; i++) {
    var weekDay = {
      week: '',
      day: ''
    }
    weekDay.week = getWeek(mondayTime + i * 24 * 60 * 60 * 1000)
    weekDay.day = getMyDay(mondayTime + i * 24 * 60 * 60 * 1000)
    timeBean.weekDayList.push(weekDay)
  }

  timeBean.yearMonth = getYearMonth(selectWeekTime);
  timeBean.selectDay = getCurrenrWeek();
  return timeBean;
}


//获取当前时间戳  --
function getCurrentTimeStamp() {
  var timestamp = new Date().getTime();
  return timestamp
}

//获取当前周几
function getCurrenrWeek() {
  var str = "6012345".charAt(new Date().getDay());
  return str;
}

//时间戳获得年月
function getYearMonth(res) {
  var time = new Date(res);
  var y = time.getFullYear();
  var m = time.getMonth() + 1;
  return y + "-" + m;
}

//时间戳转几号
function getMyDay(res) {
  var time = new Date(res);
  var d = time.getDate();
  return d;
}

//时间戳转周几 
function getWeek(res) {
  var time = new Date(res);
  var y = time.getFullYear();
  var m = time.getMonth() + 1;
  var d = time.getDate();
  return "日一二三四五六".charAt(new Date(y + '-' + m + '-' + d).getDay());
}

//时间戳转周几 0123456  --
function getWeekNumber(res) {
  var time = new Date(res);
  var y = time.getFullYear();
  var m = time.getMonth() + 1;
  var d = time.getDate();
  return "0123456".charAt(new Date(y + '-' + m + '-' + d).getDay());
}

module.exports = {  //把方法共享,让引用的地方可以调用
  getWeekDayList: getWeekDayList,
}

组件代码

        接下来就是组件的主要代码,和小程序一个模块一样,这里有四个不同格式文件。js、json、wxml、wxss,四个文件每个文件只有简单的几行代码,也都有详细的说明很好理解,可以直接复制使用。里面多是一些布局和样式,没有什么逻辑,如果对小程序组件不是很了解的朋友,建议详细对小程序组件进行一下了解,基本都会用到的。

weekCalendar.js   包含了点击事件传递给调用组件的js文件的方法

// compoents/weekCalendar/weekCalendar.js
Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },

  /** * 组件的属性列表 * 用于组件自定义设置 */
  properties: {
    timeBean: { // 属性名 在wxml调用组件时利用该属性传递组件显示的数据
      type: Object, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型) 
      value: ''// 属性初始值(可选),如果未指定则会根据类型选择一个
    },
  },

  /**
   * 组件的方法列表
   */
  methods: {
    lastWeek:function(e){ //点击了上一周
      this.triggerEvent("lastWeek")
    },

    nextWeek:function(e){ //点击了下一周
      this.triggerEvent("nextWeek")
    },
 
    itemClick: function (e) {  //点击了某一日,传递该日的下标
      var index = e.currentTarget.dataset.index
      this.triggerEvent("dayClick", index);
    },
  }
})

weekCalendar.json  配置文件,组件的基本配置

{
  "component": true 
}

weekCalendar.wxml   界面

<!--compoents/weekCalendar/weekCalendar.wxml-->
<view class='line'></view>

<view class='row'>
  <view class='row' bindtap='lastWeek'>
    <text class='iconfont icon-sanjiaoleft' style='padding:15rpx;color:#999999'></text>
    <view style='font-size:28rpx;color:#999999'>上一周</view>
  </view>
  <view class='timeType'>{{timeBean.yearMonth}}</view>
  <view class='row' bindtap='nextWeek'>
    <view style='font-size:28rpx; color:#999999'>下一周</view>
    <text class='iconfont icon-sanjiaoright' style='padding:15rpx;color:#999999'></text>
  </view>
</view>

<view class='row'>
    <view  wx:for="0123456" data-index="{{index}}" class='{{index==timeBean.selectDay?"select-column":"column"}}' bindtap='itemClick'>
      <view class='weekType'>{{timeBean.weekDayList[index].week}}</view>
      <view class='dateType'>{{timeBean.weekDayList[index].day}}</view>
      <text class='iconfont icon-mifan' style='color:#fff'></text>
    </view>
</view>

<view class='line-shadow'></view>

<view class='suspension' bindtap='addMenuClick'>
  <text class='iconfont icon-tianjia' style='font-size:60rpx; color:#fff;'></text>
</view>

weekCalendar.wxss  界面样式,这里用到了字体图标,如果想替换的话直接修改界面就好,也可以直接复制使用

/* compoents/weekCalendar/weekCalendar.wxss */
.row { 
  display:flex; flex-direction:row;  
  justify-content: space-around; 
  align-items: center;
  background: #fff;}

.column{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-bottom: 5rpx;
  padding-top: 5rpx;  
  margin-top: 10rpx;
  flex: 1;
}

.select-column{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-bottom: 5rpx;
  padding-top: 5rpx;  
  margin-left: 5rpx;
  margin-right: 5rpx;
  margin-top: 10rpx;
  flex: 1;
  border-top-left-radius:20rpx;
  border-top-right-radius:20rpx;
  background: #36d6a6;
}

.timeType{
  font-size: 35rpx;
  font-weight:bold;
}

.dateType{
  font-size: 35rpx;
  font-weight:bold;
}

.weekType{
  font-size: 28rpx;
  color: darkgrey;
}

.line{
  height: 1rpx;
  width: 100%;
  background-color: gainsboro;
}

.line-shadow{
  height: 3rpx;
  width: 100%;
  background-color: gainsboro;
  box-shadow:5px 0px 5px 0px gainsboro;
}

@font-face {font-family: "iconfont";
  src: url('iconfont.eot?t=1533031583450'); /* IE9*/
  src: url('iconfont.eot?t=1533031583450#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
  url('iconfont.ttf?t=1533031583450') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
  url('iconfont.svg?t=1533031583450#iconfont') format('svg'); /* iOS 4.1- */
}

.iconfont {
  font-family:"iconfont" !important;
  font-size:16px;
  font-style:normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/**
*字体图标,左右箭头,书,米饭,可以修改界面对图标进行修改替换
*/
.icon-sanjiaoleft:before { content: "\e6b6"; }  

.icon-sanjiaoright:before { content: "\e6b7"; }

.icon-book1:before { content: "\e631"; }

.icon-mifan:before { content: "\e606"; }

 

三、调用流程说明

        以上这个小程序的周日历组件算是完成了,剩下的就时调用了,这还不简单嘛,参考组件的正常应用流程,代码如下

首先是json配置文件中表示引用该控件,路径要对应自己组件的路径

{
  "usingComponents": {
    "weekCalendar": "../../../compoents/weekCalendar/weekCalendar",
  }
}

然后是wxml界面直接的组件调用

这里是不是有发现,timeBean就是组件中写的接收数据,bind事件都是组件中调用调用方的方法呢

<weekCalendar timeBean="{{timeBean}}" bind:lastWeek="lastWeek" bind:nextWeek="nextWeek" bind:dayClick="dayClick"></weekCalendar>

最后一步是js文件中的数据处理,就是上面界面中的timeBean里面的数据处理,注释非常详尽

// pages/recipe/recipelist/recipelist.js
var util = require("../../../utils/time-utils.js")
Page({

  /**
   * 页面的初始数据
   * selectWeek 0代表的本周  1代表下一周  -1代表上一周   
   * timeBean 传递给组件的数据,数据的格式在一开始的工具类中明确
   */
  data: {
    selectWeek:0,
    timeBean:{},
  },

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

  },
    
  /**
   * 点击了上一周,选择周数字减一,然后直接调用工具类中一个方法获取到数据
   */
  lastWeek:function(e){   
    var selectWeek = --this.data.selectWeek;
    var timeBean = this.data.timeBean
    timeBean = util.getWeekDayList(selectWeek)

    if (selectWeek != 0) {
      timeBean.selectDay = 0;
    }

    this.setData({
      timeBean,
      selectWeek
    })
  },

  /**
   * 点击了下一周,选择周数字加一,然后直接调用工具类中一个方法获取到数据
   */
  nextWeek:function(e){
    var selectWeek = ++this.data.selectWeek;
    var timeBean = this.data.timeBean
    timeBean = util.getWeekDayList(selectWeek)

    if (selectWeek != 0){
      timeBean.selectDay = 0;
    }

    this.setData({
      timeBean,
      selectWeek
    })
  },

  /**
   * 选中了某一日,改变selectDay为选中日
   */ 
  dayClick:function(e){
    var timeBean = this.data.timeBean
    timeBean.selectDay = e.detail;
    this.setData({
      timeBean,
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    this.setData({
      timeBean: util.getWeekDayList(this.data.selectWeek)
    })
  },


})

到此这个组件就可以顺利使用啦。

  • 9
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值