初衷
- 本人第一次使用uni-app,目标是根据uni-app做一个小程序后台,小程序框架选用uni-app,但是uni-app毕竟是小程序框架,所以不存在vue-router,这种概念,对于全局的封装捉襟见肘,市面上没有太好的方法,基于自身经验,封装出一套自用框架,目前适用于小程序,H5没怎么加适配性代码
- 本篇文章只提关键点和注意事项,其余自行百度搜索哦,本篇以uni-app为基础,使用场景为微信小程序,进行举例
- 框架我提炼出来后放链接,现在先写一篇文章玩玩
项目目录
UI框架选型
可以用其他,因为方便用iconfont
uview
uni-app之我见
生命周期问题
- onLaunch 在众多小程序中都是不支持异步的,简而言之,如果在onLaunch写了异步,会和页面的onLoad有一个顺序问题,onLauch中的异步可能先于页面onLoad执行,也可以晚执行
- uni-app 小程序生命周期页面调用顺序为onLoad,onShow,mounted, 意味着先启动小程序页面本身,再做JS对页面的渲染
分包设计
- 此处根据逻辑设计,因为tabbar页面必须在主包,所以主包放5个页面, 所有其余页面根据功能放分包
特殊的执行环境
- 分热启动冷启动
- 无dom环境,需提前写入view,因为是沙盒环境,浏览器环境的方法统统不支持,Blob,File等都要kao
如何进行底层改造?
小程序需要如下能力
- 权限体系,不同于传统小程序,需要支持对指定页面支持游客模式,对页面进行权限判断
- 页面缓存,第一次进页面调用api 下载图片,再次进入直接调用缓存图片,提高体验
- 页面埋点,页面埋点,在离开时收集所有埋点并统一发送
- 支持对二进制文件上传(小程序无File Blob等API)
基于上述需求,需要一个统一的入口,在进入页面之前(即onLoad)之前提前处理好逻辑,当页面加载完毕,再进行当前页面的接口渲染,比如在onShow进行接口渲染,在onReady拿到缓存的页面图片
在Vue中有vue-router这个功能库,可以在页面进入之前进行功能性判断,而uni-app毕竟是重点在小程序,这方面能力偏弱,但是我们仍可以弯道超车!
页面改造
export default {
}
- Vue中我们经常会这么做,因为return一个全新的页面的页面对象,而且这个页面对象是独一份,页面互不影响,既然是对象,我们可以是否代理生命周期等函数?用call apply? 在进入小程序时先进入我们代理的函数,处理完逻辑之后再对页面进行访问
- 那么我尝试拿到当前页面对象
const miniPage = function(config) {
return new MyPage(config);
};
export default miniPage({
data(){
return{}
}
})
function MyPage(config){
console.log(config)
}
- 在打印的confing中可以看到当前页面的生命周期,直接在页面中用变量缓存生命周期,然后在进行自己的操作,然后释放
- 有几个重点需要注意
- 此处我在重新定义了onLoad ,onShow, 需要在当前页面,定义好onLoad,onShow,哪怕你什么都不做,否则call方法找不到当前页面的方法,会报错
function MyPage(config) {
console.log(config,'----config')
let _this = this;
this.lifetimeBackup = {};
const LIFETIME_EVENTS = ["onLoad", "onShow", "mounted"]; // 这一步的步骤是告诉Vue需要改造哪些生命周期, 并把需要改造的生命周期提前放到lifetimeBackup
LIFETIME_EVENTS.forEach((event) => {
_this.lifetimeBackup[event] = config[event];
config[event] = function() {};
});
config.onLoad = function(options) {
let that = this;
let LIFETIME_EVENTS_COPY=['onLoad','mounted']; // 此处是真实要变更的生命周期,不要在此处加onShow等无意义的生命周期,会导致执行两次生命周期方法
//执行步骤1
init(that).then((res) => {
LIFETIME_EVENTS_COPY.forEach(event => {
_this.lifetimeBackup[event].call(that, options);
config[event] = _this.lifetimeBackup[event];
})
});
};
config.onShow = function(options) {
let that = this;
_this.lifetimeBackup['onShow'].call(that, options);
config['onShow'] = _this.lifetimeBackup['onShow'];
};
config.onHide = function() {};
return config;
}
- 此处我定义了一个init方法,是一个Promise回调,是的,等init方法执行完之后,再恢复页面的生命周期的执行顺序,这时就可以做到 onLaunch->onLoad->onShow 的方法,而当小程序在运行过程中,始终保持执行完init方法再执行页面生命周期的行为,基于此,我们可以赋予小程序更多的功能
底层改造完毕,增强小程序
权限设计和游客模式举例
- 具体直接参照vue-router等设计,在meta加功能点即可
- 设计一个route文件夹,以index.js为总入口,建议以分包为文件名,然后汇总到index
import subPackagesA from './subPackagesA.js'
const base=[{
path:'pages/login/index',
meta:{
isChecking:false,
}
}]
const routes=[
...base,
...subPackagesA,
...subPackagesB
]
export default routes
- 在上面代码步骤1中,有一个init函数,在init执行完毕后才执行onLoad页面方法,此方法应该是一个Promise方法,比如调用接口,执行异步方法时执行完毕后 再进行页面逻辑
- 以login页面为例
- 在此处通过getCurrentPages可以拿到当前路由的路径,路径匹配之后通过数组的find方法找到自己定义的路由里的meta字段,
if(!currRoute.meta.isCheck){
resolve()
}else{
// 执行全局逻辑
getUserInfo().then(res=>{
resolve()
})
}
埋点设计
- 有时候我们觉得小程序需要埋点,产品人员要对业务端小程序功能的使用程度进行调研,对页面和功能点都需要埋点,此时我们可以在onHide做一些操作
- 利用onHide和Store 达到数据的拿取
- 以页面的route为key 维护一个数组,数组匹配后,然后再指定页面的meta字段,比如isCheckPoint,如果满足指定条件就可以在onHide进行埋点的统一收发
还有很多功能可以实现
基于页面增强,其实很多能力都可以迎刃而解,就不一一举例了。。懒
改造的同时需要注意什么
- 毕竟多端适配,还需要很多的特定判断,比如getCurrentPages的route,在H5就不行,需要灵活配置
- easycom这个文件匹配很操蛋,注意分包主包不要重复
结语
小程序我只经历过原生时代,这次uni-app改造 让我感叹有些面试只要uni-app精通实在很low,其实改造前我也没有uni-app的经验,但是我仍然相信一通百通。。更何况是小程序这种轮子货,其实还是要多注意对基础的运用。
|