• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前言

接上文:微信小程序开发05-日历组件的实现

github地址:https://github.com/yexiaochai/wxdemo

这里来说一说我们的理念,我们也学习小程序开发有一周多了,从近期的使用上来说,小程序可以作为底层,但是缺少一个框架层,这个框架层需要提供:

① 组件库

② 更好的代码组织方式,也就是让我们可以做到轻松的组件化开发

我们从最开始到现在,都在沿着这个方向去分解小程序学习,其实小程序本身的东西差不多了,但是我们代码过程中有时候却越高越复杂,多了很多封装,其实这所有的复杂都是为了设置一个基本的架构,一个标准的开发模式,让后面写业务代码的同学能更高效的写代码,经过一年多的发展,事实上这种较为成熟的框架已经有了,比如我们正在使用的:

https://tencent.github.io/wepy/

但是,可以看到小程序基本还是原生JS,这其实是个非常好的学习整理机会,所以我这边一步步和大家对小程序进行了拆分,期望能形成一套还能用的雏形,帮助大家理解,所以我们继续今天的学习吧,为了降低单页面难度,我们将首页进行下改造。

首页

首页做了一点改造,变成了这个样式了:

这里需要三个点击时间点,因为日历组件,我们昨天就做好了,而他这个出发日期事实上就是我们日历组件的selecedDate,处理这块逻辑:

 1 <template name="searchbox">
 2   <view class="c-row search-line" data-flag="start">
 3     <view class="c-span3">
 4       出发</view>
 5     <view class="c-span9 js-start search-line-txt">
 6       请选择出发地</view>
 7   </view>
 8   <view class="c-row search-line" data-flag="arrive">
 9     <view class="c-span3">
