文章目录

  • 1 前言
  • 2 简介
  • 3 部分实现步骤与代码
    • 3.1 对象方法属性
    • 3.2 箭头函数(Arrow Function)
    • 3.3 日历
  • 4 最后

1 前言

Hi,大家好,学长今天向大家介绍 一个小程序项目

基于微信小程序的备忘录记事助手

大家可用于 毕业设计

2 简介

这次学长给大家介绍的是一个比较简单的小应用事项助手,其实跟事项也不沾多少边,只是作为辅助功能,只有数据的添加和删除,主要内容是日历这块内容。日历组件在web应用中应用非常广泛,插件也非常丰富,但是小程序不支持传统的插件写法,而是以数据驱动内容。

大部分的日历选择器都是差不多的,能显示当前的年份、月份和天数,可以选择某天、某月或者某年,我们可以打开操作系统中自带的日历观察一番。

日历的布局大同小异,本次案例的布局也是中规中矩,比较传统,头部显示当前年份月份,头部的左右个显示一个翻页按钮,跳转到上一月和下一月,下半部分显示当月的天数列表,由于每月的天数可能不一样,列表的格数是固定的,所以当月的天数显示使用高亮,其余的使用偏灰色彩。

实现效果如下

3 部分实现步骤与代码

3.1 对象方法属性

小程序的每一个页面都有一个相对应的js文件,里面必不可少的就是Page函数,Page函数接受的参数是一个对象,我们经常使用的写法就是:

