- 视频号关联小商店/小程序
更新:以下内容适用于微信8.0.6版本前的设备,微信8.0.6版本后的设备详见指引 一、视频号关联商店的作用 [图片][图片] 二、关联条件 「小商店」 当前视频号的超级管理员为小商店的超级管理员当前视频号的超级管理员为小商店的成员「小程序」 当前视频号和小程序的主体一致当前视频号和小程序的超级管理员一致视频号的管理员为小程序的推广者(可在mp后台交易组件模块设置)三、如何上架直播 请完成视频号关联小商店/小程序步骤后,前往查看视频号直播关联小商店/小程序指引 四、视频号关联小商店/小程序步骤的详细说明 [图片][图片] 更多资讯,欢迎到【交流专区】微信小商店主页发帖和寻找答案。
2021-06-11 - Skyline|原生级卡片转场,小程序轻松实现
在上一篇文章《在小程序中实现原生相册》中,我们学习了自定义路由搭配共享元素实现的原生相册效果,共享元素可以让用户在体验小程序时视觉关联性更强。 除了相册实现之外,常见的卡片转场也非常适合。 [图片] ⬆️ 演示效果:默认动画 vs 卡片转场动画 👇 下面我们来看看卡片转场中通过 共享元素 + 自定义路由 来实现无痕跳转。 [图片] 这里的转场稍微有点复杂,涉及到以下 3 个点 旧卡片:图片放大、内容渐隐新页面:按比例放大、页面渐显手势搭配1、旧卡片:图片放大、内容渐隐 在本示例中,列表页采用的是 scroll-view 瀑布流布局的实现。 [图片] 这里我们的共享元素是卡片,即 grid-view 中的内容 card,卡片包括 图片、内容描述。 [图片] 默认情况下,共享元素是整个节点进行飞跃的,由于前后页面的图片元素一致但文本内容不一致, 导致在第一帧或者最后一帧会有跳动的效果。 为了让转场动画更加自然,我们需要在飞跃的过程中渐隐旧卡片的内容描述。 [图片] 在这里,我们需要先用 this.applyAnimatedStyle 来给对应的节点绑定 worklet 驱动动画。 .card_wrap 节点:整个卡片按比例放大.card_desc 节点:内容描述渐隐[图片] 关于动画执行的时机,我们可以通过配置项修改。 immediate:设置是否立即执行驱动动画flush:shareValue 更新时,applyAnimatedStyle 的 updater 函数刷新时机在本例中,需要保证共享元素的图片与目标页面图片位置重叠,所以 flush 设置 sync 在当前时间片刷新。 [图片] 绑定完驱动动画之后,我们需要给共享元素绑定帧回调事件,根据当前动画进度改变共享变量的值来驱动共享动画 [图片] 2、新页面:按比例放大、页面渐显 新页面在路由中的动画,需要在自定义路由中进行配置。关于自定义路由的更多介绍,可参考《小程序页面转场动画》 在路由动画过程中,我们将上一步的共享元素帧回调拿到 begin、end 的值,然后结合动画进度 t 计算得出新页面的位置、缩放比例。 还有根据动画进度,设置页面渐显,与前面的卡片渐隐承接。 [图片] 3、手势搭配 学习过我们前面的文章的同学都知道,自定义路由经常需要结合页面手势,来实现手势返回,关于手势的基础知识可参考《小程序页面转场动画》 [图片] 这里我们希望手势缩小整个当前页面,所以这里手势返回时只在当前页面做手势动画即可。 在页面详情页的最外层,嵌套一个手势组件 pan-gesture-handler,当手势拖动时根据手势的位置改变整个页面(通过 #fake-host 控制)的位置和大小来达到拖动的效果。 [图片] 同样绑定页面驱动动画,通过 applyAnimatedStyle 给 #fake-host 绑定驱动动画,当共享变量 transX、transY 等变化时则自动改变 transform 来驱动 #fake-host 缩小。 [图片] 接着绑定手势事件,根据手势拖动时拿到位置信息改变共享变量 transX、transY 的值。 [图片] 最后我们需要设置背景颜色透明,来达到类似把卡片拖回列表的视觉效果,更好的减少页面切换感~ [图片] 一个自定义路由的页面会有 3 层可以设置到背景色,要做到透明的效果需要将 3 个背景色都设置为透明。更多自定义路由背景色的详情参考官方文档。 [图片] 想要试试卡片转场的无恒效果~扫描 ⬇️ 下方小程序码即可体验。 如果你也想在小程序中实现卡片转场动画,mark 下这个 源码 直接接到到你的小程序吧~ [图片]
2023-08-03 - 微信开放平台第三方代实现小程序业务简述
一、微信公众平台-第三方平台开发(什么是第三方平台) 微信公众平台-第三方平台(简称第三方平台)开放给所有通过开发者资质认证后的开发者使用。在得到公众号或小程序运营者(简称运营者)授权后,第三方平台开发者可以通过调用微信开放平台的接口能力,为公众号或小程序的运营者提供账号申请、小程序创建、技术开发、行业方案、活动营销、插件能力等全方位服务。同一个账号的运营者可以选择多家适合自己的第三方为其提供产品能力或委托运营。 从具体的业务场景上说,第三方平台包括以下场景: 1、提供行业解决方案,整体打包公众号或小程序的产品开发等; 2、行业:提供更加专业的运营能力,精细化运营用户公众号或小程序; 3、功能:对公众平台功能的优化,如专门优化图文消息视觉样式和排版的工具,或专门定制的 CRM 用户管理功能,或功能强大的小程序插件等。 二、第三方平台代实现小程序业务 第三方平台代实现小程序业务,即第三方平台帮助旗下已授权的小程序进行代码管理。和普通的小程序开发流程相比,第三方代实现小程序业务,需要先开发完成小程序模板,再将小程序模板部署到旗下小程序帐号中 三、从0到1代实现小程序业务 3.1 微信开放平台注册与认证 在微信开放平台https://open.weixin.qq.com/ 注册帐号,并在账号中心中,完成认证。 [图片] 3.2 创建第三方平台 1)在“微信开放平台-管理中心-第三方平台”创建第三方平台。 [图片] 2)选择对应的服务商类型进行第三方平台创建。 *定制化开发服务商:指具备完整开发独立小程序或插件,并可以提供后续运营的服务商。定制化服务商,可将自己已经开发出的定制化小程序关联到服务商平台中,生成凭证(票据)填充到小程序代码包中进行关联。平台获取开发关系。 *平台型服务商:平台型服务商可以通过一键授权,获得为商户开发部署小程序的权限,代商户完成小程序的开发部署及上线。 [图片] Step 1 : 基本信息填写 平台名称: 名称尽可能能够和自己的业务方向相似,且不要包含测试等字样。 业务标签:有如下几类,可以按照行业划分,也可以按照功能划分,标签选择自己业务范畴之内的即可。 [图片] 平台简介: 这里将显示在详情页中,一般用户从这里获得对平台的业务认知,建议要合理填写。 官方网站: 此处填写你的官网域名,需要注意的是,此处写的地址必须要和此第三方平台的业务描述相一致。否则在审核的时候会被驳回的。 平台图标: 需要自己制作核实的图标,必须保证是108*108像素,仅支持PNG格式,大小不超过300KB。 Step 2 :选择权限 微信开放平台为第三方平台型服务商提供丰富的权限勾选,服务商自由选择需要的权限,所勾选的权限,将在用户授权页面展示。最终服务商可获得的权限,以授权用户选择的权限为准。关于权限详情,可查询第三方平台权限说明 特别提醒,请勿随意全选所有权限,当选择一些没有用到的权限集时,会在全网发布的自动化测试时触发某些检测,导致不能通过。具体可以细看全网发布接入检测说明 [图片] Step 3 :开发资料填写 [图片] 授权发起页域名: 此处填写的是跳转授权页时所在的域名,比如此处填写 w.example.com ,那么授权页必须从这个域名中打开才能正常显示,否则会出错。这在一定程度上防止了授权信息的盗用和滥授权,一般这里填用户授权可以访问的业务域名。这里不校验https,但是需要保证域名是实名且可以公共访问的。 授权测试公众号列表: 由于在创建后并没有全网发布,需要先行做开发测试,这里就是用于测试的公众号、小程序的原始ID。我们需要找到一个任意主体的小程序用来测试,推荐选择自己的,好在接下来的环节中实践。需要注意的是,在全网发布之前,扫描授权页二维码授权的账号只能在这个列表中选择,列表外的没有办法成功授权! 授权事件接收URL: 此处需要填写一个API地址,开放平台向你发送的所有消息均通过请求此URL来完成。在这个地址请求后,需要程序判定消息的类型以及相应的处理方法。在此实践中,此URL主要用来接收开放平台的验证票据(component_verify_ticket) 信息校验Token和消息加解密Key: 这两个主要用来解密开放平台向接收URL发送的消息,或者加密信息向开放平台发送。token填写任意一个字符串即可,key必须保证长度为43位的字符串,只能是字母和数字。 小程序服务器域名: 在授权过来的小程序中配置的合法域名必须在此设置的列表中,本教程小程序使用云开发作为后端服务,所以此处设置的域名没有用到,在使用传统后端服务模式时,建议填写支持小程序后台服务的域名。 小程序业务域名: 在授权过来的小程序中配置的合法域名必须在此设置的列表中,本教程小程序使用云开发作为后端服务,所以此处设置的域名没有用到,在使用传统后端服务模式时,建议填写支持小程序后台服务的域名。 白名单IP地址: 这两个主要用来解密开放平台向接收URL发送的消息,或者加密信息向开放平台发送。token填写任意一个字符串即可,key必须保证长第三方平台所有的API接口必须在白名单列表中的IP才可以成功响应,一般填写自己服务器的公网IP。 更多信息可查询文档申请资料说明 完成上述【基本信息】、【选择权限】和【开发资料】信息填写后,提交审核即可,审核时间1小时以内。审核成功后,就可以使用相关接口进行对应开发。 3.3 平台型服务商代实现小程序基本流程 3.3.1开发准备 1)配置域名并设定授权事件url 2)创建授权事件接收URL的服务监听 微信开放平台向授权事件url发送相关的开发或通知信息,如验证票据等。开放平台向此URL发送的数据是加密过的,具体遵循消息加解密方案。 3)使用接收到的验证票据(component_verify_ticket)获取令牌 令牌是第三方平台接口的调用凭据,根据官方文档-获取令牌可知,我们需要请求API接口:https://api.weixin.qq.com/cgi-bin/component/api_component_token 在请求时需要提供三个参数:component_appid(第三方平台 appid)、component_appsecret(第三方平台 appsecret)、component_verify_ticket(第二步获取的ticket),其中前两个我们可以在开放平台直接获取。 [图片] 4)使用令牌获取预授权码并拼接用户授权链接 预授权码(pre_auth_code)是第三方平台方实现授权托管的必备信息,每个预授权码有效期为 10 分钟。一般我们获取它用来拼接授权链接并发给用户使用。 5)获取第三方调用令牌 3.3.2 小程序模版开发 平台型服务商需要将现成小程序模板通过接口直接上传部署到用户的小程序账号中。具体操作为我们在第三方平台的控制台中可以添加开发小程序。 [图片]选择自己为管理者的小程序账号。在添加流程中,也是需要验证小程序账号密码并通过管理员微信扫码验证的。(这里是输入谁的小程序账号密码?) [图片] 当添加成功之后,我们便可以在公众平台的设置页中看到如下信息的变化,开发小程序所属账号为我们的第三方平台的账号,此时小程序的代码上传便由第三方平台接管。 [图片] 使用微信开发者工具使用此小程序appid创建或导入项目,效果如下,跟普通开发相比,多了一个平台名 [图片] 当我们上传代码时,会提示上传到第三方平台的草稿箱。 [图片] 当上传之后,我们便可以在第三方平台详情页中看到我们上传的代码。 [图片]我们可以点击右边的按钮,直接将代码直接添加到模板库中,也可以删除。 [图片]添加后在模板库中就会出现模板代码,并附带有模板编号,我们便可以通过对应的API接口直接将此模板小程序上传至指定的授权小程序中了,无需再用开发者工具上传提交。 具体关于模板小程序的细则,可以查看官方文档。其中关于extAppid的开发调试属于小程序开发的范畴知识附加,在这里不详细阐述。 3.3.3 小程序模板部署与发布(提审) 小程序模版开发完成后,可以点击全网发布按钮。 [图片] 在发布前会进行自动化测试检查,在本教程推荐的两个权限集勾选,无其他权限集的状态下,只需要验证票据的推送状态。具体可以细看全网发布接入检测说明。 检测通过后,会进行资质审核。主要检查你的官网描述是否和设置的描述相仿。审核通过后,第三方平台业务即可上线,可向所有符合要求的公众号、小程序进行登录授权。
2021-09-09 - 前端架构之路:小程序 Log 日志
前言 后续我会在 [代码]github[代码] 开放源码,并打包至 [代码]npm[代码] ,开发者后续可自行 [代码]install[代码] 调用。 后续 源码地址 及 npm安装方法 将会在该页面更新。 开放时间基于大家需求而定。 通常情况下,日志系统是开发中重要的一环。 但出于种种原因,在前端开发中做日志打印和上报系统却不常见。 但有些特定情况下,日志系统往往有奇效。 比如一个聊天系统中遇到了以下问题: 语音通话中,用户听不到声音 即时通讯中,部分场景用户反馈,消息发送不出去 即时通讯中, A 回复 B 消息时,偶尔对话框不显示 即时通讯中, A 给 B 连续发送两条消息后, B 接收不到第二条的提示 即时通讯中,发送语音消息发送时,用户以为语音已经发送,但实际上录音还在继续。这时用户以为是网络卡了,最后发现自己和其他人说话的声音被录制进去 但是以上几种错误,在后台接口中并没有体现。再加上部分用户手机型号的问题,导致问题很难被定位。 如果我们这里有 [代码]log[代码] ,我们就能很快定位到出问题的代码。 如果不是代码问题,也更有底气回复用户不是我们系统的问题。 如何使用小程序 Log 日志系统 小程序侧提供了两种小程序 Log 日志接口: LogManager ( 普通日志 ) RealtimeLogManager ( 实时日志 ) 官方并没有介绍两者的具体区别,只是强调了 Realtime 的实时性质。 在我看来他们的最大区别就是: [代码]LogManager[代码] 可以让用户有种心安的感觉,因为 [代码]LogManager[代码] 是用户手动反馈的问题。 [代码]RealtimeLogManager[代码] 则对开发者更友好,可以在用户不知情的情况下收集到问题信息,并在用户无感的情况下对问题进行修复。 LogManager 小程序提供的 [代码]Log[代码] 日志接口,通过 [代码]wx.getLogManager()[代码] 获取实例。 注意: 最多保存5M的日志内容,超过5M后,旧的日志内容会被删除。 对于 小程序 ,用户可以通过使用 [代码]button[代码] 组件的 [代码]open-type="feedback"[代码] 来上传打印的日志。 对于 小游戏 ,用户可以通过使用 [代码]wx.createFeedbackButton[代码] 来创建上传打印的日志的按钮。 开发者可以通过小程序管理后台左侧菜单 反馈管理 页面查看相关打印日志。 创建 LogManager 实例 你可以通过 [代码]wx.getLogManager()[代码] 获取日志实例。 括号中可以传参 [代码]{ level: 0 | 1 }[代码] 来决定是否写入 [代码]Page[代码] 的生命周期函数, [代码]wx[代码] 命名空间下的函数日志。 0: 写入 1: 不写入 [代码]const logger = wx.getLogManager({ level: 0 }) [代码] 使用 LogManager 实例 [代码]const logger = wx.getLogManager({ level: 0 }) logger.log({str: 'hello world'}, 'basic log', 100, [1, 2, 3]) logger.info({str: 'hello world'}, 'info log', 100, [1, 2, 3]) logger.debug({str: 'hello world'}, 'debug log', 100, [1, 2, 3]) logger.warn({str: 'hello world'}, 'warn log', 100, [1, 2, 3]) [代码] 用户反馈上传 LogManager 记录的日志 当日志记录后, 用户可以在小程序的 [代码]profile[代码] 页面,单击 反馈与投诉 ,在点击 功能异常 进行日志上传。 开发者处理用户反馈及和用户沟通 开发者可以在小程序后台 管理 -> 用户反馈 -> 功能异常 查看用户反馈的信息。 开发者可以在 功能 -> 客服 下绑定客服微信,绑定后可以在 48小时 内通过微信和反馈用户沟通。 注:沟通需要用户反馈时勾选:允许开发者在 48 小时内通过客服消息联系我。 RealtimeLogManager 小程序提供的 [代码]实时Log[代码] 日志接口,通过 [代码]wx.getRealtimeLogManager()[代码] 获取实例。 注意: [代码]wx.getRealtimeLogManager()[代码] 基础库 2.7.1 开始支持 官方给出实时日志每条的容量上限是 [代码]5kb[代码] 官方对每条日志的定义:在一个页面 onShow -> onHide 之间,会聚合成一条日志上报 开发者可从小程序管理后台: 开发 -> 运维中心 -> 实时日志 进入小程序端日志查询页面 为了定位问题方便,日志是按页面划分的,某一个页面,在onShow到onHide(切换到其它页面、右上角圆点退到后台)之间打的日志,会聚合成一条日志上报,并且在小程序管理后台上可以根据页面路径搜索出该条日志 创建 RealtimeLogManager 实例 你可以通过 [代码]wx.getRealtimeLogManager()[代码] 获取实时日志实例。 [代码]const logger = wx.getRealtimeLogManager() [代码] 使用 RealtimeLogManager 实例 [代码]const logger = wx.getRealtimeLogManager() logger.debug({str: 'hello world'}, 'debug log', 100, [1, 2, 3]) logger.info({str: 'hello world'}, 'info log', 100, [1, 2, 3]) logger.error({str: 'hello world'}, 'error log', 100, [1, 2, 3]) logger.warn({str: 'hello world'}, 'warn log', 100, [1, 2, 3]) [代码] 查看实时日志 与普通日志不同的是,实时日志不再需要用户反馈,可以直接通过以下方式查看实例。 登录小程序后台 通过路径 开发 -> 开发管理 -> 运维中心 -> 实时日志 查看实时日志 如何搭建小程序 Log 日志系统 上面我们知道了小程序的 [代码]Log[代码] 日志怎么使用,我们当然可以不进行封装直接使用。 但是我们直接使用起来会感觉到十分的别扭,因为这不符合我们程序员单点调用的习惯。 那么接下来让我们对这套 Log 系统进行初步的封装以及全局的方法的日志注入。 后续我会在 github 开放源码,并打包至 npm ,需要的开发者可自行 install 调用。 封装小程序 Log 方法 封装 Log 方法前,我们需要整理该方法需要考虑什么内容: 打印格式:统一打印格式有助于我们更快的定位问题 版本号:方便我们清晰的知道当前用户使用的小程序版本,避免出现旧版本问题在新代码中找不到问题 兼容性:我们需要考虑用户小程序版本不足以支持 [代码]getLogManager[代码] 、 [代码]getRealtimeLogManager[代码] 的情况 类型:我们需要兼容 [代码]debug[代码] 、 [代码]log[代码] 、 [代码]error[代码] 类型的 [代码]log日志[代码] 版本问题 我们需要一个常量用以定义版本号,以便于我们定位出问题的代码版本。 如果遇到版本问题,我们可以更好的引导用户 [代码]const VERSION = "1.0.0" const logger = wx.getLogManager({ level: 0 }) logger.log(VERSION, info) [代码] 打印格式 我们可以通过 [代码][version] file | content[代码] 的统一格式来更快的定位内容。 [代码]const VERSION = "1.0.0" const logger = wx.getLogManager({ level: 0 }) logger.log(`[${VERSION}] ${file} | `, ...args) [代码] 兼容性 我们需要考虑用户小程序版本不足以支持 [代码]getLogManager[代码] 、 [代码]getRealtimeLogManager[代码] 的情况 [代码]const VERSION = "0.0.18"; const canIUseLogManage = wx.canIUse("getLogManager"); const logger = canIUseLogManage ? wx.getLogManager({ level: 0 }) : null; const realtimeLogger = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null; export function RUN(file, ...args) { console.log(`[${VERSION}]`, file, " | ", ...args); if (canIUseLogManage) { logger.log(`[${VERSION}]`, file, " | ", ...args); } realtimeLogger && realtimeLogger.info(`[${VERSION}]`, file, " | ", ...args); } [代码] 类型 我们需要兼容 [代码]debug[代码] 、 [代码]log[代码] 、 [代码]error[代码] 类型的 [代码]log日志[代码] [代码]export function RUN(file, ...args) { ... } export function DEBUG(file, ...args) { ... } export function ERROR(file, ...args) { ... } export function getLogger(fileName) { return { DEBUG: function (...args) { DEBUG(fileName, ...args) }, RUN: function (...args) { RUN(fileName, ...args) }, ERROR: function (...args) { ERROR(fileName, ...args) } } } [代码] 完整代码 以上都做到了,就完成了一套 [代码]Log[代码] 系统的基本封装。 [代码]const VERSION = "0.0.18"; const canIUseLogManage = wx.canIUse("getLogManager"); const logger = canIUseLogManage ? wx.getLogManager({ level: 0 }) : null; const realtimeLogger = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null; export function DEBUG(file, ...args) { console.debug(`[${VERSION}] ${file} | `, ...args); if (canIUseLogManage) { logger.debug(`[${VERSION}]`, file, " | ", ...args); } realtimeLogger && realtimeLogger.info(`[${VERSION}]`, file, " | ", ...args); } export function RUN(file, ...args) { console.log(`[${VERSION}]`, file, " | ", ...args); if (canIUseLogManage) { logger.log(`[${VERSION}]`, file, " | ", ...args); } realtimeLogger && realtimeLogger.info(`[${VERSION}]`, file, " | ", ...args); } export function ERROR(file, ...args) { console.error(`[${VERSION}]`, file, " | ", ...args); if (canIUseLogManage) { logger.error(`[${VERSION}]`, file, " | ", ...args); } realtimeLogger && realtimeLogger.error(`[${VERSION}]`, file, " | ", ...args); } export function getLogger(fileName) { return { DEBUG: function (...args) { DEBUG(fileName, ...args) }, RUN: function (...args) { RUN(fileName, ...args) }, ERROR: function (...args) { ERROR(fileName, ...args) } } } [代码] 全局注入 Log 通过该章节的名称,我们就可以知道全局注入。 全局注入的意思就是,不通过手动调用的形式,在方法写完后自动注入 [代码]log[代码] ,你只需要在更细节的地方考虑打印 [代码]log[代码] 即可。 为什么要全局注入 虽然我们实现了全局 [代码]log[代码] 的封装,但是很多情况下,一些新同学没有好的打 [代码]log[代码] 的习惯,尤其是前端同学(我也一样)。 所以我们需要做一个全局注入,以方便我们的代码书写,也避免掉手动打 [代码]log[代码] 会出现遗漏的问题。 如何进行全局注入 小程序提供了 [代码]behaviors[代码] 参数,用以让多个页面拥有相同的数据字段和方法。 需要注意的是, [代码]page[代码] 级别的 [代码]behaviors[代码] 在 2.9.2 之后开始支持 我们可以通过封装一个通用的 [代码]behaviors[代码] ,然后在需要 [代码]log[代码] 的页面进行引入即可。 [代码]import * as Log from "./log-test"; export default Behavior({ definitionFilter(defFields) { console.log(defFields); Object.keys(defFields.methods || {}).forEach(methodName => { const originMethod = defFields.methods[methodName]; defFields.methods[methodName] = function (ev, ...args) { if (ev && ev.target && ev.currentTarget && ev.currentTarget.dataset) { Log.RUN(defFields.data.PAGE_NAME, `${methodName} invoke, event dataset = `, ev.currentTarget.dataset, "params = ", ...args); } else { Log.RUN(defFields.data.PAGE_NAME, `${methodName} invoke, params = `, ev, ...args); } originMethod.call(this, ev, ...args) } }) } }) [代码] 总结 连着开发带整理,林林总总的也有了 [代码]2000+[代码] 字,耗费了三天的时间,整体感觉还是比较值得的,希望可以带给大家一些帮助。 也希望大家更重视前端的 [代码]log[代码] 一点。这基于我自身的感觉,尤其是移动端用户。 在很多时候由于 手机型号 、 弱网环境 等导致的问题。 在没有 [代码]log[代码] 时,找不到问题的着力点,导致问题难以被及时解决。
2022-01-17 - 小程序app.onLaunch与page.onLoad异步问题的最佳实践
场景: 在小程序中大家应该都有这样的场景,在onLaunch里用wx.login静默登录拿到code,再用code去发送请求获取token、用户信息等,整个过程都是异步的,然后我们在业务页面里onLoad去用的时候异步请求还没回来,导致没拿到想要的数据,以往要么监听是否拿到,要么自己封装一套回调,总之都挺麻烦,每个页面都要写一堆无关当前页面的逻辑。 直接上终极解决方案,公司内部已接入两年很稳定: 1.可完美解决异步问题 2.不污染原生生命周期,与onLoad等钩子共存 3.使用方便 4.可灵活定制异步钩子 5.采用监听模式实现,接入无需修改以前相关逻辑 6.支持各种小程序和vue架构 。。。 //为了简洁明了的展示使用场景,以下有部分是伪代码,请勿直接粘贴使用,具体使用代码看Github文档 //app.js //globalData提出来声明 let globalData = { // 是否已拿到token token: '', // 用户信息 userInfo: { userId: '', head: '' } } //注册自定义钩子 import CustomHook from 'spa-custom-hooks'; 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) // 正常走初始化逻辑 App({ globalData, onLaunch() { //发起异步登录拿token login((token)=>{ this.globalData.token = token //使用token拿用户信息 getUser((user)=>{ this.globalData.user = user }) }) } }) //关键点来了 //Page.js,业务页面使用 Page({ onLoadLogin() { //拿到token啦,可以使用token发起请求了 const token = getApp().globalData.token }, onLoadUser() { //拿到用户信息啦 const userInfo = getApp().globalData.userInfo }, onReadyUser() { //页面初次渲染完毕 && 拿到用户信息,可以把头像渲染在canvas上面啦 const userInfo = getApp().globalData.userInfo // 获取canvas上下文 const ctx = getCanvasContext2d() ctx.drawImage(userInfo.head,0,0,100,100) }, onShowUser() { //页面每次显示 && 拿到用户信息,我要在页面每次显示的时候根据userInfo走不同的逻辑 const userInfo = getApp().globalData.userInfo switch(userInfo.sex){ case 0: // 走女生逻辑 break case 1: // 走男生逻辑 break } } }) 具体文档和Demo见↓ Github:https://github.com/1977474741/spa-custom-hooks 祝大家用的愉快,记得star哦
2023-04-23