微信小程序开发05-日历组件的实现
github地址:https://github.com/yexiaochai/wxdemo
我们这里继续实现我们的日历组件,这个日历组件稍微有点特殊,算是相对复杂的组件了,然后一般的日历组件又会有很多的变化,所以我们这里实现最基本的标签即可:
let View = require('behavior-view');
const util = require('../utils/util.js'); // const dateUtil = util.dateUtil; Component({
behaviors: [
View
],
properties: { },
data: {
weekDayArr: ['日', '一', '二', '三', '四', '五', '六'],
displayMonthNum: 1, //当前显示的时间
displayTime: null,
//可以选择的最早时间
startTime: null,
//最晚时间
endTime: null, //当前时间,有时候是读取服务器端
curTime: new Date() }, attached: function () {
//console.log(this)
},
methods: { }
})
<wxs module="dateUtil">
var isDate = function(date) {
return date && date.getMonth;
}; var isLeapYear = function(year) {
//传入为时间格式需要处理
if (isDate(year)) year = year.getFullYear()
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) return true;
return false;
}; var getDaysOfMonth = function(date) {
var month = date.getMonth(); //注意此处月份要加1,所以我们要减一
var year = date.getFullYear();
return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
} var getBeginDayOfMouth = function(date) {
var month = date.getMonth();
var year = date.getFullYear();
var d = getDate(year, month, 1);
return d.getDay();
} var getDisplayInfo = function(date) {
if (!isDate(date)) {
date = getDate(date)
}
var year = date.getFullYear(); var month = date.getMonth();
var d = getDate(year, month); //这个月一共多少天
var days = getDaysOfMonth(d); //这个月是星期几开始的
var beginWeek = getBeginDayOfMouth(d); /*
console.log('info',JSON.stringify( {
year: year,
month: month,
days: days,
beginWeek: beginWeek
}));
*/ return {
year: year,
month: month,
days: days,
beginWeek: beginWeek
}
} module.exports = {
getDipalyInfo: getDisplayInfo
}
</wxs> <view class="cm-calendar">
<view class="cm-calendar-hd ">
<block wx:for="{{weekDayArr}}">
<view class="item">{{item}}</view>
</block>
</view>
<view class="cm-calendar-bd ">
<view class="cm-month ">
</view>
<view class="cm-day-list"> <block wx:for="{{dateUtil.getDipalyInfo(curTime).days + dateUtil.getDipalyInfo(curTime).beginWeek}}" wx:for-index="index"> <view wx:if="{{index < dateUtil.getDipalyInfo(curTime).beginWeek }}" class="item active"></view>
<view wx:else class="item">{{index + 1 - dateUtil.getDipalyInfo(curTime).beginWeek}}</view> </block> <view class=" active cm-item--disabled " data-cndate="" data-date=""> </view>
</view>
</view>
</view>
这个是非常简陋的日历雏形,在代码过程中有以下几点比较痛苦:
① WXML与js间应该只有数据传递,根本不能传递方法,应该是两个webview的通信,而日历组件这里在WXML层由不得不写一点逻辑
② 本来在WXML中写逻辑已经不太对了,而我们引入的WXS,使用与HTML中的js片段也有很大的不同
这些问题,一度让代码变得复杂,而可以看到一个简单的组件,还没有复杂功能,涉及到的文件都太多了,这里是调用层:
<ui-calendar is-show="" ></ui-calendar>
事实上,我们以上数据根本不应该写到data里面,应该属性传递,我们这里先为了简单实现功能,接下来我们继续完善这个组件,具体代码请看git:
这个日历组件应该是在小程序中写的最复杂的组件了,尤其是很多逻辑判断的代码都放在了WXML里面,根据之前的了解,小程序渲染在一个webview中,js逻辑在一个webview中,他这样做的目的可能是想让性能更好,但是我这里代码写起来事实上是有点痛苦的,我们这里开始组装组件,将数据配置放到属性上,开始组装abstract-page,事实上我认为日历这种非全局组件本来不应该放到基类中:
① 因为Component提供的是一个标签,而且涉及的文件很多,加上继承关系很不好管理
② 因为日历组件事实上是一个标签,所以我们会有一个引入的基础WXML,一个使用的js,完全独立一个文件更加复杂
③ 本来小程序或者复杂的页面都应该组件化开发,所以我们简历一个页面级别的组件,分散到对应的页面中
小程序像是给灵活的HTML&JS戴上了枷锁,只允许在其允许的范围灵活,我们这里尝试对页面进行再拆分:
<import src="./mod.searchbox.wxml" />
<view>
<template is="searchbox" />
</view>
<include src="./mod/calendar.wxml"/>
<include src="../../utils/abstract-page.wxml"/>
<ui-calendar displayTime="{{CalendarDisplayTime}}"
selectedDate="{{CalendarSelectedDate}}"
displayMonthNum="{{CalendarDisplayMonthNum}}"
is-show="{{isCalendarShow}}" ></ui-calendar>
/*
事实上一个mod就只是一个对象,只不过为了方便拆分,将对象分拆成一个个的mod
一个mod对应一个wxml,但是共享外部的css,暂时如此设计
所有日历模块的需求全部再此实现
*/
module.exports = {
q: 1,
ddd: function(){}, data: {
isCalendarShow: '',
CalendarDisplayMonthNum: 2,
CalendarDisplayTime: new Date(),
CalendarSelectedDate: null
}
}
核心代码还是在abstract-page里面:
//pageData为页面级别数据,mod为模块数据,要求一定不能重复
initPage(pageData, mod) {
//debugger;
let _pageData = {};
let key, value, k, v; //为页面动态添加操作组件的方法
Object.assign(_pageData, this.getPageFuncs(), pageData); //生成真实的页面数据
_pageData.data = {};
Object.assign(_pageData.data, this.getPageData(), pageData.data || {}); for( key in mod) {
value = mod[key];
for(k in value) {
v = value[k];
if(k === 'data') {
Object.assign(_pageData.data, v);
} else {
_pageData[k] = v;
}
}
} console.log(_pageData);
return _pageData;
}
这里再改造一下,我们基本的日历组件便完成了80%了:
/*
事实上一个mod就只是一个对象,只不过为了方便拆分,将对象分拆成一个个的mod
一个mod对应一个wxml,但是共享外部的css,暂时如此设计
所有日历模块的需求全部再此实现
*/
module.exports = {
q: 1,
ddd: function(){},
onCalendarDayTap: function (e) {
let data = e.detail;
var date = new Date(data.year, data.month, data.day);
console.log(date)
this.setData({
calendarSelectedDate: date
});
},
data: {
isCalendarShow: '',
calendarDisplayMonthNum: 2,
calendarDisplayTime: new Date(),
calendarSelectedDate: null
}
}
至此,我们组件相关课题基本结束,接下来,我们开始我们的业务代码
微信小程序开发05-日历组件的实现的更多相关文章
- 微信小程序开发—快速掌握组件及API的方法
微信小程序框架为开发者提供了一系列的组件和API接口. 组件主要完成小程序的视图部分,例如文字.图片显示.API主要完成逻辑功能,例如网络请求.数据存储.音视频播放控制,以及微信开放的微信登录.微信支 ...
- 微信小程序开发—快速掌握组件及API的方法---转载
微信小程序框架为开发者提供了一系列的组件和API接口. 组件主要完成小程序的视图部分,例如文字.图片显示.API主要完成逻辑功能,例如网络请求.数据存储.音视频播放控制,以及微信开放的微信登录.微信支 ...
- 微信小程序开发 [05] wx.request发送请求和妹纸图
1.wx.request 微信小程序中用于发起网络请求的API就是wx.request了,具体的参数太多,此处就不再一一详举了,基本使用示例如下: wx.request({ url: 'test.ph ...
- 手摸手教你微信小程序开发之自定义组件
前言 相信大家在开发小程序时会遇到某个功能多次使用的情况,比如弹出框.这个时候大家首先想到的是组件化开发,就是把弹出框封装成一个组件,然后哪里使用哪里就调用,对,看来大家都是有思路的人,但是要怎样实现 ...
- 微信小程序开发之日期组件
一: wxml: <view class="navbarlift" style="background:#ffffff;padding:20rpx"> ...
- 微信小程序开发06-一个业务页面的完成
前言 接上文:微信小程序开发05-日历组件的实现 github地址:https://github.com/yexiaochai/wxdemo 这里来说一说我们的理念,我们也学习小程序开发有一周多了,从 ...
- 微信小程序开发03-这是一个组件
编写组件 基本结构 接上文:微信小程序开发02-小程序基本介绍 我们今天先来实现这个弹出层: 之前这个组件是一个容器类组件,弹出层可设置载入的html结构,然后再设置各种事件即可,这种组件有一个特点: ...
- [小程序开发] 微信小程序audio音频播放组件+api_wx.createAudioContext
引言: audio是微信小程序中的音频组件,可以轻松实现小程序中播放/停止音频等自定义动作. 附上微信小程序audio组件的相关属性说明:https://mp.weixin.qq.com/debug/ ...
- 微信小程序开发之模板消息
一.添加模板 登录https://mp.weixin.qq.com获取模板,如果没有合适的模板,可以申请添加新模板,审核通过后可使用,详见模板审核说明 页面的 <form/> 组件,属性r ...
随机推荐
- nsq topic和channel的区别
topic:一个可供订阅的话题.channel:属于topic的下一级,一个topic可以有多个channel.二者关系可以再参考下面两文章:http://www.cnblogs.com/forres ...
- BZOJ_1391_[Ceoi2008]order_最大权闭合子图
BZOJ_1391_[Ceoi2008]order_最大权闭合子图 Description 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可 ...
- ArchLinux 安装五笔输入法
说明 自己的笔记本已经全盘做成了ArchLinux系统了,用着还好,苦于常用的五笔输入法在Arch下有点不太好装,参考wiki弄好了,这里简单记录下 这里使用ibus-rime 原因有二: ibus- ...
- bootstrap小知识
栅格系统 1. row必须放到container和container-fluid里面 2. 你的内容应当放置于"列(column)"内,并且,只有"列(column)&q ...
- 前端笔记之Vue(一)初识SPA和Vue&webpack配置和vue安装&指令
一.单页面应用(SPA) 1.1 C/S到B/S页面架构的转变 C/S:客户端/服务器(Client/Server)架构的软件. C/S 软件的特点: ① 从window桌面双击打开 ② 更新的时候会 ...
- JavaScript使用闭包实现单例模式
闭包是JS的一种特性,其中一点就是:可以将外部函数的变量保存在内存中,利用这一特性,我们可以用来实现类的单例模式. 首先需要了解何为单例模式: 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问 ...
- HWPushDemo【华为推送集成,基于2.6.1.301版本】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个Demo只是记录华为推送的集成,不能运行. 另外,因为可能用到存储权限,所以还需要搭配运行时权限申请功能. 使用步骤 一.项目组 ...
- Bumblebee之负载、限流和故障处理实践
Bumblebee作为标准HTTP 1.1应用协议的网关,它能作为任何基于HTTP 1.1构建Webapi服务的前置网关.以下通过示例讲述如何用Bumblebee来制作一个asp.net core w ...
- EIGRP 基础实验
一.环境准备 1. 软件:GNS3 2. 路由:c7200 二.实验操作 实验要求: 1.掌握EIGRP 的基本配置 2.掌握EIGRP 的通配符掩配置方法 3.掌握EIGRP 的自动汇总特性,理解E ...
- DSAPI 网页获取本地程序登陆用户
这是一个非常简单的示例,在网页或其他平台获取程序中已经登陆的用户,当然也可以是其他信息. 源码 Imports DSAPI.网络.HTTP监听_DSWebAPI Public Class Form1 ...