Page({data: {userAvatar: './images/avatar.png',userName: 'Oopsguy'},onLoad: function() {//....},onReady: function() {//....}
});

现在换做ES6的写法,我们可以这样:

Page({data: {userAvatar: './images/avatar.png',userName: 'Oopsguy'},onLoad() {//....},onReady() {//....}
});

我们可以把以前的键值写法省略掉,而且function声明也不需要了。

class关键字用于声明类,constructor是构造函数,static修饰静态方法。不能理解?我们看一下以前的js的简单写法:

class Animal {constructor() {}eat() {}static doSomething(param) {//...}
}module.exports = Animal;var Animal = function() {};Animal.prototype.eat = function() {};Animal.doSomething = function(param) {};module.exports = Animal;let animal = new Animal();
animal.eat();
//静态方法
Animal.doSomething('param');

3.2 箭头函数(Arrow Function)

箭头函数简化了函数的写法,但是还是跟普通的function有区别,主要是在作用域上。

比如我们需要请求网络:

wx.request({url: 'url', header: {'Content-Type': 'application/json'},success: function(res) {console.log(res.data)}
});

用函数还是可以简化一定的代码量

wx.request({url: 'url', header: {'Content-Type': 'application/json'},success: (res) => {console.log(res.data)}
});

注意到那个success指向的回调函数了么,function关键字没了,被醒目的=>符号取代了。看到这里大家是不是认为以后我们写function就用箭头函数代替呢?答案是不一定,而且要非常小心!

function和箭头函数虽然看似一样,只是写法简化了,其实是不一样的,function声明的函数和箭头函数的作用域不同,这是一个不小心就变坑的地方。

Page({data: {windowHeight: 0},onLoad() {let _this = this;wx.getSystemInfo({success: function(res) {_this.setData({windowHeight: res.windowHeight});}});}
});

一般我们获取设备的屏幕高度差不多是这样的步骤,在页面刚加载的onLoad方法中通过wx.getSystemInfoAPI来获取设备的屏幕高度,由于success指向的回调函数作用域跟onLoad不一样,所以我们无法像onLoad函数体中直接写this.setData来设置值。我们可以定义一个临时变量指向this,然后再回调函数中调用。

3.3 日历

建立工程的步骤就不讲了,直接进入主题,应用只有两个页面,一个首页,一个详情页,结构清晰,功能简单。

先来看看首页,日历的wxml结构;

结构分为上中下三部分,header为头部,用于展示翻页按钮和当前日期信息。在.week.row和.body.row元素中展示星期和天数列表,这里的布局采用了比较low的百分比分栏,总共有7栏,100/7哈哈,想高逼格的可以采用css的分栏布局和flex布局。

<view class="og-calendar"><view class="header"><view class="btn month-pre" bindtap="changeDateEvent" data-year="{{data.beforeYear}}" data-month="{{data.beforMonth}}"> <image src="../../images/prepage.png"></image></view><view class="date-info"><picker mode="date" fields="month" value="{{pickerDateValue}}" bindchange="datePickerChangeEvent"><text>{{data.showYear}}年{{data.showMonth > 9 ? data.showMonth : ('0' + data.showMonth)}}月</text></picker></view><view class="btn month-next" bindtap="changeDateEvent" data-year="{{data.afterYear}}" data-month="{{data.afterMonth}}"><image src="../../images/nextpage.png"></image></view></view><view class="week row"><view class="col"><text>一</text></view><view class="col"><text>二</text></view><view class="col"><text>三</text></view><view class="col"><text>四</text></view><view class="col"><text>五</text></view><view class="col"><text>六</text></view><view class="col"><text>日</text></view></view><view class="body row">  <block wx:for="{{data.dates}}" wx:key="_id"><view bindtap="dateClickEvent" data-year="{{item.year}}" data-month="{{item.month}}" data-date="{{item.date}}" class="col {{data.showMonth == item.month ? '' : 'old'}} {{data.currentDate == item.date && data.currentYear==item.year && data.currentMonth == item.month ? 'current' : ''}} {  {item.active ? 'active' : ''}}"><text>{{item.date}}</text></view> </block></view>
</view>

.btn.month-pre和.btn.month-next翻页按钮,都绑定了changeDateEvent的tap事件,各自都用自己的data-year和data-mont属性,这两个属性是临时存值,当点击按钮翻页的时候,我们需要知道当前的年份和日期,以便可以更加方便地翻到上一页或者下一页。

changeDateEvent事件比较简单:

changeDateEvent(e) {const {year, month} = e.currentTarget.dataset;changeDate.call(this, new Date(year, parseInt(month) - 1, 1));
}

点击翻页按钮,根据回调进来的event对象来获取元素上的data-*属性,然后调用changeDate这个方法来更新日历数据,这个方法接收一个Date对象,代表要翻页后的日期。

暂且不关心changeDate具体干了些什么,看看.body.row里有一个循环,每一个元素都绑定了dateClickEvent事件,而且每一个元素都附带了自己所属的年份、月份和天数信息,这些信息是非常有用的,当点击了具体的某一天,可以通过获取元素上的data-*信息来知道我们具体选择的日期。除此之外,元素上的class属性包裹了一长串的判断表达式。这些语句最终的目的是为了给元素动态变更,.old代表当前的日期不是本月日期,因为每一版的日期除了当前月份的日期还可能包含上一月和下一月的部分日期,我们给予它灰色的样式显示,.current代表今天的日期,用实心填充颜色的背景样式修饰,.active即代表着当前选中的日期。

dateClickEvent事件其实也是调用了changeDate事件,本质上也是也是改变日期,额外的工作就是保存选中的日期到selected对象中。

dateClickEvent(e) {const {year, month, date} = e.currentTarget.dataset;const {data} = this.data;let selectDateText = '';data['selected']['year'] = year;data['selected']['month'] = month;data['selected']['date'] = date;this.setData({ data: data });changeDate.call(this, new Date(year, parseInt(month) - 1, date));
}

来看看重中之重的changeDate函数,这个函数的代码比较多,虽然堆砌大量在一个函数中是个不好的习惯,不过里面声明变量和赋值比较多,业务代码比较少:

/*** 变更日期数据* @param {Date} targetDate 当前日期对象*/
function changeDate(targetDate) {let date = targetDate || new Date();let currentDateObj = new Date();let showMonth, //当天显示月份showYear, //当前显示年份showDay, //当前显示星期showDate, //当前显示第几天showMonthFirstDateDay, //当前显示月份第一天的星期showMonthLastDateDay, //当前显示月份最后一天的星期showMonthDateCount; //当前月份的总天数let data = [];showDate = date.getDate();showMonth = date.getMonth() + 1;showYear = date.getFullYear();showDay = date.getDay();showMonthDateCount = new Date(showYear, showMonth, 0).getDate();date.setDate(1);showMonthFirstDateDay = date.getDay(); //当前显示月份第一天的星期date.setDate(showMonthDateCount);showMonthLastDateDay = date.getDay(); //当前显示月份最后一天的星期  let beforeDayCount = 0,beforeYear, //上页月年份beforMonth, //上页月份afterYear, //下页年份afterMonth, //下页月份afterDayCount = 0, //上页显示天数beforeMonthDayCount = 0; //上页月份总天数//上一个月月份beforMonth = showMonth === 1 ? 12 : showMonth - 1;//上一个月年份beforeYear = showMonth === 1 ? showYear - 1 : showYear;//下个月月份afterMonth = showMonth === 12 ? 1 : showMonth + 1;//下个月年份afterYear = showMonth === 12 ? showYear + 1 : showYear;//获取上一页的显示天数if (showMonthFirstDateDay != 0)beforeDayCount = showMonthFirstDateDay - 1;elsebeforeDayCount = 6;//获取下页的显示天数if (showMonthLastDateDay != 0)afterDayCount = 7 - showMonthLastDateDay;elseshowMonthLastDateDay = 0;//如果天数不够6行,则补充完整let tDay = showMonthDateCount + beforeDayCount + afterDayCount;if (tDay <= 35)afterDayCount += (42 - tDay); //6行7列 = 42//虽然翻页了,但是保存用户选中的日期信息是非常有必要的  let selected = this.data.data['selected'] || { year: showYear, month: showMonth, date: showDate };let selectDateText = selected.year + '年' + formatNumber(selected.month) + '月' + formatNumber(selected.date) + '日';data = {currentDate: currentDateObj.getDate(), //当天日期第几天currentYear: currentDateObj.getFullYear(), //当天年份currentDay: currentDateObj.getDay(), //当天星期currentMonth: currentDateObj.getMonth() + 1, //当天月份showMonth: showMonth, //当前显示月份showDate: showDate, //当前显示月份的第几天 showYear: showYear, //当前显示月份的年份beforeYear: beforeYear, //当前页上一页的年份beforMonth: beforMonth, //当前页上一页的月份afterYear: afterYear, //当前页下一页的年份afterMonth: afterMonth, //当前页下一页的月份selected: selected,selectDateText: selectDateText};let dates = [];let _id = 0; //为wx:key指定//上一月的日期if (beforeDayCount > 0) {beforeMonthDayCount = new Date(beforeYear, beforMonth, 0).getDate();for (let fIdx = 0; fIdx < beforeDayCount; fIdx++) {dates.unshift({_id: _id,year: beforeYear,month: beforMonth,date: beforeMonthDayCount - fIdx});_id++;}}//当前月份的日期for (let cIdx = 1; cIdx <= showMonthDateCount; cIdx++) {dates.push({_id: _id,active: (selected['year'] == showYear && selected['month'] == showMonth && selected['date'] == cIdx), //选中状态判断year: showYear,month: showMonth,date: cIdx});_id++;}//下一月的日期if (afterDayCount > 0) {for (let lIdx = 1; lIdx <= afterDayCount; lIdx++) {dates.push({_id: _id,year: afterYear,month: afterMonth,date: lIdx});_id++;}}data.dates = dates;this.setData({ data: data, pickerDateValue: showYear + '-' + showMonth });loadItemListData.call(this);
}

4 最后

【毕业设计】基于微信小程序的备忘录记事助手相关推荐

  1. java计算机毕业设计基于微信小程序的校园外卖订餐系统APP

    项目介绍 网络技术的快速发展给各行各业带来了很大的突破,也给各行各业提供了一种新的管理模块和校园订餐模块,对于校园订餐小程序将是又一个传统管理到智能化信息管理的改革,对于传统的校园订餐管理,所包括的信 ...

  2. java计算机毕业设计基于微信小程序的药店药品销售管理系统APP

    项目介绍 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息.为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代, ...

  3. 计算机毕业设计-基于微信小程序高校学生课堂扫码考勤签到系统-校园考勤打卡签到小程序

    注意:该项目只展示部分功能,如需了解,评论区咨询即可. 本文目录 1.开发环境 2.系统的设计背景 3 各角色功能模块 3.1 用户 3.2 管理员 4 系统页面展示 4.1 学生端功能模块展示 4. ...

  4. 计算机毕业设计-基于微信小程序的大学生心理预约咨询系统-心理测试小程序

    注意:该项目只展示部分功能,如需了解,评论区咨询即可. 本文目录 1.开发环境 2.系统的设计背景 3 各角色功能模块 3.1 学生用户 3.2 心理老师 3.3 管理员 4 系统页面展示 4.1 用 ...

  5. 【附源码】Java计算机毕业设计基于微信小程序停车系统(程序+LW+部署)

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  6. php计算机毕业设计 基于微信小程序的房屋出租租赁 小程序 uniapp

    随着时代的发展,人们对房屋租赁的需求也越来越显得比较重要,在当下很多城市中房价都是比较高的,这就导致很多外来人员需要进行房租的租赁,当前房屋租赁一般都是通过中介的方式来找房和挂牌,这就导致房主和租房的 ...

  7. 毕业设计-基于微信小程序的“安心乘车”服务系统

    目录 前言 课题背景与简介 实现设计思路 一.出租车服务质量投诉现状 二.基于微信小程序的"安心乘车"服务技术原理及运 行模拟 三."安心乘车"服务优势 四.总 ...

  8. 毕业设计-基于微信小程序的课堂考勤管理系统

    目录 前言 课题背景与简介 实现设计思路 一.微信小程序 二.基于微信小程序的课堂管理系统的设计 三.基于微信小程序的课堂管理系统的实现 四.系统测试 五.总结 实现效果样例 更多帮助 前言

  9. 毕业设计-基于微信小程序的签到系统

    目录 前言 课题背景与简介 实现设计思路 一.微信公众号和微信小程序 二.基于微信小程序的签到系统设计 三.签到系统应用流程 实现效果样例 更多帮助 前言

最新文章

  1. Activity的插件化(三)
  2. 中文 Markdown 编写格式规范的命令行工具 lint-md
  3. 把一个目录文件设为临时内存目录文件,以加快读写速度
  4. input文本框设置和移除默认值
  5. MySql 中 case when then else end 的用法
  6. 云将与行业走向深度融合
  7. Java多线程异常处理
  8. 普通索引和唯一索引,难道还分不清
  9. 为什么强烈推荐你使用单表查询?(续篇)
  10. 写给嵌入式方向的某些同学 - 基于WINCE系统的程序开发[不完整版]
  11. Netty ChannelBuffer
  12. 遗传算法的C语言代码
  13. 【推荐】数据治理资料合集
  14. 浅谈制作BIM模型后期展示视频
  15. 关闭 Windows Defender
  16. 720不能建立远程计算机连接,宽带连接错误720:不能建立到远程计算机的连接 正确解决方法...
  17. 虚拟机2003服务器配置教程,虚拟机安装win2003及Ip配置.doc
  18. Placing Lampposts UVA - 10859 放置街灯 树形dp
  19. 详解动态规划算法(Python实现动态规划算法典型例题)
  20. java中cache是什么_java中的cache机制

热门文章

  1. 基于springboot开发项目架构概述
  2. 关于五子棋AI的一点小尝试
  3. deepin显卡驱动管理器在哪_deepin20 安装英伟达闭源驱动的步骤详解
  4. 计算机原始程序,原始程序员竟然是这样写代码的?
  5. 半个月通过软考高级架构师,分享经验
  6. 浅谈SSM框架下实现简单登录界面
  7. GraphPad Prism中的单因素方差分析这样用
  8. Revit软件 | 愁死人,一个误删引发的事故
  9. Zabbix 网络和端口检测
  10. EMS企业微电网能效管理解决方案为工业能效提升行动计划提供助力