接上文:微信小程序开发04-打造自己的UI库

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-日历组件的实现的更多相关文章

  1. 微信小程序开发—快速掌握组件及API的方法

    微信小程序框架为开发者提供了一系列的组件和API接口. 组件主要完成小程序的视图部分,例如文字.图片显示.API主要完成逻辑功能,例如网络请求.数据存储.音视频播放控制,以及微信开放的微信登录.微信支 ...

  2. 微信小程序开发—快速掌握组件及API的方法---转载

    微信小程序框架为开发者提供了一系列的组件和API接口. 组件主要完成小程序的视图部分,例如文字.图片显示.API主要完成逻辑功能,例如网络请求.数据存储.音视频播放控制,以及微信开放的微信登录.微信支 ...

  3. 微信小程序开发 [05] wx.request发送请求和妹纸图

    1.wx.request 微信小程序中用于发起网络请求的API就是wx.request了,具体的参数太多,此处就不再一一详举了,基本使用示例如下: wx.request({ url: 'test.ph ...

  4. 手摸手教你微信小程序开发之自定义组件

    前言 相信大家在开发小程序时会遇到某个功能多次使用的情况,比如弹出框.这个时候大家首先想到的是组件化开发,就是把弹出框封装成一个组件,然后哪里使用哪里就调用,对,看来大家都是有思路的人,但是要怎样实现 ...

  5. 微信小程序开发之日期组件

    一: wxml: <view class="navbarlift" style="background:#ffffff;padding:20rpx"> ...

  6. 微信小程序开发06-一个业务页面的完成

    前言 接上文:微信小程序开发05-日历组件的实现 github地址:https://github.com/yexiaochai/wxdemo 这里来说一说我们的理念,我们也学习小程序开发有一周多了,从 ...

  7. 微信小程序开发03-这是一个组件

    编写组件 基本结构 接上文:微信小程序开发02-小程序基本介绍 我们今天先来实现这个弹出层: 之前这个组件是一个容器类组件,弹出层可设置载入的html结构,然后再设置各种事件即可,这种组件有一个特点: ...

  8. [小程序开发] 微信小程序audio音频播放组件+api_wx.createAudioContext

    引言: audio是微信小程序中的音频组件,可以轻松实现小程序中播放/停止音频等自定义动作. 附上微信小程序audio组件的相关属性说明:https://mp.weixin.qq.com/debug/ ...

  9. 微信小程序开发之模板消息

    一.添加模板 登录https://mp.weixin.qq.com获取模板,如果没有合适的模板,可以申请添加新模板,审核通过后可使用,详见模板审核说明 页面的 <form/> 组件,属性r ...

随机推荐

  1. Instrumentation(1)

    Instrumentation介绍: JavaInstrumentation指的是可以用独立于应用程序之外的代理(agent)程序来监测和协助运行在JVM上的应用程序.这种监测和协助包括但不限于获取J ...

  2. CAD中用户选择实体

    在CAD的很多操作中都会有需要用户选择实体的时候,这里将我最近项目中用到的方法分享一下,程序原意是希望用户选择一个单行文本或者多行文本,并返回所选文本的内容,直接上代码: CString CPaint ...

  3. 说说 input 输入框的事件

    从input框获取焦点到,输入值,失去焦点这个过程所有事件,以及一些特点: 1.过程 onfocus -> 键盘输入 -> onkeydown -> onkeypress -> ...

  4. vue中引入babel步骤

    vue中引入babel步骤 vue项目中普遍使用es6语法,但有时我们的项目需要兼容低版本浏览器,这时就需要引入babel插件,将es6转成es5. 1.安装babel-polyfill插件 npm ...

  5. Springcloud Gateway 路由管理

    Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开 ...

  6. CSharpGL(53)漫反射辐照度

    CSharpGL(53)漫反射辐照度 本系列将通过翻译(https://learnopengl.com)这个网站上关于PBR的内容来学习PBR(Physically Based Rendering). ...

  7. 8天入门docker系列 —— 第三天 使用aspnetcore小案例熟悉对镜像的操控

    上一篇我们聊到了容器,现在大家应该也知道了,没有镜像就没有容器,所以镜像对docker来说是非常重要的,关于镜像的特性和原理作为入门系列就不阐 述了,我还是通过aspnetcore的小sample去熟 ...

  8. DS控件库 Win7链接列表框的仿Windows开始菜单样式

    Win7链接列表框是依照Windows7的开始菜单开发的,同时进行了属性和功能的扩展. 效果图 项属性 控件属性 控件主要事件 点击项(Sender As Win7链接列表框, Itm As 链接项, ...

  9. 适配器模式(Adapter Pattern)

    适配器模式概述 定义:将一个类的接口转化成客户希望的另一个接口,适配器模式让那些接口不兼容的类可以一起工作.别名(包装器[Wrapper]模式) 它属于创建型模式的成员,何为创建型模式:就是关注如何将 ...

  10. 设计模式之Singleton模式和Strategy模式是什么

    Singleton模式 单例模式,也交单子模式,有时候系统只需要拥有一个全局对象. 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问其唯一的对象的方 ...