10       到达</view>
11     <view class="c-span9 js-arrive search-line-txt">
12       请选择到达地</view>
13   </view>
14   <view class="c-row search-line" data-flag="arrive">
15     <view class="c-span3">
16       出发日期</view>
17     <view class="c-span9 js-arrive search-line-txt">
18       {{calendarSelectedDate || \'请选择出发日期\'}} </view>
19   </view>
20   <view class="c-row " data-flag="arrive">
21     <span class="btn-primary full-width js_search_list">查询</span>
22   </view>
23 </template>
View Code
1 <view class="c-row search-line" data-flag="arrive">
2   <view class="c-span3">
3     出发日期</view>
4   <view class="c-span9 js-arrive search-line-txt">
5     {{calendarSelectedDate || \'请选择出发日期\'}} </view>
6 </view>

点击时候我们弹出我们的日历,这个时候我们日历模块释放一个事件显示日历:

PS:template不与页面级别WXML共享一个作用域,所以我暂时都采用的include引入

 1 <view class="c-row search-line" data-flag="start">
 2   <view class="c-span3">
 3     出发</view>
 4   <view class="c-span9 js-start search-line-txt">
 5     请选择出发地</view>
 6 </view>
 7 <view class="c-row search-line" data-flag="arrive">
 8   <view class="c-span3">
 9     到达</view>
10   <view class="c-span9 js-arrive search-line-txt">
11     请选择到达地</view>
12 </view>
13 <view class="c-row search-line" data-flag="arrive" ontap="showCalendar">
14   <view class="c-span3">
15     出发日期</view>
16   <view class="c-span9 js-arrive search-line-txt">
17     {{calendarSelectedDateStr}}</view>
18 </view>
19 <view class="c-row " data-flag="arrive">
20   <span class="btn-primary full-width js_search_list">查询</span>
21 </view>
22 <include src="./mod/calendar.wxml" />
23 <include src="../../utils/abstract-page.wxml" />
View Code
1 <view class="c-row search-line" data-flag="arrive" ontap="showCalendar">
2   <view class="c-span3">
3     出发日期</view>
4   <view class="c-span9 js-arrive search-line-txt">
5     {{calendarSelectedDateStr}}</view>
6 </view>
 1 /*
 2 事实上一个mod就只是一个对象,只不过为了方便拆分,将对象分拆成一个个的mod
 3 一个mod对应一个wxml,但是共享外部的css,暂时如此设计
 4 所有日历模块的需求全部再此实现
 5 */
 6 const util = require(\'../../../utils/util.js\')
 7 
 8 let selectedDate = new Date();
 9 
10 module.exports = {
11   showCalendar: function () {
12     this.setData({
13       isCalendarShow: \'\'
14     });
15   },
16   onCalendarDayTap: function (e) {
17     let data = e.detail;
18     var date = new Date(data.year, data.month, data.day);
19     console.log(date)
20     this.setData({
21       calendarSelectedDate: date,
22       calendarSelectedDateStr: util.dateUtil.format(date, \'Y年M月D日\')
23     });
24   },
25   data: {
26     isCalendarShow: \'none\',
27     calendarDisplayMonthNum: 2,
28     calendarDisplayTime: new Date(),
29     calendarSelectedDate: selectedDate,
30     calendarSelectedDateStr: util.dateUtil.format(selectedDate, \'Y年M月D日\')
31   }
32 }

显然,这里的日历这样摆设有点丑,我们这里将其封装成一个弹出层,所以我们这里再做一个容器类组件,专门用于装载页面样式用:

1 <view class="cm-modal " style="z-index: {{uiIndex}}; position: fixed; display: {{isShow}}; ">
2   <slot ></slot>
3 </view>
4 <view class="cm-overlay" bindtap="onMaskEvent" style="z-index: {{maskzIndex}}; display: {{isShow}}" >
5 </view>
1 <ui-container bindonContainerHide="onContainerHide" is-show="{{isCalendarShow}}" >
2     <view class="calendar-wrapper-box">
3       <view class="box-hd">
4         <text class="fl icon-back js_back "></text>
5         <text class="fr icon-next js_next"></text>
6       </view>
7       <ui-calendar bindonDayTap="onCalendarDayTap" displayTime="{{calendarDisplayTime}}" 
selectedDate
="{{calendarSelectedDate}}" displayMonthNum="{{calendarDisplayMonthNum}}"
is-show
="{{isCalendarShow}}"></ui-calendar> 8 </view> 9 </ui-container>

但是这里也引起了其他问题,因为引入了shadow-dom概念,我的样式不能重用,组件内部样式与外部是不能通信的,但是这里是页面级别容器,内容的样式肯定是来源页面的,这里没什么问题,所以我们这里显示的是正确的,但是我这里想做一个出格一点的操作,我想用样式将这里日历月标题换个位置:

而日历组件和外部是不能通信的,我们这里该如何处理呢,我这里想了两个方案:

① 设置一个全局使用的组件库样式,让所有组件继承,但是不知道这里对性能是否有影响,因为这样的话体积不会太小

② 小程序设计了可以传入组件的方法,比如我们这里的日历组件我们可以这样改变其样式

1 .calendar-cm-month {
2     position: absolute;
3     top: 0;
4     height: 90rpx;
5     line-height: 90rpx;
6     width: 100%;
7     color: #00b358;
8     text-align: center;
9 }
 1 Component({
 2   externalClasses: [\'ex-class\'],
 3   behaviors: [
 4     View
 5   ],
 6   properties: {
 7     displayMonthNum: {
 8       type: Number
 9     },
10     displayTime: {
11       type: Date
12     },
13     selectedDate: {
14       type: Date
15     }
16   },
17   data: {
18     weekDayArr: [\'日\', \'一\', \'二\', \'三\', \'四\', \'五\', \'六\'],
19   },
20 
21   attached: function () { 
22     //console.log(this)
23     // debugger
24   },
25   methods: {
26     onDayTap: function (e) {
27       this.triggerEvent(\'onDayTap\', e.currentTarget.dataset)
28     }
29   }
30 })
1 <ui-container bindonContainerHide="onContainerHide" is-show="{{isCalendarShow}}" >
2     <view class="calendar-wrapper-box">
3       <view class="box-hd">
4         <text class="fl icon-back js_back "></text>
5         <text class="fr icon-next js_next"></text>
6       </view>
7       <ui-calendar ex-class="calendar-cm-month" bindonDayTap="onCalendarDayTap" 
displayTime
="{{calendarDisplayTime}}" selectedDate="{{calendarSelectedDate}}"
displayMonthNum
="{{calendarDisplayMonthNum}}" is-show="{{isCalendarShow}}"></ui-calendar> 8 </view> 9 </ui-container>

具体各位去github上查看,总而言之,我们的页面变成了这个样子了:

PS:这里发现一个不知道是不是坑点的点,我们这里属性传递的是一个date对象,但是到了组件层之间变成了对象,不知微信底层做了什么:

calendarDisplayTime: new Date()

好像变成了一个空对象,这里可能发生的情况是,经过传递的日期对象会被某种特殊处理,但是具体发生了什么事情就不知道了,这个却引起了我们不小的麻烦,这里大概去翻开了一下源码:

极有可能,小程序本身就不支持date属性的传递,我们的日历组件能跑起来的原因是什么,我这里都有点疑惑了......

而且就算以对象方式传递到组件的date类型都会变成莫名其妙的东西:

1     ttt: {
2       key: \'date\',
3       value: selectedDate
4     },

这个特性有点令人抓不住头脑了,这里根据探查,很有可能Component将date对象传入WXML解释时候,自动转为了日期字符串了,所以我们这里看上去是对象的东西其实是字符串,这里的建议是:跟组件的date传递,暂时全部使用字符串代替,以免自我麻烦,然后我们先将之前的日历操作全部变成字符串,再为我们的前后按钮加上事件:

 1 module.exports = {
 2   showCalendar: function () {
 3     this.setData({
 4       isCalendarShow: \'\'
 5     });
 6   },
 7   hideCalendar: function () {
 8     this.setData({
 9       isCalendarShow: \'none\'
10     });
11   },
12   preMonth: function () {
13 
14     this.setData({
15       calendarDisplayTime: util.dateUtil.preMonth(this.data.calendarDisplayTime).toString()
16     });
17   },
18   nextMonth: function () {
19     this.setData({
20       calendarDisplayTime: util.dateUtil.nextMonth(this.data.calendarDisplayTime).toString()
21     });
22   },
23   onCalendarDayTap: function (e) {
24     let data = e.detail;
25     var date = new Date(data.year, data.month, data.day);
26     console.log(date)
27     this.setData({
28       isCalendarShow: \'none\',
29       calendarSelectedDate: date.toString(),
30       calendarSelectedDateStr: util.dateUtil.format(date, \'Y年M月D日\')
31     });
32   },
33   onContainerHide: function () {
34     this.hideCalendar();
35   },
36 
37   data: {
38     ttt: {
39       key: \'date\',
40       value: selectedDate
41     },
42     isCalendarShow: \'\',
43     calendarDisplayMonthNum: 1,
44     calendarDisplayTime: new Date(2018, 9).toString(),
45     calendarSelectedDate: selectedDate,
46     calendarSelectedDateStr: util.dateUtil.format(new Date(selectedDate), \'Y年M月D日\')
47   }
48 }

虽然看上去恶心了一点,但是总是不会出什么明显的问题,忍一忍吧......日期部分基本结束了,还有些小的限制没有做上,比如哪些时段能选,哪些不能,这块就有待各位发现吧,我们这里毕竟是学习,做细了很花功夫,我们接下来做出发目的地选择部分。

数据请求

城市列表

城市列表这里看起来需要新开一个页面,但是我这里想做在一个页面中,考虑篇幅,我们使用弹出层容器组件看并且尽量削弱一些特性,几天下来别说写的还有些累......

这个又作为首页的一个模块而存在:

 1 <view style="display: {{isCityShow}}; " class="city-wrapper"  >
 2     <view class="city-list">
 3         <view class="list-name">A</view>
 4         <view class="list-item">成都</view>
 5         <view class="list-item">成都</view>
 6         <view class="list-item">成都</view>
 7         <view class="list-item">成都</view>
 8         <view class="list-item">成都</view>
 9         <view class="list-item">成都</view>
10     </view>
11     <view class="city-list">
12         <view class="list-name">A</view>
13         <view class="list-item">成都</view>
14         <view class="list-item">成都</view>
15         <view class="list-item">成都</view>
16         <view class="list-item">成都</view>
17         <view class="list-item">成都</view>
18         <view class="list-item">成都</view>
19     </view>
20 </view>
 1 /*
 2 事实上一个mod就只是一个对象,只不过为了方便拆分,将对象分拆成一个个的mod
 3 一个mod对应一个wxml,但是共享外部的css,暂时如此设计
 4 所有日历模块的需求全部再此实现
 5 */
 6 const util = require(\'../../../utils/util.js\')
 7 
 8 let selectedDate = new Date().toString();
 9 
10 module.exports = {
11   showCitylist: function (e) {
12     let flag = e.currentTarget.dataset.flag;
13 
14     if(flag === \'start\') {
15 
16     } else {
17 
18     }
19   },
20   //用于设置城市数据
21   setCityData: function (data) {
22 
23   },
24   showCity: function () {
25       this.setData({
26         isCityShow: \'\'
27       });
28   },
29   shideCity: function () {
30     this.setData({
31       isCityShow: \'none\'
32     });
33   },
34   data: {
35     isCityShow: \'\'
36   }
37 }

首页调用代码:

 1 //获取公共ui操作类实例
 2 const _page = require(\'../../utils/abstract-page.js\');
 3 let modCalendar = require(\'./mod/calendar.js\');
 4 let modCity = require(\'./mod/city.js\');
 5 
 6 //获取应用实例
 7 const app = getApp()
 8 
 9 Page(_page.initPage({
10   data: {
11   },
12   // methods: uiUtil.getPageMethods(),
13   methods: {
14   },
15   onShow: function () {
16     global.sss = this;
17     let scope = this;
18   },
19   onLoad: function () {
20     // this.setPageMethods();
21   }
22 }, {
23   modCalendar: modCalendar,
24< 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
微信小程序代码片段发布时间:2022-07-18
下一篇:
微信小程序开发——后端Java(一)发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap