个人案例
店小two
一个方便老板管理店铺,方便会员消费的小程序
店小two扫码体验
- wx.updateTimelineShareData 提示ok,但是没有唤起朋友圈的功能
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
2023-01-29 - webView报错the permission value is offline verifying
the permission value is offline verifying这个错误是因为config没有正确执行,或者是调用的JSAPI没有传入config的jsApiList参数中。建议按如下顺序检查: 确认config正确通过。 如果是在页面加载好时就调用了JSAPI,则必须写在wx.ready的回调中。 确认config的jsApiList参数包含了这个JSAPI。 可参考:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#%E9%99%84%E5%BD%951-JS-SDK%E4%BD%BF%E7%94%A8%E6%9D%83%E9%99%90%E7%AD%BE%E5%90%8D%E7%AE%97%E6%B3%95
2019-09-24 - wx.getPrivacySetting接口needAuthorization一直返回false
wx.getPrivacySetting接口needAuthorization一直返回false,privacyContractName字段未返回。 在基础库2.33.0和3.0.0上都存在。 在微信-设置中取消授权后(如摄像头等),needAuthorization依然是false。
2023-08-15 - 微信小程序中安全区域计算和适配
前言 自从iphoneX问世之后,因为iphoneX、iphoneXR和后续全面屏手机设备,因为物理Home键被底部小黑条代替了,这时候很多前端小伙伴在开发的过程都会遇到 “全面屏”和“非全面屏”的兼容性问题,普遍问题就是底部按钮或者选项卡与底部黑线重叠 解释 根据官方解释: 安全区域指的是一个可视窗口范围,处于安全区域的内容不受圆角(corners)、齐刘海(sensor housing)、小黑条(Home Indicator)的影响。 具体区域如图展示 [图片] 适配方案 当前有效的解决方式有几种 使用已知底部小黑条高度34px/68rpx来适配 使用苹果官方推出的css函数env()、constant()适配 使用微信官方API,getSystemInfo()中的safeArea对象进行适配 使用已知底部小黑条高度34px/68rpx来适配 这种方式是根据实践得出,通过物理方式测出iPhone底部的小黑条(Home Indicator)高度是34px,实际在开发者工具选中真机获取到高度也是34px,所以直接根据该值,设置margin-bottom、padding-bottom、height也能实现。同时这样做要有一个前提,需要判断当前机型是需要适配安全区域的机型。 但是这种方案相对来说是不推荐使用的。比较是一个比较古老原始的方案 使用苹果官方推出的css函数env()、constant()适配 这种方案是苹果官方推荐使用env(),constant()来适配,开发者不需要管数值具体是多少。 env和constant是IOS11新增特性,有4个预定义变量: safe-area-inset-left:安全区域距离左边边界的距离 safe-area-inset-right:安全区域距离右边边界的距离 safe-area-inset-top:安全区域距离顶部边界的距离 safe-area-inset-bottom :安全距离底部边界的距离 具体用法如下: Tips: constant和env不能调换位置 [代码] padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/ padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/ [代码] 其实利用这个能解决大部分的适配场景了,但是有时候开发需要自定义头部信息,这时候就没办法使用css来解决了 使用微信官方API,getSystemInfo()中的safeArea对象进行适配 通过 wx.getSystemInfo获取到各种安全区域信息,解析出具体的设备类型,通过设备类型做宽高自适应,话不多说,直接上代码 代码实现 [代码] const res = wx.getSystemInfoSync() const result = { ...res, bottomSafeHeight: 0, isIphoneX: false, isMi: false, isIphone: false, isIpad: false, isIOS: false, isHeightPhone: false, } const modelmes = result.model const system = result.system // 判断设备型号 if (modelmes.search('iPhone X') != -1 || modelmes.search('iPhone 11') != -1) { result.isIphoneX = true; } if (modelmes.search('MI') != -1) { result.isMi = true; } if (modelmes.search('iPhone') != -1) { result.isIphone = true; } if (modelmes.search('iPad') > -1) { result.isIpad = true; } let screenWidth = result.screenWidth let screenHeight = result.screenHeight // 宽高比自适应 screenWidth = Math.min(screenWidth, screenHeight) screenHeight = Math.max(screenWidth, screenHeight) const ipadDiff = Math.abs(screenHeight / screenWidth - 1.33333) if (ipadDiff < 0.01) { result.isIpad = true } if (result.isIphone || system.indexOf('iOS') > -1) { result.isIOS = true } const myCanvasWidth = (640 / 375) * result.screenWidth const myCanvasHeight = (1000 / 667) * result.screenHeight const scale = myCanvasWidth / myCanvasHeight if (scale < 0.64) { result.isHeightPhone = true } result.navHeight = result.statusBarHeight + 46 result.pageWidth = result.windowWidth result.pageHeight = result.windowHeight - result.navHeight if (!result.isIOS) { result.bottomSafeHeight = 0 } const capsuleInfo = wx.getMenuButtonBoundingClientRect() // 胶囊热区 = 胶囊和状态栏之间的留白 * 2 (保持胶囊和状态栏上下留白一致) * 2(设计上为了更好看) + 胶囊高度 const navbarHeight = (capsuleInfo.top - result.statusBarHeight) * 4 + capsuleInfo.height // 写入胶囊数据 result.capsuleInfo = capsuleInfo; // 安全区域 const safeArea = result.safeArea // 可视区域高度 - 适配横竖屏场景 const screenHeight = Math.max(result.screenHeight, result.screenWidth) const height = Math.max(safeArea.height, safeArea.width) // 状态栏高度 const statusBarHeight = result.statusBarHeight // 获取底部安全区域高度(全面屏手机) if (safeArea && height && screenHeight) { result.bottomSafeHeight = screenHeight - height - statusBarHeight if (result.bottomSafeHeight < 0) { result.bottomSafeHeight = 0 } } // 设置header高度 result.headerHeight = statusBarHeight + navbarHeight // 导航栏高度 result.navbarHeight = navbarHeight [代码]
2022-11-04 - 使用van-circle组件,模拟器显示没问题,到了真机上样式显示不出来,需要刷新,怎么办?
[图片][图片]
2023-01-13 - rich-text组件 中富文本框图片不能自适应?
[图片] 用了标签 rich-text 但是图片 莫名超过去,不会自适应,请问大佬们怎么结局
2022-09-07 - 小程序EventChannel的一些理解和使用实践
EventChannel是什么通过官方文档和示例,实际可以发现EventChannel借助wx.navigateTo方法,在两个页面之间构建起了数据通道,互相可以通过“派发事件”及“注册这些事件的监听器”来实现基于事件的页面通信。 具体看下下面的官方示例: wx.navigateTo({ url: 'test?id=1', events: { // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据 acceptDataFromOpenedPage: function(data) { console.log(data) }, someEvent: function(data) { console.log(data) } ... }, success: function(res) { // 通过 eventChannel 向被打开页面传送数据 res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' }) } }) events: 注册将在目标页面触发(派发)的同名事件的监听器 success:跳转后进行可通过res.eventChannel 触发自定义事件 //test.js Page({ onLoad: function(option){ console.log(option.query) const eventChannel = this.getOpenerEventChannel() eventChannel.emit('acceptDataFromOpenedPage', {data: 'test'}); eventChannel.emit('someEvent', {data: 'test'}); // 监听 acceptDataFromOpenerPage 事件,获取上一页面通过 eventChannel 传送到当前页面的数据 eventChannel.on('acceptDataFromOpenerPage', function(data) { console.log(data) }) } }) 通过this.getOpenerEventChannel()获取eventChannel对象, 使用eventChannel.emit() 可以在任意时刻触发(派发)事件。当前页面即可执行对应的事件处理函数。 使用eventChannel.on() 即可监听上个页面emit的事件。 使用示例A页面为订单页面,B页面为填写发票信息页面,A页面跳转B页面携带开票金额(amount),A页面如果已填写,再次跳转B页面,需要携带发票信息(invoice),方便直接编辑B页面填写后返回更新A页面的发票信息(invoice)简单的实现是 A到B的传值使用query实现,B到A的传值使用globalData实现。 // A页面 onShow(){ if(globalData.temp_invoice_info){ this.setData({ invoice:globalData.temp_invoice_info },()=>{ globalData.temp_invoice_info=null; }) } }, //跳转填写发票表单信息 toFillOutInvoiceInfo() { wx.navigateTo({ url: `/pages/invoice/invoice-info-form/invoice-info-form?amount=${ this.data.detail.amount }&invoice=${ this.data.invoice.invoice_title ? JSON.stringify(this.data.invoice) : "" }`, }); }, //B页面 onLoad(options){ this.data.options = options; if (this.data.options.invoice) { this.setData({ invoice: JSON.parse(this.data.options.invoice) }) } }, submit(){ globalData.temp_invoice_info = this.data.invoice; wx.navigateBack(); } 如下EventChannel的实现 //A页面(注意这里需要使用箭头函数(访问this)) //跳转填写发票表单信息 toFillOutInvoiceInfo() { wx.navigateTo({ url: `/pages/invoice/invoice-info-form/invoice-info-form`, events:{ updateInvoice:(result)=>{ this.setData({invoice:result}) } }, success:(res)=>{ const params = { amount: this.data.amount, invoice:this.data.invoice.invoice_title ? JSON.stringify(this.data.invoice) : "" } res.eventChannel.emit('sendQueryParams',params) } }); }, //B页面 onLoad(){ this.getOpenerEventChannel().once('sendQueryParams',(params)=>{ const {amount,invoice} = parmas; this.setData({amount,invoice}) }) } submit(){ this.getOpenerEventChannel().emit('updateInvoice',this.data.invoice); wx.navigateBack(); } 还有一个额外的地方就是EventChannel可以在A-B-C多个页面直接建立数据通道。官方示例。 //注意this.getOpenerEventChannel() 只能在navigateTo模板页面使用,其他更多页面使用时, //可以保存在getApp()全局实例中以备其他页面使用 // 保留AB通道事件,已备C页面给A页面发送数据 // B页面 const eventChannel = this.getOpenerEventChannel() getApp().pageBEventChannel = eventChannel //C页面 getApp().pageBEventChannel.emit('PageAacceptDataFromPageC', { data: 'Page C->A' }); 有不对或扩展的地方欢迎大家批评交流。
2022-08-11 - onShareAppMessage 怎么判断是否分享成功呢?
success:function 方法没有办法监听分享成功事件呢, 想记录一下文章分享的次数 // 自定义分享 onShareAppMessage() { let _this = this; _this.share(); return { title: this.articleInfo.title, path: '/pagesA/articleDetail/articleDetail?id=' + this.articleInfo.id, imageUrl: this.articleInfo.image, success:function(res) { _this.share(); }, fail: function () { uni.showToast({ title: '分享失败', icon: 'none', duration: 2000 }); }, complete: function (c) { }, } },
2022-03-18 - 云储存文件如何批量下载到本地
[图片] 云储存文件上传下载文档地址,https://docs.cloudbase.net/cli-v1/storage 首先确保你已经操作了以上 3 步~~~ 然后你可以选择在桌面新建一个 downloads 文件夹,然后选择打开桌面的命令提示符, [图片] //通过 --mode 指定你的云环境id tcb --mode '你的云环境id' [图片] 环境部署成功后,下载云储存文件到本地(下载 dianXiaoTwo云储存文件 到 本地downloads文件 中) // tcb storage download '云环境文件路径' '本地文件路径' --dir tcb storage download dianXiaoTwo downloads --dir [图片] [图片]
2022-10-13