- 【实战记录】使用新版接口获取手机号过程中,对小程序的基础库版本的了解
描述: 老版文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/deprecatedGetPhoneNumber.html 新版文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html 如题所示,最近项目中对获取手机号的接口进行升级,这里先展示下老版的写法 wxml部分: <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button> js部分: getphonenumber(e) { wx.login({ success (res) { if (res.code) { //发起网络请求 wx.request({ url: 'https://example.com/onLogin', data: { code: res.code }, success (res) { const data = { ..., encryptedData: e.detail.encryptedData, iv: e.detail.iv, sessionKey: res.data.session_key } wx.request({ url: 'https://example.com/getphonenumber', data, success (res) { // todo } }) } }) } } }) } 新版写法: getphonenumber(e) { wx.request({ url: 'https://example.com/getphonenumber', data: { code: e.detail.code }, success (res) { // todo } }) } 分析: 1、如文档所说旧版用户使用不当会存在下图所示问题,本身项目定位也是做自己的产品,也本着长期发展的目标,决定进行此次更新。 [图片] 2、新版代码简洁逻辑清晰,但若在项目中替换的话,还需要考虑到用户版本库使用情况,原因是:从基础库 2.21.2 开始,对获取手机号的接口进行了安全升级,这时需要登录下我们的小程序管理后台,设置-》基本设置-》基础库最低版本设置;查看下当前小程序用户版本库使用的占比情况,如下图所示,由于我们当前的小程序自2.21.3以下没有用户再使用,故直接设置了2.21.2,这样设置后,假设后面有低版本用户访问我们小程序的话,微信侧会提示用户去更新微信版本 [图片] 3、考虑如果其他同学项目发现有部分用户的版本是低于2.21.2的,这时可能就需要做兼容处理了。 小结: 获取手机号虽然api更简洁了,但也注意不能滥用哦~,好吧就到这里了,如有描述的不到位的地方,欢迎大家指正哈~ [图片]
2022-06-05 - 【讨论】关于收回getUserProfile,使用button的开放能力chooseAvatar替换获取头像的思考
背景: 应微信官方通知(https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01?blockType=1),即将收回getUserProfile,并且官方推荐通过使用button的开放能力chooseAvatar来获取头像(https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/userProfile.html),最近项目也在做相应的调整。 问题描述: 由于原有项目中,由于原先获取的微信头像都为正方形,且项目中显示头像的地方都为圆形,如下图1所示。现替换button的开放能力chooseAvata后,如下图2所示,选择”从相册选择“或者”拍照“时,得到的图片为长方形,这样获取到的图片,在项目中对应的头像显示或宽高比失调、或图片显示效果差(即设置image组建mode属性保持宽高比不变时,自动截取的部分图片不是用户想要的那个部分)。 图1:[图片] 图:2 [图片] 需求分析: 基于以上的场景,查阅了图片相关的api,找到了wx.editImage,效果如下图1所示;倘若wx.editImage支持自定义裁剪比例就好了,遗憾的是wx.editImage的入参只有:src,success,fail,complete这四个,如下图2所示;GG,黔驴技穷了,总不能跟产品经理说,微信小程序相关api不支持,不予处理。一个好的api工程师是需要严格要求自己的。 图1:[图片] 图2:[图片] 小结: 作为一个严谨的程序员,希望官方大大能拉我一把,快帮帮孩子吧(wx.editImage,能不能加一些配置项啥的),也欢迎大家一起帮忙分析下,有没有啥其他的解决方案,欢迎留言哦~
2022-05-28 - 【转】重要通知:小程序用户头像昵称获取规则调整公告!!!
通知: 今天刷官方的更新公告,对的,没错,小程序获取用户头像和昵称的接口又双叒叕调整了!!!具体详细请参见https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01?blockType=1 [图片]
2022-05-10 - 【实战记录】h5项目引入fastclick后,点击input框时,要过一会才弹起键盘
背景:在维护一个历史项目时,发现登录页面,在输入手机号,点击input框,发现无法立刻获取焦点,通过查找代码,发现项目中引入了fastclick。 问题描述:FastClick,这个库解决了什么问题? click 300ms延迟:浏览器click会比touch延迟300ms触发 click穿透现象:当两个div同处一个position,上层div绑定touch,下层div绑定click,当上层div触发touch消失后,可能会触发下层div的click事件 既然Fastclick是为了解决这两类问题,其实现原理如下图所示: [图片] 解决方案:[图片]
2022-05-09 - 【转】可以生成体验版小程序码啦
最近突然发现wxacode.getUnlimited可以生成体验版的小程序码了,设置env_version为trial即可,详细可见https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html,扫码进入小程序的场景再也不用等到线上再去验证了~
2022-05-06 - 【分享】关于人脸核身接入流程
第一步:先注册小程序,参考文档https://mp.weixin.qq.com/wxopen/waregister?action=step1 第二步:去腾讯云开通人面核身服务,参考文档https://cloud.tencent.com/document/product/1007/31071#.E6.8E.A5.E5.85.A5.E6.B5.81.E7.A8.8B 第三步:登录小程序后台,开通人脸核身并等待审核 第四步:第二步,第三步审核通过之后,按照第二步中的文档,引入sdk即可 备注:若项目为uniapp,可联系客服进行指导
2022-05-06 - 【实战记录】关于实现聊天室语音播放问题的一次曲线救国的记录
需求背景: 该项目为互联网医院小程序,其中重要的功能为在线问诊,需要建立医患聊天的功能,故本项目集成了融云sdk即时通讯单聊功能。 问题: 接了融云的sdk后,发文字,图片及自定义消息都是那么的丝滑,但在上线阶段,发现微信小程序真机中部分语音播放不了;通过分析定位,发现由于 wx.createInnerAudioContext(),部分语音在ios真机中会报INNERERRCODE:-11800, ERRMSG:这项操作无法完成。通过和融云技术一顿沟通,也在查找社区文档后发现,早在2021年3月份,有人也提了这个问题,也没有找到官方的相关反馈,并且我自己提了bug(https://developers.weixin.qq.com/community/develop/doc/0004224a4c09c0553ddd1c09657800),也没有下文了。没办法,项目上线迫在眉睫,只能换其他技术替代方案了 解决方案: 为兼容wx.createInnerAudioContext()报错,在onError时,保存需要通过uni.getBackgroundAudioManager()来播放的音频列表 this.audio = uni.createInnerAudioContext(); this.audio.src = this.src; this.audio.onPlay(() => { this.audio.isPlaying = true; this.animate = true; this.timer = setInterval(() => { this.animate = false setTimeout(() => { this.animate = true }, 50) }, 1250); this.audio.onStop(() => { this.audio.isPlaying = false; this.animate = false; this.timer && clearInterval(this.timer) }) this.audio.onEnded(() => { this.audio.isPlaying = false; this.animate = false; this.timer && clearInterval(this.timer) }) }) this.audio.onError((err) => { this.$bgAudioList.push({ messageUId: this.messageUId, animate: false, }) // 所有需要通过背景音乐播放的存入全局 this.useBackgroundAudioManager = true; }) this.$audioList.push(this.audio)//所有实例加入全局变量 效果如下: [图片]
2022-05-06 - 【分享】uniapp体验
前言:关于使用uniapp的好处就不必多说了,我自己的话从uniapp面世,也一直在关注。头几年微信,支付宝,抖音等小程序也在高速发展中,多端确实是很头疼的问题。记得早在18年团队中有项目引入了uniapp,但由于当时不支持分包原因,有个业务场景又只需要买单一个即可,这样把所有页面都放到主包内影响性能,无奈只能用微信原生小程序语法。但几年过去,uniapp生态圈日渐成熟,vue语法,双向数据绑定及Option API(computed,watch,filters等)一定程度上提高了开发者的效率,代码撸起来更加happy。 2.创建项目: 我是通过cli脚手架创建的项目,可参考https://uniapp.dcloud.io/quickstart-cli.html 3.安装项目依赖: 安装vuex,axios引入uView库 https://www.uviewui.com/components/install.html最终目录如下: [图片] 4.总结 目前项目只有微信小程序,如需支持h5,支付宝或者抖音小程序,可结合条件编译来做适配https://uniapp.dcloud.io/tutorial/platform.html,好用的东西,不用推广,自然有开发者拥护
2022-05-06 - 【实战记录】关于生成体验版小程序码在使用中容易遇到的问题
背景: 最近在社区中,发现一些帖子关于使用wxacode.getUnlimited时,不能生成体验版小程序码的,也有一些同学在下面回复说:“页面要发布到线上,才能设置体验版”类似这样的话,故在此想再关于生成体验版小程序码,再说明一下 操作说明: 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html 1、首先设置env_version 为 trial [图片] 2、若需生成的小程序码对应的路径,不存在线上版本的话,需要设置check_path为false [图片] 小结: 在该功能还没面世以前,测试过程中,有些需要扫码进入的场景,则必须在线上验证,有bug修改的话,则必须反复发版审核,比较耗时;该功能极大程度提升上线效率。这里也希望同步一下广大同学,可以放心的使用wxacode.getUnlimited来生成体验版小程序码,也没有什么需要页面发布到线上这么一说,撸就完了,有问题先仔细阅读下文档哦~
2022-06-22 - 【实战记录】手撸自定义dialog弹出框动画效果
背景: 最近在使用animate.css,遇到一种场景:A元素消失后,B元素显示,于是代码如下: <!-- A元素 --> <div :class="Show ? 'video-wrapper animate__animated animate__fadeIn': 'video-wrapper animate__animated animate__fadeOut'" v-if="Show"> // todo </div> <!-- B元素 --> <div class="animate__animated animate__fadeInUpBig" v-else> // todo </div> 表现为:A元素页面刚渲染时,动画效果正常,将show设置为false时,B元素动画效果正常;但A元素消失缺没有淡出的效果。 分析: 经过一顿挣扎以后,想起16年刚入门小程序时,当初自己写弹框动画效果与改场景很相似;问题表现为A元素消失动画效果不生效,由于动画效果皆需要一定的延时,这里使用v:if将show改为false时,dom已被销毁,故需要将判断dom显示与隐藏,和判断动画显示与消失的字段需要区分开来。 具体实现: 以手写dialog为例: index.wxml <button catchtap="openDialog">打开弹框</button> <view class="{{ maskShowClass ? 'mask maskShow' : 'mask' }}" wx:if="{{maskShow}}"></view> <view class="{{ dialogShowClass ? 'dialog dialogShow' : 'dialog' }}" wx:if="{{dialogShow}}"> <view class="dialog-title">提示</view> <view class="dialog-content">弹框动画效果演示</view> <view class="dialog-footer"> <view class="dialog-btn">取消</view> <view class="dialog-btn dialog-confirm" catchtap="closeDialog">确认</view> </view> </view> index.wxss .mask{ position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.6); z-index: 1; opacity: 0; transition: opacity 0.3s; } .maskShow{ opacity: 1; } .dialog{ position: fixed; width: 600rpx; bottom: -200rpx; left: 50%; transform: translate(-50%, 50%); transition: bottom 0.3s; z-index: 2; background-color: #fff; border-radius: 8rpx; } .dialogShow{ bottom: 50%; } .dialog-title{ padding: 20rpx; text-align: center; font-size: 32rpx; font-weight: bold; } .dialog-content{ padding: 30rpx 30rpx 50rpx 30rpx; text-align: center; color: #666; } .dialog-footer{ border-top: 1rpx solid #Efefef; display: flex; } .dialog-btn{ flex: 1; text-align: center; padding: 20rpx 0; } .dialog-confirm{ border-left: 1rpx solid #Efefef; color: #07c160; } index.js Page({ data: { maskShowClass: false, maskShow: false, dialogShowClass: false, dialogShow: false }, openDialog() { this.setData({ maskShow: true, dialogShow: true, }, () => { setTimeout(() => { this.setData({ maskShowClass: true, dialogShowClass: true }) }, 300) }) }, closeDialog() { this.setData({ maskShowClass: false, dialogShowClass: false, }, () => { setTimeout(() => { this.setData({ maskShow: false, dialogShow: false }) },300) }) } }) 代码片段:https://developers.weixin.qq.com/s/MS2gvEme71A7 小结: 此篇仅为记录在开发调试某些动画效果时,需考虑动画结束后,再将dom或者小程序节点删除。上面含代码片段,若众佬们有更好建议,欢迎指正~
2022-07-11 - 【实战记录】记录关于手撸tab标签切换效果的代码优化
背景: 这几天做代码review时,发现有同学在实现类似tab标签切换这种效果,通过单独添加一个属性用来控制标签激活态的显示与隐藏,标签切换时,从数据变化到更新视图一定程度上也会更耗性能一些。这样写不是很好,故这里进行优化一下,欲实现效果如下图: [图片] 话不多说,上代码。 旧代码: wxml部分: {{ item.name }} js部分: Page({ data: { list: [{ id: 1, name: '标签一', choosed: true }, { id: 2, name: '标签二', choosed: false }, { id: 3, name: '标签三', choosed: false }, { id: 4, name: '标签四', choosed: false }], }, // 优化前 点击标签事件 chooseTab(e) { const { item } = e.currentTarget.dataset const { list } = this.data list.forEach(v => { v.choosed = v.id === item.id }) this.setData({ list }) }, }) 优化后代码: wxml部分: {{ item.name }} js部分: Page({ data: { listOPT: [{ id: 1, name: '标签一', }, { id: 2, name: '标签二' }, { id: 3, name: '标签三' }, { id: 4, name: '标签四' }], choosedId: 2, // 选中标签id }, // 优化后 点击标签事件 chooseTabOPT(e) { const { index } = e.currentTarget.dataset const { listOPT } = this.data this.setData({ choosedId: listOPT[index].id }) } }) 代码片段:https://developers.weixin.qq.com/s/VxU5I3mr7jBC 总结: 实际项目中有不少类似的ui交互,优化前的方法虽能实现效果,但在一定程度上会更耗性能一些。如后续逻辑需要将选中标签的id传给后端做相关业务,则需要再次循环一遍list,把choosed为true的筛选出来,如此会比较麻烦些。这次就到这里吧,铁子们有更好的实现方式,欢迎在下面回帖哦~
2022-07-27 - 【实战记录】小程序登录态维护的分享
背景: 最近公司有新项目要启动,之前项目在登录的流程中需要用户授权手机号,不符合小程序运营规范,故决定此次进行梳理整改一下登录的相关流程。 分析: 根据官方的示例(https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html),针对C端业务token的管理,输出该流程图,如下所示: [图片] 代码实现: app.js // 登录 login() { return new Promise((resolve, reject) => { const userInfo = wx.getStorageSync('userinfo') if (userInfo) { resolve(userInfo) } else { wx.login({ success: (res) =>{ console.log(res) // 获取业务token,及个人信息接口 setTimeout(() => { const res = { token: "iahsoiyiuaiu798=23492ib2hbjds823sdkajhgkas=", userInfo: { mobile: '18755131234', nickName: 'xxx', imgUrl: 'https:/xxxx' } } wx.setStorageSync('userinfo', res) resolve(res) }, 0) } }) } }) xxx页面.js: const app = getApp() Page({ data: { isBandMobile: false // 是否绑定手机号 }, onLoad() { // 登录 app.login().then(res => { console.log(res) const { userInfo: { mobile } } = res this.setData({ isBandMobile: Boolean(mobile) }) }) }, // 绑定手机号 getPhoneNumber (e) { console.log(e.detail.code) }, // 业务 todo() { // todo }, }) request.js: let isRefreshing = true; let subscribers = []; function onAccessTokenFetched() { subscribers.forEach((callback) => { callback(); }) subscribers = []; } function addSubscriber(callback) { subscribers.push(callback) } export class Http { constructor() {} request({ url, data = {}, method, header, callback = ''} = {}) { let _this = this; return new Promise((resolve, reject) => { wx.request({ url, data, method, header: { Authorization: 'Bearer ' + wx.getStorageSync('userinfo').token }, callback, fail(res) { reject(res) }, complete: res => { if (callback) return callback(res.data); let statusCode = res.statusCode; if (statusCode == 404) { console.log('接口不存在') } else if (statusCode == 401) { // 将需要重新执行的接口缓存到一个队列中 addSubscriber(() => { _this.request({ url, data, method, header, callback: resolve }) }) if (isRefreshing) { refreshToken(url, data).then(() => { // 依次去执行缓存的接口 onAccessTokenFetched(); isRefreshing = true; }) } isRefreshing = false; } else if (statusCode == 200) { resolve(res.data) } else if (statusCode.startsWith('5')) { wx.showModal({ content: '服务器报错,请重试!', showCancel: false }); } } }) }) } } // 获取token const refreshToken = () => { return new Promise((resolve, reject) => { wx.login({ success: (res) =>{ console.log(res) // 获取业务token,及个人信息接口 setTimeout(() => { const res = { token: "iahsoiyiuaiu798=23492ib2hbjds823sdkajhgkas=", userInfo: { mobile: '18755131234', nickName: 'xxx', imgUrl: 'https:/xxxx' } } wx.setStorageSync('userinfo', res) resolve(res) }, 0) } }) }) } 代码片段:https://developers.weixin.qq.com/s/d2uFwHm17mBg 总结: 此流程中主要将获取用户手机号,从登录流程中剥离出去,使得登录流程更加解耦,以用户openid作为唯一标识,将授权手机号后置,当具体某业务中需要用户手机号时,再去获取。根据自己的业务需要,在“个人中心”页面也可以提供修改绑定手机号的入口即可。关于头像和昵称的话,也在个人中心去获取即可。
2022-08-22