大家好,以下是《王者荣耀周边商城》小程序的一些经验总结,也许能帮到你,也许也帮不到,大家看着办哈,因为时间有点早,所以文中有些实现不是最新的,最终请以官方文档说明为准,废话不多说,直接上高清无码大图。
以上截图是之前的版本,中间做了改版,大家可以直接扫码识别体验:
项目结构
我们都知道,小程序有自己的一套实现规范,下面我们看下小程序的项目结构,如下图:
一个入口文件:app.js
一个全局样式:app.wxss
一个全局配置:app.json
页面:pages下,每个页面再按文件夹划分,每个页面4个文件
index.js:实现页面整个生命周期的控制逻辑,置顶显示时的界面交互
index.json:页面配置,一个JSON对象,详细可配置字段见这里
index.wxml:UI结构渲染,可以理解为就是html,主要支持定制标签,更多标签见这里
index.wxss:UI样式渲染,可以理解为就是css,大部分css写法都支持。
当然在4个文件基础之下,还有一些通用的功能组件支撑它们的运行。每一个页面都是这么几个文件组成,非常规范统一,并且每一部分也都限定了内部实现框架和规范,所以在多人协作的时候,产出相对也就比较规范。
注:pages里面还可以再根据模块划分子目录,孙子目录,只需要在app.json里注册时填写路径就行
以上是必须的文件和目录,而实际中我们会增加别的目录,如lib,comm和utils等等目录。
框架设计
Web开发做得多了,你就会发现,大部分工作就是取数据,渲染UI,处理交互这三件事儿,小程序也不例外,所以按照这个框架逻辑,我们基于小程序本身的框架规范又扩展和细化了下,设计了下面的这套可直接应用于项目的开发框架。
下面我们继续详细理一下设计时的一些思路、出发点和具体的实现方式,窥其面更要知其理。
注:这里我没有直接使用第三方的框架,因为我个人觉得要学习一套技术,还是需要从原生的模式开始着手,虽然前期会比较痛苦一点,但是这些付出都是值得的,因为你一旦搞明白了本来的逻辑架构和原理,你会发现什么框架都是信手拈来,而且你也更能理解框架这样设计的优点和缺点。
工具类库
Ajax
实现了promise的封装,支持GET POST PUT和DELETE,这里设计的时候就确定为仅满足单项目通用即可,所以实现的时候融入了部分业务层面的逻辑:
接口首次格式化,兼容标准的json和var形式接口(内部有大量var形式的接口)
直接判断返回值在逻辑上是成功还是失败
针对返回未登录的情况,自动跳转登录流程
所以省去了业务调用侧的反复判断处理通用逻辑,使用更简洁。
cache
其实,小程序自带了缓存接口,有同步wx.setStorageSync,异步wx.setStorage的方法,但是实际在使用缓存的场景里,我们一般都是需要设置缓存有效时间的,本cache工具就是对小程序缓存接口的封装,实现了对缓存有效期的支持。
Model实现
model层就不用多说了,主要是把数据处理部分独立出来,便于统一服务和维护,这里重点强调下model内部的实现细节,这里有一个实现技巧可以用在其它别的地方。下面直接上代码部分。
上面的代码我们可以看到几个关键点
1. 把参数处理和返回结果处理拆出来放到单独的处理方法里,方法名称保持统一:formatParams,formatResult
2. 同时最外层定义好默认的formatParams,formatResult,如果不做特殊处理,直接使用默认即可(建议不处理也调用下默认方法,规范流程)
3. 还有一点,model里方法命令有统一规范都是已get,add,update,del开头
这个思路其实可以运用到任何场景,特别是在没有任何限定框架的场景,我们只需要按照这个模式去实现,代码一样很清晰漂亮,比如我后面实现LOL内置竞技场道具商店的时候,就是为了减少不必要的框架冗余代码,就直接徒手写的,同样是拆分为model和view层,然后model按上面的规范实现,代码同样很清晰,强烈建议大家实践下,简单实用。
组件模式
在实现王者周边小程序的时候,官方没有开放自定义组件规范,所以我们还不能按照内置组件的实现方式来实现我们业务侧自定义的组件,但是项目里又有公共组件的需求存在,那我们不管怎样还是需要把组件独立出来,不然重复代码很蛋疼,维护成本也比较高,实际我们这里的组件实现模式还是比较简单粗暴的,我们照样把组件拆分为JS,WXML,WXSS三部分(或者只有一部分也行),然后通过不同的import方式引入到需要使用组件的page里就行。
注:虽然这里没有使用官方的自定义组件规范,但是经过自己实现这个,也能大致了解到官方的自定义组件的实现方式和原理。
JS引入:import 或者 require(建议小程序这里引入都用import,跟wxml和wxss比较统一,我对代码有点小洁癖)
WXML引入:
和标签 WXSS引入:@import
JS模块引入请使用import关键字,而非require,WXML引入模板用
标签,WXSS使用@import语法,三者统一 使用 let 代替var进行变量定义,使用const定义常量,如:let goods = 1,const SEX=’男’
所有方法和变量名称都使用小写camel模式,一般是动词+名词形式,尽量不要超过5个单词,如:getList,setBackImage
所有用到的常量的地方都使用全大写,下划线分隔的形式,如:EGG_CHE
使用this转换的地方,统一使用that,如:let that = this; 尽量使用箭头函数,可保留this指向
所有自定义方法(onLoad,onShow等系统方法除外)必须使用规范注释语法进行注释
在page和model里定义方法的时候,直接使用getList(){} 即可,中间可以不用加function关键字
小程序声明周期函数里(onLoad,onReady,onShow,onHide,onUnload等)不要直接写复杂业务逻辑,复杂业务逻辑独立成方法,这里只负责方法调用。
所有数据处理必须封装到model里面,包括url地址,参数格式化,返回结果格式化都放到model里面,在page里使用的时候,基本不用做过多数据处理,一般都直接setData皆可,model规范请参考前面的说明。
如果1个功能在超过一个地方出现,那请实现为公用组件,组件实现请参考前面的说明。
在WXML模板里,如果同时有2个循环中都使用到了同样的代码片段,请使用template的方式定义,然后直接使用即可,不能重复写.
所有地方都需要有对接口返回空数据的处理,界面上要有相应的提示和引导。
其它的可以定义规范的loading,成功失败提示等,这里不多说了.
组件很多时候也需要处理页面交互,相应事件,而小程序的事件绑定机制决定,事件处理方法必须是挂载到当前page对象下(实际是Page()方法定义的对象,内部引用是this),而组件的实现是单独的文件,不在Page()方法里定义,那怎么办呢?我这边的实现方式是组件初始化的地方,传递当前的page对象(this)给到组件,然后组件内部的接口方法全部一次性extend到page上,同样数据也是这个道理,WXML里面的数据方法只能是data对象,组件里的数据也需要挂载到这个对象上,这里强烈建议把组件内部的数据定义为一个单独的对象挂载到data上,而不要直接挂载,如我们这里的购物车组件,实现就是下面这样:
上面setData的时候,定义了shoppingCart对象,在它里面再定义具体的购物车组件需要的数据变量,而下面Object.assign一句就是把组件的方法挂载到当前使用组件的page上面去。
另外还要注意,在WXML里插入组件模块的时候,template标签的data属性里的名称请使用上面setData的名称,比如购物车这里就是shoppingCart。
请大家现在实现的时候,使用官方标准的自定义组件规范
数据共享
小程序开发也涉及到多页面间数据共享,这里针对不同的场景有几种实现方式:
1、基于页面的数据传递:直接在navigate的url后面增加参数即可,然后在接收的页面onLoad方法里,通过参数(对象)接收即可,如下:
2、基于内存的数据共享:getApp方法,获取全局的App实例对象,可以设置存取这个实例对象属性来实现数据共享,如下:
上面这种方式,适合与启动后的短期数据共享,关闭小程序数据会丢失。
3、基于本地缓存的数据共享:可以使用上面的cache组件,也可以使用原生的缓存接口实现,这种方式是可以在小程序关闭后还存在。
4、基于后台服务的接口缓存:这个不多说,就是保持数据到服务器,多页面通过接口调用。
开发规范
详细的JS实现规范这就不讲了,这里大致列一下我们在开发的时候,我们这边简单定义的一些规范,供大家参考。
经验分享
大家开发前,可以大致浏览下小程序的官方文档,相对比较完善,遇到问题可以先查文档,然后再去小程序社区里搜索相关帖子,一般问题都能解决,下面是我遇到的一些问题和相应的解决方案,也许你也会碰到,仅供参考。
1、setData相关经验
设置多级对象值:this.setData({‘a.b.c.d’:value});
设置可变索引的数组值:
varkey="array["+index+"].text,
data ={key: 'changed data’};
this.setData(data);
2、swiper组件 current 问题
swiper组件切换数据源以后,current属性也需要手动重置,不会默认恢复到第一帧,就可能出现当前current大于新数据源的长度,显示会出问题
3、picker-view 初始值设置无效
picker-view初始化的时候,我们都会设置数据源和初始索引值,结果发现放到一次setData里既然不生效,分成2次setData就可以了,应该是设置数据源的时间点在初始值之后了,因为setData接收的是一个hash对象,而hash对象是没有先后顺序的,所以就可能存在初始值在数据源之前设置了,当然初始值不可能生效。
4、android 兼容性问题
从原理上我们知道,小程序本身还是基于不同的JS容器的执行的,所以由于IOS(jscore)和android(v8)上容器不一致,还是需要小程序开发者自己处理两个平台的兼容性,不过新版的微信升级后,目前ios和android的不一致的兼容性问题已经很少了,不要这里需要理解的是小程序虽然有规范,但是并没有帮我们屏蔽底层的兼容问题,我们自己需要注意。
5、cookie 的问题
我们在开发web页面的时候,肯定会使用到cookie,传递登录信息等,但是小程序本身不支持cookie,所以需要应用到cookie的地方,可以转换为参数,放到请求后面,我们上面的小程序登录态就是放到了请求参数里。
但是在调用wx.request的时候,是可以设置cookie header头的,所以如果后台接口验证的需要cookie支持,可以直接在这里设置即可,但是需要注意:android的版本的小程序会把cookie键名自动改为小写,如果后台是通过大写读取的话,可能就取不到值了,暂时还不确认新版是否已修复这个问题。
6、https 的问题
小程序要求所有请求接口都必须是https的,而且所有的域名都需要在小程序管理后台去添加,如果碰到没有添加的情况,开发调试阶段可以在小程序开发工具的项目一栏下,把下面这句勾选,不过上线之前是一定要添加的,不然会出现本地怎么调都是好的,到了手机上就是不行。
7、关于支付
直接使用微信支付即可,不多讲。
8、关于设计
如果有条件,小程序需要独立的产品设计和规划,照搬App或者H5版本不是最好的方案,因为小程序有自己的一套设计,交互规范,有基于微信的账号体系,消息机制等基础能力,我们都可以充分利用。
写在最后
虽然版本有些老,但是还是希望对大家有些帮助,最后建议,大家如果在开发小程序的过程中遇到问题,可以第一时间在论坛里发帖求助哈,微信官方有开发同学直接回复大家。
赞,很棒的分享。
思想很有价值,要是有相应的源码分享,那就更好了
大佬 有源码研究学习一下吗?
谢谢分享
学习了👍
感谢作者分享
👍
赞一个,继续学习
加个Modal层的确是不错的想法