先详细的展示功能图片以及功能说明,以确保大家看到这里能确定功能是否是自己想要的。这是一个可以实现课程表、食谱等一些功能的周日历,并且注意这是一个【组件】,同时我也建议把这种功能写成组件化,方便复用。
具体的功能,我们可以点选日期获得该日期的详细标志,例如我们点了如下图所示的’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 界面
上一周
{{timeBean.yearMonth}}
下一周
{{timeBean.weekDayList[index].week}}
{{timeBean.weekDayList[index].day}}
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事件都是组件中调用调用方的方法呢
最后一步是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)
})
},
})