你是否纠结过底层业务逻辑(登陆、获取用户信息等)到底是放app.js的onLaunch还是page的onLoad里比较好,或者因为异步问题被迫放在了onload,我们来分析一下优劣
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 分析
onLaunch处理
优点:底层业务逻辑集中并且只需写一次,比较好维护
缺点:目前没有一个理想的方案来解决onLaunch和onLoad的异步问题,包括注册回调、重写onLoad、请求拦截等。
onLoad处理
优点:因为不涉及跨页面通知,因此异步逻辑比较好处理
缺点:每个页面都得写一次底层业务逻辑,非常繁琐,而且既然是公用的底层业务逻辑,分散在每个页面的onLoad里,好像也不大对劲。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 抉择
按照高内聚低耦合的原则,那逻辑和数据放onLaunch里肯定的,不应该和普通page逻辑耦合在一起,通用的数据和逻辑应该在入口去处理,执行一次到处使用,就像vue的main.js一样,会注册一些技术层的基础设施(路由、状态管理等插件),那业务层的基础设施不就是token、用户信息、所在位置等逻辑吗?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 想象中的最佳实践
那我们的目标就是如何满足两者的优点,避免两者的缺点,做到真正的“高内聚低耦合”
1.保持底层业务逻辑写在入口app.js,避免耦合page里的逻辑
2.能在任何page里第一时间拿到globalData数据
3.使用方便,做到在业务开发中无感知,不需要写额外的调用、通知等代码
4.无任何副作用,不会影响其他功能,比如重写阻塞onLoad
5.灵活可配,适用以后此类任何业务
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 梦想成真
先看一段代码 ⬇️
// page.js
export default {
name: 'Home',
onLoadLogin(){
//登录成功(拿到token) && 页面初始化完成
//Tips:适用于某页面发送的请求依赖token的场景
},
onLoadUser(){
//页面初始化完成 && 获取用户信息完成
//Tips:适用于页面初始化时需要用到用户信息去做判断再走页面逻辑的场景
},
onReadyUser(){
//dom渲染完成 && 获取用户信息完成
//Tips:适用于首次进入页面需要在canvas上渲染头像的类似场景
},
onReadyShow(){
//小程序内页面渲染完成 && 页面显示
//Tips:适用于需要获取小程序组件或者dom,并且每次页面显示都会执行的场景
},
}
应该懂什么意思了吧?是不是你理想中的样子,使用起来跟没有似的
⬆️ 这段示例代码满足了上面的第2、3、4条目标
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
再来看一段 ⬇️
// app.js
// 配置自定义钩子,所有钩子都可以随意组合搭配使用,执行机制类似于Promise.all(但不是用Promise实现的)
CustomHook.install({
'Login':{
// 自定义钩子名称、必须大写字母开头
name:'Login',
watchKey: 'token',
onUpdate(token){
//有token则触发此钩子
return !!token;
}
},
'User':{
// 自定义钩子名称
name:'User',
watchKey: 'userInfo',
onUpdate(user){
//获取到userinfo里的userId则触发此钩子
return !!user.userId;
}
}
//依赖globalData中数据
}, globalData)
怎么样,是不是很棒,依赖globalData,名字可配,连触发规则都可配,而且还附加了可随意组合的功能(意外还解决了页面内逻辑执行时机问题,在下篇讲)
⬆️ 这段示例代码满足了上面的第1、5条目标。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
是不是跃跃欲试了,那就赶紧试试,好用回来告诉我! ⬇️(公司内部已接入两年了很稳定)
GitHub:https://github.com/1977474741/spa-custom-hooks
高手
mark下,异步加载确实是日常开发中的一个痛点
打开某些页面的时候,我对用户信息要重新请求接口获取最新的,这个有没有钩子可以做
新建模板里官方就给出了异步处理的方法,在app.js里请求,page.js里拿数据,官方的方法基本上够用了