0

    微信小程序开发(5):日历组件的实现

    2023.08.06 | admin | 126次围观

    接上文:

    github地址:

    我们这里继续实现我们的日历组件,这个日历组件稍微有点特殊,算是相对复杂的组件了,然后一般的日历组件又会有很多的变化微信小程序组件传值,所以我们这里实现最基本的标签即可:

    let View = require('behavior-view');

    constutil = require('../utils/util.js');

    // const dateUtil = util.dateUtil;

    Component({

    behaviors: [

    View

    ],

    properties: {

    },

    data: {

    weekDayArr: ['日','一','二','三','四','五','六'],

    displayMonthNum: 1,

    //当前显示的时间

    displayTime: null,

    //可以选择的最早时间

    startTime: null,

    //最晚时间

    endTime: null,

    //当前时间,有时候是读取服务器端

    curTime: newDate()

    },

    attached: function(){

    //console.log(this)

    },

    methods: {

    })

    varisDate = function(date){

    returndate && date.getMonth;

    };

    varisLeapYear = function(year){

    //传入为时间格式需要处理

    if(isDate(year))year = year.getFullYear()

    if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))returntrue;

    returnfalse;

    };

    vargetDaysOfMonth = function(date){

    varmonth = date.getMonth();//注意此处月份要加1,所以我们要减一

    varyear = date.getFullYear();

    return[31,isLeapYear(year)?29 : 28,31,30,31,30,31,31,30,31,30,31][month];

    vargetBeginDayOfMouth = function(date){

    varmonth = date.getMonth();

    varyear = date.getFullYear();

    vard = getDate(year,month,1);

    returnd.getDay();

    vargetDisplayInfo = function(date){

    if(!isDate(date)){

    date = getDate(date)

    varyear = date.getFullYear();

    varmonth = date.getMonth();

    vard = getDate(year,month);

    //这个月一共多少天

    vardays = getDaysOfMonth(d);

    //这个月是星期几开始的

    varbeginWeek = 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

    {{item}}

    {{index + 1 - dateUtil.getDipalyInfo(curTime).beginWeek}}

    这个是非常简陋的日历雏形,在代码过程中有以下几点比较痛苦:

    ① WXML与js间应该只有数据传递,根本不能传递方法,应该是两个webview的通信微信小程序组件传值,而日历组件这里在WXML层由不得不写一点逻辑

    ② 本来在WXML中写逻辑已经不太对了,而我们引入的WXS,使用与HTML中的js片段也有很大的不同

    这些问题,一度让代码变得复杂,而可以看到一个简单的组件,还没有复杂功能,涉及到的文件都太多了,这里是调用层:

    事实上,我们以上数据根本不应该写到data里面,应该属性传递,我们这里先为了简单实现功能,接下来我们继续完善这个组件,具体代码请看git:

    这个日历组件应该是在小程序中写的最复杂的组件了,尤其是很多逻辑判断的代码都放在了WXML里面,根据之前的了解,小程序渲染在一个webview中,js逻辑在一个webview中,他这样做的目的可能是想让性能更好,但是我这里代码写起来事实上是有点痛苦的,我们这里开始组装组件,将数据配置放到属性上,开始组装abstract-page,事实上我认为日历这种非全局组件本来不应该放到基类中:

    ① 因为Component提供的是一个标签,而且涉及的文件很多,加上继承关系很不好管理

    ② 因为日历组件事实上是一个标签,所以我们会有一个引入的基础WXML,一个使用的js,完全独立一个文件更加复杂

    ③ 本来小程序或者复杂的页面都应该组件化开发,所以我们简历一个页面级别的组件,分散到对应的页面中

    小程序像是给灵活的HTML&JS戴上了枷锁,只允许在其允许的范围灵活,我们这里尝试对页面进行再拆分:

    /*

    事实上一个mod就只是一个对象,只不过为了方便拆分,将对象分拆成一个个的mod

    一个mod对应一个wxml,但是共享外部的css,暂时如此设计

    所有日历模块的需求全部再此实现

    */

    module.exports = {

    q: 1,

    ddd: function(){},

    data: {

    isCalendarShow: '',

    CalendarDisplayMonthNum: 2,

    CalendarDisplayTime: newDate(),

    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 inmod){

    value = mod[key];

    for(kinvalue){

    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;

    vardate = newDate(data.year,data.month,data.day);

    console.log(date)

    this.setData({

    calendarSelectedDate: date

    });

    },

    data: {

    isCalendarShow: '',

    calendarDisplayMonthNum: 2,

    calendarDisplayTime: newDate(),

    calendarSelectedDate: null

    至此,我们组件相关课题基本结束,接下来,我们开始我们的业务代码

    【关于投稿】

    如果大家有原创好文投稿,请直接给公号发送留言。

    ①留言格式:

    【投稿】+《文章标题》+文章链接

    ②示例:

    【投稿】《不要自称是程序员,我十多年的IT职场总结》:

    ③最后请附上您的个人简介哈~

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论