- scroll-view滚动页面,input键盘弹出时,页面滚动到顶部,输入框内容错位问题。怎么解决?
从一个页面点击带一个id跳转到scroll-view问题的页面,通过传过来的id自动滚动到指定位置,然后点击输入框拉起键盘时,页面突然会滚动到顶部去了,输入框也飘了(输入框错位),跟着到顶部去了。然后我有使用input的adjust-position,键盘弹起时,不自动上推页面和获取input焦点时不滚动,失去焦点在滚,这俩种方法可以解决拉起输入框页面滚动到顶部的问题跟输入框错位的问题,但输入框错误还有点问题,点击输入框获取焦点他会闪一下,先错位在恢复,请问各位大大有什么好的方法解决这个问题吗,或者有什么方法解决先错误在恢复的问题 =。=[图片]
2020-09-02 - 微信字体文件加载,IOS正常,安卓无法正常加载?
wx.loadFontFace({ family:'alimamashuheiti', source:'url("https://file-esurl-cn03.oss-cn-hangzhou.aliyuncs.com/RTD2024/alimamashuheiti.ttf")', success: function(res){ console.log(res,'字体加载成功!'); }, fail: function(err){ console.log(err,'字体加载失败!'); } })
09-24 - createSelectorQuery 页面初始化拿不到节点信息如何解决?
每次小程序重新打开 都会报错 An SelectorQuery call is ignored because no proper page or component is found. Please considering using `SelectorQuery.in` to specify a proper one. 提示我页面或者组件找不到 ,导致wx.createSelectorQuery() 节点信息也没有,然后刷新一下就好了,这个请问大神们怎么解决啊? 方法写在onScrollHandle onScrollHandle(e) { if (this.sectionNavNodeRefs.length === 0) this.getSectionNodeRefs()搜的是首页滚动内容的节点信息 getSectionNodeRefs() { this.sections.forEach((item, index) => { wx.createSelectorQuery().select(`#${item.name}`).boundingClientRect((res) => { if (res) { item.nodeRefs = res this.sectionTops.push(res.top) } }).exec() wx.createSelectorQuery().select(`#nav${item.name}`).boundingClientRect((res) => { if (res) { console.log(res) this.sectionNavNodeRefs.push(res) } }).exec() })BTW :SelectorQuery.in(this)没用,用的MPVUE, 程序是除了第一次打开工具的时候才会报错,之后刷新都是可以运行的,应该是API的问题,如何解决?
2018-09-03 - unknown file: path.requeueComputedKeyAndDecorators
miniprogram-ci preview 上传代码报错。 报错1: unknown file: path.requeueComputedKeyAndDecorators is not a function at enhance (/usr/local/lib/node_modules/miniprogram-ci/dist/modules/corecompiler/summer/plugins/enhance.js:1:1579) at doTransform (/usr/local/lib/node_modules/miniprogram-ci/dist/modules/corecompiler/summer/plugins/enhance.js:1:1827) at Object.runSummerPluginHook (/usr/local/lib/node_modules/miniprogram-ci/dist/modules/corecompiler/summer/worker.js:1:1225) { code: 10045, path: 'app/components/block-item/index.js' 报错2: { type: 'SummerError', message: 'TypeError: _traverse.visitors.environmentVisitor is not a function', stack: 'TypeError: _traverse.visitors.environmentVisitor is not a function\n' + ' at Object.<anonymous> (/usr/local/bin/global/5/.pnpm/node_modules/@babel/helper-replace-supers/lib/index.js:22:51)\n' + ' at Module._compile (node:internal/modules/cjs/loader:1159:14)\n' + ' at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)\n' + code: 10046, path: 'miniprogram/api/account.ts', plugin: 'summer-typescript', hook: 'load' } 测试了一下npm包的版本均有问题。 miniprogram-ci@2.0.6 miniprogram-ci@2.0.4 miniprogram-ci@1.9.16 miniprogram-ci@1.9.8 配置如下: miniprogram-ci preview \ -v false \ --pp ./dist \ --pkp ./private-key.txt \ --enable-es6 true \ --enable-es7 true \ --enable-minify true \ --enable-allowIgnoreUnusedFiles true \ --enable-autoprefixwxss true \ --uv ***** \ --ud ***** \ --appid ***** \ -r 1 上周五还能用,今天周一我们公司所有的小程序CI全部异常。
07-29 - 小程序手势:让半屏弹窗更顺滑
手势系统:更方便、自然、直观的操作方式,提高用户体验和操作效率 —————— 在小程序页面开发中,我们经常用半屏弹窗来进来内容展示,例如:微信开放社区切换主页、加入购物车的选项页、文章留言区等等。 [图片] 常见的半屏弹窗展示逻辑是这样的: 打开弹窗:点击 “打开弹窗” 按钮展示弹窗关闭弹窗:点击“关闭按钮” or 遮罩层 关闭弹窗当我们想在半屏弹窗加一些交互动画时,可以监听节点的 touch 事件来做一些手势判断,进而处理拖拽事件。但是这种方式实现的滚动动画容易卡顿,出现延迟的情况,效果并不理想。 为了丰富小程序的交互体验,我们内置了一批手势组件,可以帮助开发者更好的实现交互动画的效果。 下图演示使用手势的半屏弹窗下拉效果与普通半屏下拉的对比。 当内部评论列表往下拉到顶部时,变为半屏的下拉,可直接下拉关闭弹窗。 [图片] 我们来看下这种操作是怎么实现的 在上面评论列表的半屏弹窗中会有一个 scroll-view 滚动组件,在 scroll-view 中会有滚动事件,当滚动到顶部时,我们希望有整个半屏的下拉事件。 所以我们需要在半屏的最外层放置一个拖动手势组件 pan-gesture-handler。 由于拖动组件内部的 scroll-view 也是可以滚动的,所以这里需要进行一个手势协商的处理,就是什么条件下由哪个组件来响应手势。 当手势往下 ⬇️ 滚动时,此时判断内部 scroll-view 滚动条的位置: 滚动条处于顶部:外层 pan-gesture-handler 响应滚动,此时半屏往下拖动至关闭半屏;滚动条不处于顶部:内层 scroll-view 响应滚动,此时内部列表往上滚。[图片] 当手势往上 ⬆️ 滚动时,此时判断半屏的位置 半屏不完全打开时:外层 pan-gesture-handler 响应滚动,此时半屏往上拖动至完全打开半屏半屏完全打开时:内层 scroll-view 响应滚动,此时内部列表往下滚[图片] 我们来看一下代码的实现,这里用到的手势组件 pan-gesture-handler(拖动时触发)和 vertical-drag-gesture-handler(纵向滑动时触发),手势组件有以下属性 on-gesture-event:手势回调事件should-response-on-move:是否响应当前手势的 move 阶段simultaneous-handlers:指定需要协商的手势是哪几个,下面演示表示 pan 和 scroll 协同触发。native-view:代理的原生节点,这里 scroll-view(scroll-y) 内有个 vertical-drag 手势,scroll-view 自身无法处理,需要被代理出来 ... 接着,我们看看在页面 js 中怎么处理手势。 在手势处理的回调中因为会改变半屏的状态值,所以这里的回调函数采用 worklet 函数,worklet 函数运行在 UI 线程,使得小程序可以做到类原生动画般的体验。 // page.js // shared 创建的变量为共享变量,可在 UI 线程和 JS 线程间同步 this.transY = wx.worklet.shared(1000) this.scrollTop = wx.worklet.shared(0) this.startPan = wx.worklet.shared(true) // shouldPanResponse 和 shouldScrollViewResponse 用于 pan 手势和 scroll-view 滚动手势的协商 shouldPanResponse() { 'worklet' return this.startPan.value }, shouldScrollViewResponse(pointerEvent) { 'worklet' // transY > 0 说明 pan 手势在移动半屏,此时 scroll-view 滚动不应生效 if (this.transY.value > 0) return false const scrollTop = this.scrollTop.value const { deltaY } = pointerEvent // deltaY > 0 是往上滚动,scrollTop <= 0 是滚动到顶部边界,此时 pan 开始生效,scroll-view 滚动不生效 const result = scrollTop <= 0 && deltaY > 0 this.startPan.value = result return !result }, // pan 手势处理 handlePan(gestureEvent) { 'worklet' if (gestureEvent.state === GestureState.ACTIVE) { const curPosition = this.transY.value const destination = Math.max(0, curPosition + gestureEvent.deltaY) // 改变半屏的位置 this.transY.value = destination } // 其他手势状态的处理,如滚动结束时计算半屏处于打开还是关闭的状态 } 目前,同程旅行 已经上线了手势结合半屏的效果 体验路径:酒店查询 - 选择酒店 - 选择入住人 - 新增入住人 [图片] 普通半屏结合手势代码片段:https://developers.weixin.qq.com/s/lx0RH1mD7rGj 手势除了在普通半屏的应用之外,也可以实现分段式半屏。下面演示的分段式半屏比普通半屏的判断条件更多一些。 判断条件同普通半屏类似,根据手势方向 和 分段式半屏当前的位置来判断是响应分段式半屏还是内部列表,响应分段式半屏是改变到哪一个位置。 [图片] 这里与普通半屏不同的是我们还改变了地图的缩放级别(scale) 因为 worklet 函数是在 UI 线程运行的,当要改变 data 值时,需要通过 wx.worklet.runOnJS 调回 JS 线程。 // page.js // 设置 map scale // 运行在 JS 线程 setMapScale(scale) { this.setData({ scale }) }, // worklet 函数,运行在 UI 线程 scrollTo(toValue) { 'worklet' let scale = 18 if (toValue > screenHeight / 2) { scale = 16 } // 从 UI 线程调回 JS 线程 wx.worklet.runOnJS(this.setMapScale.bind(this))(scale) this.transY.value = timing(toValue, { duration: 200 }) }, // 处理拖动半屏的手势 handlePan(gestureEvent) { 'worklet' // 滚动半屏的位置 if (gestureEvent.state === GestureState.ACTIVE) { // deltaY < 0,往上滑动 this.upward.value = gestureEvent.deltaY < 0 // 当前半屏位置 const curPosition = this.transY.value // 只能在 [statusBarHeight, screenHeight] 之间移动 const destination = clamp(curPosition + gestureEvent.deltaY, statusBarHeight, screenHeight) if (curPosition === destination) return // 改变 transY,来改变半屏的位置 this.transY.value = destination } if (gestureEvent.state === GestureState.END || gestureEvent.state === GestureState.CANCELLED) { if (this.transY.value <= screenHeight / 2) { // 在上面的位置 if (this.upward.value) { this.scrollTo(statusBarHeight) } else { this.scrollTo(screenHeight / 2) } } else if (this.transY.value > screenHeight / 2 && this.transY.value <= this.initTransY.value) { // 在中间位置的时候 if (this.upward.value) { this.scrollTo(screenHeight / 2) } else { this.scrollTo(this.initTransY.value) } } else { // 在最下面的位置 this.scrollTo(this.initTransY.value) } } }, 分段式页面代码片段:https://developers.weixin.qq.com/s/fw0U31mI7bGf 半屏的交互除了在页面内实现,也能跨页面实现,如常见的下沉式半屏交互。其中,半屏效果与上述实现类似,而前一页面的下沉实现需要结合自定义路由。 后面的文章中我们会介绍自定义路由结合手势怎么去实现下沉式半屏效果,不仅如此,还有很多类原生的页面切换效果都能通过自定义路由实现。 [图片]
2023-10-20 - draggable-sheet 组件:快速实现半屏拖拽
在日常应用中,半屏可拖拽交互已经成为了用户体验的重要组成部分。页面内的分段式拖拽、半屏拖拽放大等等,这些常见的场景使用半屏拖拽交互可以很好的提升用户的体验感。 目前,实现半屏拖拽交互可以使用手势协商系统来实现,不过需要理解手势协商系统并编写相关代码。 考虑到半屏拖拽交互比较常见,为了让小程序开发者更加轻松地实现半屏拖拽交互,小程序 Skyline 渲染引擎推出了 draggable-sheet 组件。这个组件自带半屏拖拽交互,可以帮助开发者省去手势协商相关的代码,只需要简单配置容器大小、吸附阈值等参数即可实现半屏拖拽交互。无论是半屏弹窗、分段式半屏还是其他场景,draggable-sheet 组件都能帮助你实现更加出色的用户体验。 快速接入 使用 draggable-sheet 组件的流程如下: Step 1. 配置 draggable-sheet 组件 在页面中引入 draggable-sheet 组件,并且配置 draggable-sheet 组件的参数,包括容器大小、吸附阈值等。 在 draggable-sheet 组件内嵌套 scroll-view 组件,且声明 associative-container="draggable-sheet" 将 scroll-view 组件与 draggable-sheet 组件进行关联即可。 <!-- page.wxml --> <draggable-sheet class="sheet" initial-child-size="0.5" min-child-size="0.2" max-child-size="0.8" snap="{{true}}" snap-sizes="{{[0.4, 0.6]}}" > <scroll-view scroll-y="{{true}}" type="list" associative-container="draggable-sheet" bounces="{{true}}" > <!-- 这里放置半屏内容 --> </scroll-view> </draggable-sheet> Step 2. 使用 DraggableSheetContext 接口控制滚动 使用 createSelectorQuery 方法获取 draggable-sheet 组件的节点,然后通过 node 方法获取 DraggableSheetContext 实例。调用 DraggableSheetContext.scrollTo 即可将 draggable-sheet 组件 滚动到指定位置。 // page.js Page({ onReady() { this.createSelectorQuery().select('.sheet').node().exec(res => { // 使用 sheetContext 控制 draggable-sheet 组件的滚动 const sheetContext = res[0].node sheetContext.scrollTo({ size: 0.7, animated: true, duration: 300, easingFunction: 'ease' }) }); }, }); 使用 draggable-sheet 组件,你可以轻松实现半屏拖拽交互,让用户体验更加自由。同时,使用 DraggableSheetContext 接口,你可以动态控制 draggable-sheet 组件的行为,实现更加灵活的交互效果。 例如,我们这里演示了使用 draggable-sheet 实现的 分享弹窗效果 和 分段式拖拽查看旅游景点列表~ [图片][图片] 与其他组件联动 除了简单的半屏弹窗之外,我们还可以通过 worklet:onsizeupdate 回调,在 draggable-sheet 组件尺寸发生变化时,将 draggable-sheet 组件与其他组件进行动画交互。 例如,我们这里在 draggable-sheet 接近搜索框时,与搜索框衔接为一体,隐藏后面的页面,以此实现更流畅的展示效果。 首先,给 draggable-sheet 配置监听函数 worklet:onsizeupdate="onSizeUpdate" <!-- page.wxml --> <view class="search-wrp"> ... </view> <draggable-sheet class="sheet" ... worklet:onsizeupdate="onSizeUpdate" > 然后,我们在 onSizeUpdate 发生变化时,通过 worklet 函数改变共享变量的值即可 Page({ // 监听 draggable-sheet 尺寸变化去改变 progress onSizeUpdate(e) { 'worklet' const distance = sheetHeight - e.pixels this.progress.value = distance >= 20 ? 1 : distance / 20 }, onLoad(options) { const progress = wx.worklet.shared(1) // 绑定 worklet 动画,progress 变化时改变搜索的背景来显示/隐藏 map this.applyAnimatedStyle('.search-wrp', () => { 'worklet' const t = progress.value return { backgroundColor: `rgb(245, 242, 241, ${1 - t})` } }) ... this.progress = progress }, }) [图片] 如果想要快速了解和实践本文中的案例,可在 PC 端点击 代码片段 进行调试。 注意:draggable-sheet 组件支持页面内的拖拽放大功能,如果需要实现页面返回的功能,可以使用 预设路由 来实现。 总结 draggable-sheet 组件通过拖拽的方式来展开或关闭一个面板,提供更加直观、自然的用户交互体验。不仅能够节省屏幕空间,让用户更加高效地利用界面,适用于展示评论列表、商品列表、展开筛选条件、展示更多信息等场景。对于需要提供更加灵活、自由的用户交互体验的小程序来说,draggable-sheet 组件是一个非常有用的功能。 因此,我们邀请大家尝试将这个能力应用到自己的小程序上,通过这个组件来提升用户体验和交互效果。结合其他组件和功能,打造出更加丰富、多样的小程序~
02-26 - 半屏小程序中,tabBar页面的贴底元素及滚动异常?
API名称:wx.openEmbeddedMiniProgram 机型:仅Android 微信版本:8.0.49 基础库版本:3.4.4 问题描述:在半屏小程序中,从普通页面跳转到tabBar页面,如果tabBar页面的内容大于一屏,则以fixed定位贴底的元素无法显示,并且这一屏的内容无法滚动到底部。此时触发一下onHide和onShow,底部元素出现并且可以滚动到页面底部(容器重新计算了?)。如果直接半屏打开这个tabBar页面则无此问题。仅安卓手机,iOS手机暂未复现。 截图:(按顺序) [图片][图片][图片][图片] 复现代码片段: // 普通页面 wxml <button bind:tap="go">购物车</button> // 普通页面 js Page({ go() { wx.switchTab({ url: '/pages/tabBar/cart/cart', }) }, }) // tabBar页面 wxml <view class="items"> <view wx:for="{{list}}" class="item">{{item}}</view> </view> <view class="placeholder"></view> <view class="bottom">底部模块</view> // tabBar页面 wxss .items { padding: 20rpx 0; } .item { display: flex; align-items: center; justify-content: center; height: 200rpx; background-color: cornflowerblue; color: white; } .item + .item { margin-top: 20rpx; } .placeholder { height: 100rpx; } .bottom { position: fixed; bottom: 0; left: 0; right: 0; z-index: 100; display: flex; align-items: center; justify-content: center; height: 100rpx; background-color: cornsilk; } // tabBar页面 js Page({ data: { list: [1, 2, 3, 4, 5, 6, 7, 8, 'END'], }, })
05-24 - TypeError: Failed to fetch,最近出来什么问题?上传经常出现这个错误
message:TypeError: Failed to fetch appid: wx10073fc4994c2804 openid: o6zAJsymTOSYhxyganCfayzTzScc ideVersion: 1.05.2105142 osType: darwin-x64 time: 2021-05-18 14:32:25 开始还以为是网络问题,换了地方还是出现。 [图片]
2021-05-18 - H5网页跳转小程序
现在小程序越来越普遍了,从H5网页(要在微信浏览器下打开的)跳转到相应小程序的场景也越来越多。至此微信提供了相应的微信开放标签让网页开发者可安全便捷地使用微信或系统的能力,为微信用户提供更优质的网页体验。 需要注意的是,微信开放标签有最低的微信版本和最低的系统版本要求。 微信版本要求为:7.0.12及以上系统版本要求为:iOS 10.3及以上、Android 5.0及以上 对于符合微信或系统最低版本要求但仍无法使用微信开放标签的场景,将会在下方使用步骤中的[代码]wx.config[代码]权限验证成功后触发[代码]WeixinOpenTagsError[代码]事件告知开发者。仅无法使用微信开发标签,JS-SDK其他功能不受影响。可通过如下方法监听并进行回退兼容: document.addEventListener('WeixinOpenTagsError', function (e) { console.error(e.detail.errMsg); // 无法使用开放标签的错误原因,需回退兼容。仅无法使用开放标签,JS-SDK其他功能不受影响 }); 根据目前已知的错误场景,回退兼容建议如下: iOS15底层 WebKit 接口发生变更,微信版本8.0.8以下(不包括8.0.8)无法使用开放标签,可引导用户升级最新版本微信;开放标签依赖Web Components方案,极少部分 Android 系统可能由于版本太低而不支持,可引导用户升级系统固件。H5网页跳转小程序有如下步骤: 1.在微信公众号(已认证的服务号)绑定“JS接口安全域名” 如果是公众号身份的网页,需要绑定安全域名。登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 如果是使用小程序云开发静态网站托管的小程序网页,则不需绑定安全域名即可直接使用(即跳过该"步骤一:绑定JS接口安全域名")。 2.引入JS文件 在需要调用 JS 接口的页面引入如下 JS 文件:http://res.wx.qq.com/open/js/jweixin-1.6.0.js (支持https) 如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https) 备注:支持使用 AMD/CMD 标准模块加载方法加载。 注意:js文件必须使用1.6.0版本以上 3.通过config接口注入权限验证配置并申请所需开放标签 与使用 JS-SDK 配置方式相同,所有需要使用开放标签的页面必须先注入配置信息,并通过[代码]openTagList[代码]字段申请所需要的开放标签,否则将无法使用(同一个 url 仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用。目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。开放标签的申请和 JS 接口的申请相互独立,因此是可以同时申请的。 wx.config({ debug: true, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: [], // 必填,需要使用的 JS 接口列表 openTagList: [] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app'] }); 注意:如果使用的是小程序云开发静态网站托管的域名的网页,可以免鉴权直接跳任意合法合规小程序,调用 wx.config 时 appId 需填入非个人主体的已认证小程序,不需计算签名,timestamp、nonceStr、signature 填入非空任意值即可。 4.通过ready接口处理成功验证 wx.ready(function () { // config信息验证后会执行 ready 方法,所有接口调用都必须在 config 接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在 ready 函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在 ready 函数中 }); 5.通过error接口处理失败验证 wx.error(function (res) { // config信息验证失败会执行 error 函数,如签名过期导致验证失败,具体错误信息可以打开 config 的debug模式查看,也可以在返回的 res 参数中查看,对于 SPA 可以在这里更新签名 }); 接口调用说明所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数: success:接口调用成功时执行的回调函数。fail:接口调用失败时执行的回调函数。complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。 以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下: 调用成功时:"xxx:ok" ,其中xxx为调用的接口名 用户取消时:"xxx:cancel",其中xxx为调用的接口名 调用失败时:其值为具体错误信息 使用说明 所使用的标签允许提供插槽,由于插槽中模版的样式是和页面隔离的,因此需要注意在插槽中定义模版的样式。插槽模版及样式均需要通过[代码]<script type="text/wxtag-template"></script>或<template></template>[代码]进行包裹。另外,对于具名插槽还需要通过[代码]slot[代码]属性声明插槽名称,下文标签插槽中的 default 插槽为默认插槽,可不声明插槽名称。 对于标签事件,均可通过[代码]event.detail[代码]获得详细信息。如果无特殊说明,下文标签事件说明中的返回值均指代[代码]event.detail[代码]中的内容。 另外,需要注意以下几点: 页面中与布局和定位相关的样式,如[代码]position: fixed; top -100;[代码]等,尽量不要写在插槽模版的节点中,请声明在标签或其父节点上;对于有 CSP 要求的页面,需要添加白名单[代码]frame-src https://*.qq.com webcompt:[代码],才能在页面中正常使用开放标签。(CSP相关内容可查看以下几篇文章:https://zhuanlan.zhihu.com/p/142987601、https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)开放对象已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签跳转任意合法合规的小程序。已认证的非个人主体的小程序,使用小程序云开发的静态网站托管绑定的域名下的网页,可以使用此标签跳转任意合法合规的小程序。代码 参考:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/staticstorage/jump-miniprogram.html https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>H5跳转小程序</title> <!-- weui 样式 --> <link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.4.1/weui.min.css"> <!-- 页面样式 start --> <style> /* --------START reset.css------- */ * { margin: 0; padding: 0; } html, body { background-color: #fff; } a { text-decoration: none; } a, button, input, span, div { -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } li { list-style-type: none; } /* --------END reset.css------- */ .hidden { display: none; } .full { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .public-web-container, .wechat-web-container, .wechat-web-container wx-open-launch-weapp, .desktop-web-container { display: flex; flex-direction: column; align-items: center; } .public-web-container p, .wechat-web-container p, .desktop-web-container p { position: absolute; top: 40%; } .public-web-container a { position: absolute; bottom: 40%; } .wechat-web-container wx-open-launch-weapp { position: absolute; bottom: 40%; left: 0; right: 0; } .wechat-web-container .open-btn { display: block; margin: 0 auto; padding: 8px 24px; width: 200px; height: 45px; border: none; border-radius: 4px; background-color: #07c160; color: #fff; font-size: 18px; text-align: center; } </style> <!-- 页面样式 end --> </head> <body> <!-- 页面容器 start --> <div id="h5OpenMiniprogram"> <!-- <template> --> <!-- 页面内容 start --> <div class="page full"> <!-- 移动端微信外部浏览器 --> <div id="public-web-container" class="hidden"> <p>正在打开“小程序名字”</p> <a href="javascript:" id="public-web-jump-button" class="weui-btn weui-btn_primary weui-btn_loading" onclick="openWeapp()"> <span id="public-web-jump-button-loading" class="weui-primary-loading weui-primary-loading_transparent"> <i class="weui-primary-loading__dot"></i> </span> 打开小程序 </a> </div> <!-- 微信内部浏览器 --> <div id="wechat-web-container" class="hidden"> <p>点击以下按钮打开“小程序名字”</p> <!-- username:必填,所需跳转的小程序原始id,即小程序对应的以gh_开头的id; path:非必填,所需跳转的小程序内页面路径及参数(默认小程序的初始页面【即首页】) --> <wx-open-launch-weapp id="launch-btn" username="gh_XXX" path="/pages/XXX"> <!-- 第一种: 不适用于Vue.js开发的项目,template标签会冲突 --> <template> <style> .open-btn { display: block; margin: 0 auto; padding: 8px 24px; width: 200px; height: 45px; border: none; border-radius: 4px; background-color: #07c160; color: #fff; font-size: 18px; text-align: center; } </style> <button class="open-btn">打开小程序</button> </template> <!-- 第二种:几乎适用于所有前端框架开发的项目 --> <!-- <script type="text/wxtag-template"> <style> .open-btn { display: block; margin: 0 auto; padding: 8px 24px; width: 200px; height: 45px; border: none; border-radius: 4px; background-color: #07c160; color: #fff; font-size: 18px; text-align: center; } </style> <button class="open-btn">打开小程序</button> </script> --> </wx-open-launch-weapp> </div> <!-- 桌面端 --> <div id="desktop-web-container" class="hidden"> <p>请在手机打开网页链接</p> </div> </div> <!-- 页面内容 end --> <!-- </template> --> </div> <!-- 页面容器 end --> <!-- 引入jQuery --> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> <!-- 调试用的移动端 console --> <script src="https://cdn.jsdelivr.net/npm/eruda"></script> <script> eruda.init(); </script> <!-- 公众号 JSSDK --> <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> <!-- 云开发 Web SDK --> <script src="https://res.wx.qq.com/open/js/cloudbase/1.1.0/cloud.js"></script> <script> function docReady(fn) { document.addEventListener('WeixinOpenTagsError', function (e) { console.error(e.detail.errMsg); // 无法使用开放标签的错误原因,需回退兼容。仅无法使用开放标签,JS-SDK其他功能不受影响 }); if (document.readyState === "complete" || document.readyState === "interactive") { fn(); } else { document.addEventListener("DOMContentLoaded", fn); } } docReady(async function () { var ua = navigator.userAgent.toLowerCase(); var isWXWork = ua.match(/wxwork/i) == "wxwork"; var isWeixin = !isWXWork && ua.match(/micromessenger/i) == "micromessenger"; console.log("isWeixin", isWeixin, isWXWork); var isMobile = false; var isDesktop = false; if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) { isMobile = true; } else { isDesktop = true; } if (isWeixin) { var containerEl = document.getElementById("wechat-web-container"); containerEl.classList.remove("hidden"); containerEl.classList.add("full", "wechat-web-container"); // 公众号网页需要绑定安全域名 // 获取签名,timestamp、nonceStr、signature $.ajax({ url: "请求地址", dataType: "json", success: function (res) { console.log("WeChatConfig", res); if (res.id === 1) { var data = res.items; // 根据实际情况返还的数据进行赋值 wx.config({ // debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印 appId: data.appId, // 必填,公众号的唯一标识 timestamp: data.timestamp, // 必填,生成签名的时间戳 nonceStr: data.nonceStr, // 必填,生成签名的随机串 signature: data.signature, // 必填,签名 jsApiList: ["chooseImage"], // 必填,需要使用的JS接口列表(此处随意一个接口即可) openTagList: ["wx-open-launch-weapp"], // 可选,需要使用的开放标签列表,例如['wx-open-launch-app'] }); /** * config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后。 * config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。 * 对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中 * */ wx.ready(function (res2) { console.log("ready", res2); var launchBtn = document.getElementById("launch-btn"); launchBtn.addEventListener("ready", function (e) { console.log("开放标签 ready"); }); launchBtn.addEventListener("launch", function (e) { console.log("开放标签 success"); }); launchBtn.addEventListener("error", function (e) { console.log("开放标签 fail", e.detail); }); }); // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名 wx.error(function (err) { console.log("error", err); }); } } }) // 小程序云开发静态网站托管的网页 // var launchBtn = document.getElementById("launch-btn"); // launchBtn.addEventListener("ready", function (e) { // console.log("开放标签 ready"); // }); // launchBtn.addEventListener("launch", function (e) { // console.log("开放标签 success"); // }); // launchBtn.addEventListener("error", function (e) { // console.log("开放标签 fail", e.detail); // }); // wx.config({ // // debug: true, // 调试时可开启 // appId: "", // 非个人主体的已认证的小程序APPID // timestamp: 0, // 必填,填任意数字即可 // nonceStr: "nonceStr", // 必填,填任意非空字符串即可 // signature: "signature", // 必填,填任意非空字符串即可 // jsApiList: ["chooseImage"], // 必填,随意一个接口即可 // openTagList: ["wx-open-launch-weapp"], // 填入打开小程序的开放标签名 // }); } else if (isDesktop) { // 在 pc 上则给提示引导到手机端打开 var containerEl = document.getElementById("desktop-web-container"); containerEl.classList.remove("hidden"); containerEl.classList.add("full", "desktop-web-container"); } else { var containerEl = document.getElementById("public-web-container"); containerEl.classList.remove("hidden"); containerEl.classList.add("full", "public-web-container"); // 云函数 // 因未开通云开发环境,此处不做处理 // var c = new cloud.Cloud({ // identityless: true, // 必填,表示是未登录模式 // resourceAppid: "小程序 AppID", // 资源方 AppID // resourceEnv: '云开发环境 ID', // 资源方环境 ID // }); // await c.init(); // window.c = c; // var buttonEl = document.getElementById("public-web-jump-button"); // var buttonLoadingEl = document.getElementById("public-web-jump-button-loading"); // try { // await openWeapp(() => { // buttonEl.classList.remove("weui-btn_loadin"); // buttonLoadingEl.classList.add("hidden"); // }) // } catch (error) { // buttonEl.classList.remove("weui-btn_loadin"); // buttonLoadingEl.classList.add("hidden"); // throw error; // } } }); async function openWeapp(onBeforeJump) { console.log("未开通云开发环境", onBeforeJump); // 因未开通云开发环境,此处不做处理 // var c = window.c; // const res = await c.callFunction({ // name: "public", // data: { // action: "getUrlScheme", // }, // }); // console.warn(res); // if (onBeforeJump) { // onBeforeJump(); // } // location.href = res.result.openlink; } </script> </body> </html> 错误提示 (1)没有在“JS接口安全域名”设置 [图片] 成功提示 (1)微信开发者工具 [图片] (2)真机:会有要打开小程序的名字 [图片]
03-06 - WeixinJSBridge.beforeinvoke is not a function?
环境:(env: Windows,mp,1.05.2204250; lib: 2.26.1) 报错:window.WeixinJSBridge.beforeinvoke is not a function 问题:在onLanch里面调用不了wx.request的吗? App({ onLaunch() { wx.login({ success: res => { wx.request({....}) } }) } })
2022-10-09 - 【已解决】自定义组件多层级嵌套时,组件n无法继承组件m的样式?
注意不是组件继承页面的样式,是组件继承组件的样式。 可能标题不太好理解,举个例子。 现有父级页面index/index.html 和 4个自定义组件,嵌套情况如下, index/index.html 页面中引入组件A <view> <view>这是index/index.html首页</view> <componentA></componentA> </view> 组件A中的代码如下: 组件A中继续引入组件B、C、D... <view class="box-a"> <view>这是A组件</view> <componentB> <componentC> <componentD></componentD> </componentC> </componentB> </view> 我在组件A的.wxss中写了一些样式如下: .box-a { background: #ccc } .box-a .box-a__d{ /* 组件a中设置组件d的样式 */ background: #f00 } 组件D的wxml如下: <view> <view class="box-a__d">这是A组件</view> </view> 现在的问题就是:组件D不会继承组件A中设置的样式,请问要怎么搞。 我尝试在组件D中添加addGlobalClass 或 styleIsolation 但都没有用。如果把组件A中的样式写到app.wxss中是可以的,但我现在不能写到page级别的页面中,我需要组件控制组件。
2020-04-29 - input组件,如果页面内容很多的情况下,输入框在iOS系统会抖动,请问怎么解决呢?
input组件,如果页面内容很多的情况下,目前在列表页面使用的,输入框在iOS系统会抖动,请问怎么解决呢?
2023-08-23 - (21)独立分包与分包预下载
在「小程序 · 小故事」的第一期,我们曾和大家一起分享过「分包加载」的故事。随着小程序功能越来越多样,页面也越来越多,但不同页面的访问频率是有一定差异的。 分包加载允许开发者将小程序划分为主包和若干个分包,将较少用到的页面或功能划分到若干个分包中,主包内只保留最频繁使用的页面和公共的代码。小程序启动时默认只加载主包,再按需加载分包。这一机制保证了在小程序包大小增加的情况下,依然能保持良好的启动速度。 为满足小程序承载的功能不断丰富的需要,小程序的代码包大小上限已提高到 8M。随着小程序应用场景和使用范围的扩大,在实践中,我们发现分包加载仍有一定的局限性。尤其是越来越多的 H5 服务迁移到小程序后,对于小程序的启动速度有更高要求。为了更好的提升小程序的加载速度和使用体验,小程序近期开放了「独立分包」和「分包预下载」两个新的能力,进一步丰富了分包加载的功能和使用场景。 01独立分包 1 技术背景 由于技术实现的差异,小程序首次启动时需要进行代码包的下载,因此在启动性能上与网页相比有一定劣势。通过对小程序启动耗时的分析,我们发现代码包大小对小程序启动速度是有最直接的影响。 一方面,代码包越大,下载时间就越长; 另一方面,代码包越大,通常意味着小程序页面结构和代码逻辑复杂,启动时代码注入执行的时间越长。 采用分包加载一定程度上解决了代码包下载耗时过长的问题。但小程序中的某些场景(如广告页、活动页、支付页等),通常功能不是很复杂且相对独立,对启动性能有很高的要求。在现有方案中,启动这一页面需要依赖整个主包的下载,如果页面在分包中,还需等待分包的下载,启动性能有严重的瓶颈。此时如果依赖开发者进行代码重构,重新分包,不仅工作量大,而且会影响其他分包的使用体验。为了解决这一问题,我们提出了「独立分包」方案。 2 功能简介 独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。从独立分包中页面进入小程序时,不需要下载主包。当用户进入普通分包或主包内页面时,主包才会被下载。 开发者可以将部分对启动性能要求很高的页面放到特殊的独立分包中。当小程序从独立分包页面启动时,只需要下载分包就可以直接运行,可以很大程度上提高分包页面的启动速度,实现小程序的秒开。 [图片] 由于小游戏中没有页面的概念,也没有小程序中多种入口的使用场景,因此小游戏目前没有支持独立分包。 3 配置方法 独立分包的配置方法十分简单,只需要在原有分包配置的基础上定义 independent 字段,即可将一个分包设置为独立分包,例如: [图片] 4 使用限制 独立分包虽然属于分包的一种,但其不依赖主包独立使用,因此在加载流程和运行环境上与普通分包相比有一些差异。除了分包本身的限制外,独立分包还有以下限制: ● 独立分包中不能依赖主包和其他分包中的内容,包括 js 文件、模板、wxss、自定义组件等; ● App 只能在主包内定义,独立分包中不能定义 App,会造成无法预期的行为; ● 独立分包中暂时不支持使用插件。 为了小程序有更好的使用体验,我们不建议开发者把过多的小程序逻辑放置到独立分包中,也不建议在小程序中过度的使用独立分包,例如把每个页面都放到一个独立分包中。 关于独立分包的详细内容请参见 独立分包 · 小程序 02 分包预下载 1 技术背景 在使用「分包加载」后,虽然能够显著提升小程序的启动速度,但是当用户在使用小程序过程中跳转到分包内页面时,需要等待分包下载完成后才能进入页面,造成页面切换的延迟,影响小程序的使用体验。分包预下载便是为了解决首次进入分包页面时的延迟问题而设计的。如果能够在用户进入分包页面之前就预先将分包下载完毕,那么进入分包页面的延迟就能够尽可能降低。 此前,小游戏中已经提供了「基于API」的分包预下载能力。在设计小程序分包预下载能力时,我们设计了「基于配置」和「基于API」两种分包预下载形式,「基于配置」的方式使用简单,且便于对预下载的使用情况进行控制,防止开发者滥用;「基于API」的方式使用起来更灵活,能够动态的调整预下载策略。综合考虑用户的使用感受和内测阶段第三方开发者的反馈后,我们最终决定首先推出「基于配置」的分包预下载能力。 2 功能简介 开发者可以预先配置某个页面可能会跳转到的分包(对于独立分包,也可以预下载主包),在进入小程序某个页面时,由基础库在后台自动预下载可能需要的分包。用户在进行页面跳转时,分包通常已经下载完成,不需要额外等待,可以有效提升进入后续分包页面时的启动速度。此外,考虑到用户的流量和存储空间,小程序也会对预下载的大小和网络进行一定的限制。 [图片] 3 配置方法 开发者可以通过在 app.json 中增加 preloadRule 字段,控制进入某个页面时进行预下载的分包,并设置触发预下载的网络环境。 [图片] [图片] 4 使用限制 对于手机用户而言,数据流量和存储空间是非常重要的资源。一方面,分包预下载能够提升小程序用户的使用体验;另一方面,过度的预下载也会破坏分包按需使用的原则,过度的占用用户的存储空间,消耗数据流量。如果开发者每次启动小程序时都将所有分包进行下载,会消耗很多不必要的流量和存储空间。 为了在分包预下载的效果和对用户资源的消耗上取得平衡,我们限制了同一个分包中的页面预下载总大小不得超过2M,并鼓励开发者按需设置分包预下载的网络条件。 关于独分包预下载详细内容请参见 分包预下载 · 小程序 03 小结 独立分包与分包预下载进一步丰富了分包加载的功能,大大拓展了分包加载的使用场景。同时,独立分包和分包预下载是相辅相成的,配合使用可以获得更好的效果。 例如,开发者可以将一个活动推广页放到一个独立分包中,利用独立分包的特性能够提升活动页面的加载速度,提升转化率。在页面中开发者可以引导有需要的用户跳转到小程序其他页面,使用小程序的更丰富的功能。在这一过程中,可以利用分包预下载能力,将主包或相关分包进行预下载,降低页面跳转的延迟,留住更多用户。 开发者在使用这两个新能力的过程中,如果遇到问题或者有什么建议,欢迎在微信开放社区(https://developers.weixin.qq.com)进行反馈,我们会根据开发者的反馈,不断的优化和丰富分包加载功能,减少功能限制,提升小程序的加载性能和使用体验。
2018-10-14 - 分包预下载 preLoadRule 的下载时机和逻辑是什么?
找了下官方文档里面并没有类似的说明,触发预下载的时机是在指定页面渲染时,指定页面渲染后,还是说是会检测页面帧率稳定后再进行下载
2023-11-17 - 使用独立分包和分包预下载(上)
[视频] 你好,我是李艺。 上节课我们学习了按需注入和初始渲染缓存,明确了静态导航页适合使用初始渲染缓存,动态详情页适合使用骨架屏的策略。这节课我们学习分包、独立分包以及分包预下载。 首先我们看一下问题,在冷启动流程中间使用按需注入改良的只是代码注入阶段的性能,如果这个代码包本身它就比较大,那么在第一阶段,也就是资源准备阶段,就会浪费大量的时间,还有如果是代码包过大,它主包超过2MB,在微信开发者工具里面根本也没有办法上传以申请这个版本的审核,为了让这个代码包瘦身,微信开发者工具提供了静态代码依赖分析这个工具,可以帮助开发者找到无依赖文件。 但是有一点我们需要注意,有一些文件它表面上看起来是用不到的,但其实是不能删除的,因为有时候它是在运行时动态加载并使用的,如果这个代码包删除了无依赖的文件以后依然超过了2MB的限制,这时候应该怎么办?小程序又提供了分包以及独立分包的机制,只要单个代码包不超过2MB,总包大小不超过20MB即可。有些开发者可能觉得2MB限制太小了,决定阈值的从来其实都不是规定,而是网络环境和用户群体,国内有很多网民还在使用低端机,包括WiFi以及4G网络环境其实还没有100%的普及,或许等以后5G技术普及以后,限制会进一步的放开,那个时候主包大小或许会进一步的放大,在目前这个阶段,在当下网络环境里面如果要想提升小程序的启动性能以及运行性能,只能在深谙小程序的运行机制以及启动流程的前提之下,在已有的技术框架之下靠精耕细作的精神一个字节 一个字节地去优化。 接下来我们看项目实践。 目前我们的项目已经超过了2MB,必须通过分包分割总代码包的大小。 首先我们看实践一:用户主页分包、创建tab-bar组件。 将用户主页放在分包内,只需要给页面所在的目录添加分包配置就可以了,在app.json全局配置文件里面,我们可以在subpackages这个节点之下添加一个分包设置,root设置为当前页面所在的目录的一个名称,然后再加上pages设置就可以完成用户主页的一个分包设置了。 在小程序里面,如果是使用配置的方式开启tabBar导航,或者是使用这种官方自定义的方式,也就是我们通过在配置文件里面设置tabBar.custom等于true这样的方式实现tabBar导航组件,这个时候tabBar它页面地址只能放在主包里面,为了破除这个限制,我们可以使用自定义的方式实现tabBar的导航。 首先我们需要在app.json配置文件里面将tabBar的配置删掉,我们现在不需要这个配置了,然后我们在components目录下面创建一个tabBar的组件,用它提供全局的导航功能,在组件的JS代码里面会创建一个select方法,它设置哪个链接,当前是选中的状态,这个方法是给外部的代码进行提供的,这个组件的wxml代码很简单,主要是渲染一个list列表,而且这个list的数据还是从原来app.json文件里面复用过来的,wxss样式仅包含自定义组件本身它所需要的样式,这个里边有一个特殊的类样式,就是bar__active。这个是选中的样式,当这个链接与当前这个页面地址一致的时候这个文本它会呈现红色,这个图标也是红色图标,文本的选中颜色还有文本的默认颜色也就是它默认呈现的颜色,与我们原来在app.json配置文件里面的设置是一致的,完全以自定义组件这种方式实现的tabBar导航有哪些优点?我们一起看一下。 首先第一点,页面不再受分包的限制。我们可以将这个页面放到任何一个分包里面去;第二点就是tab-bar组件里边用到的图标,也不再被限制只能放在本地;第三点就是这个代码里面所有的tabBar页面的跳转也不用再单独使用wx.switchTab这样的接口,可以统一使用wx.navigateTo或者是wx.redirectTo这两个接口任何一个都可以,甚至tab-bar组件本身,如果我们愿意的话还可以将它进一步的优化,不放在主包里边,放在分包里面也是可以的。 现在我们开始实践一的代码演示。 在拿到这个源码以后,我们需要在小程序里面进行一个代码的引入,引入方式也很简单,只需要找到对应的目录然后选择,选择以后这个地方AppID要选择我们自己的账号的AppID,这个名称也可以修改,然后单击确定就可以了。我们要实现分包,实现用户主页的一个分包,首先我们看一下app.json这个文件,这个文件里面,目前我们这个地方其实已经有了一个分包设置了,在subpackages下面只需要在这个底下再添加一个新的配置就可以了。这个里面第一个字段要写的是root,它代表的是我们分包的一个地址,这个地方我们写user,因为我们这个项目底下确实有一个user的目录,也就是这个,根目录指定以后,接下来我们要指定pages,也就是这个页面了,这个页面它是我们在分包下面的一个相对地址,我们可以在这个地方复制一个相对路径,然后粘到这个地方,前面这些是不需要的,它只需要从pages下面,也就是从我们目录下面,开始计算路径,这样的话我们分包的一个设置就算是已经完成了。 再往下我们再创建我们的自定义导航按钮,自定义导航的组件在我们的components目录下面,然后去创建这个组件,现在这个目录还没有,可以创建一下目录,然后这个目录下面再创建一个tab_bar这样的子目录,在这个目录下面放tab-bar自定义组件它的一个源码,可以采用一种快速的新建的方式,比如这个地方我们选择新建Component选择这个菜单,然后写入一个index,完成以后,下面所有的四个文件已经全部默认帮我们创建了,下面开始实现这个代码,这个代码我们之前这已经有实现好的,为了快速我们直接复用我们已经实现的代码,这是页面的标签代码,这个标签代码里面我们可以看一下,主要是一个列表渲染,这个地方用了一个wx:for这样一个列表渲染,然后循环渲染这个list里边还有关于image这个地方有一个判断,当前的index是否等于selected就是我们当前选择的索引,如果等于的话,然后去渲染这样的一个图标地址,如果否的话就是选择另外一个图标地址,这是它的样式。 这个地方是我们这个页面的就是文本 一个标题或者说我们页面的一个名称,这个页面的一个跳转是靠我们绑定的一个事件,在这个上面可以看一下,在这个地方有一个tap 一个绑定,nav的方法上面,我们再看一下JS代码,这是我们JS代码,这个JS代码里面nav,这是我们刚才提到的用于页面跳转的一个方法,上面这有一个select它的参数是index就是索引,我们当前选择哪一个,这个方法是对外提供的,在这个页面里面使用这个组件的时候,稍后我们会调用这个方法。 再往上就是data对象了,第一个是一个selected,就是选择的索引,我们当前选择这列表里面哪一项作为选中的页面,它的默认是0,下面这个list这些数据是我们原来的app.json里面的数据,它的一个修改,我们可以看一下我们原来的数据这个地方 这有一个list,我们可以将这个list给它拷贝一下,除了这个list还有两个color,这里有一个color 这有一个color,我们先将这个list给它拷贝一下,然后到tab_bar这个里面,可以放在这个地方对比一下,这两个数据是很像的,它的差别其实只是我们pagePath前面多了一个斜杠,包括iconPath还有selectedIconPath前面多了两个斜杠,其他的其实都是一样的。 当然了我们上面的这种格式是微信它定义的,在app.json里面,如果是要定义tabBar导航的话必须要用这种格式,但下面这种格式是我们自定义的,我们选择这样一种方式定义便于我们和默认的官方配置、保持一致的数据结构,最后我们再看一下样式。这个代码里面只有一项就是component等于true,如果它是个组件的话,在这个json里边它这一项是等于true的样式代码,这是它的一个样式代码,在样式代码里面可以看到这个里面有一个bar__active代表的是选中状态,选中状态下它文本色,这个地方其实是文本,我们可以看到在这个里边这是它的样式,选中以后文本变成这个颜色,d81e06这样的一个样式与我们前面在这个地方看到的样式它俩是一样的,包括我们前面的5151默认的文本颜色跟我们组件里面的样式也是一样的。我们可以看一下,也就是这个颜色,这是它默认的一个颜色,是一样的。这是组件已经准备好了,这个它默认生成的,其实下面那个我们不需要,只需要这一个就可以了,组件已经准备好了。 接下来我们需要在配置文件里面做一个组件的引入,在这个里面也需要写一个usingComponents,然后是tab-bar,一般的话自定义组件的命名方式就使用这样一种单词中间用连字符,因为官方它组件,然后分割单词也是这样一种形式,所以我们就沿用官方的形式就可以了,组件的地址在哪里,这个地方可以复制一下相对地址,然后粘到这个地方再稍做修改这样就可以了,稍做修改,当然后面JS不需要 把这个给去掉,接下来我们就需要在我们的三个页面:用户主页、商品详情页和主页面里面分别添加tar-bar组件的一个使用。 首先我们在user这个里面找到这个标签页wxml这个页面,在它的最下方添加一个tab-bar,再给它一个id,这样一个代码,然后我们还需要在JS里面,在这个页面的onReady的时候onReady,这个地方没有onReady就在这个地方再加一个onReady,在这个地方需要调用这个页面的selectComponent这个地方的参数,我们写#tabBar 井号代表的是id,tabBar是我们刚才定义的id,选择以后再调用它的select方法,要传一个参数,因为我们用户主页居于导航栏的里面的属于它的索引在2这个位置,所以我们这地方要选2。这是用户主页,然后将这个代码复制一下,在另外的两个页面里面,一个是商品详情页,在这个页面最下方也拷贝一份,还有是我们的index主页的最下方也放置一份,这是wxml代码,接着是拷贝我们的选择代码,在主页里面找到onReady,在这个地方可以放在最后面 放在这个位置,这个是主页,数字要设置为1,还有一个是商品详情页,商品详情页在onReady里边添加代码,这个要设置为0,这就是我们的代码,现在已经改造完成了。 单击编译我们看一下运行效果。这个地方有一个问题,就是我们的地址它不应该在subPackages分包内出现这样的一个提示,这个提示是什么意思,看一下我们这个项目的配置文件,现在我们给用户主页实现分包,将这个地址放在了这个地方,当然这个地方多了一个.js,放在这个地方以后,在我们整个文件默认的pages下面,这个地址其实我们就应该给它删掉,它不需要了,一个页面不能同时出现在两个包里,然后这样去处理再编译一下 看看效果。 这个地方也有一个问题,模拟器无法获取这个文件,已经被忽略上传,它这个忽略上传我们暂时不要去理它,只是它自己的一个提示,现在要测试导航组件的一个表现是否正常,选择商品页,商品页现在高亮了对吧,然后选择主页,然后主页高亮了对吧,然后选择我的页面,我的页面也高亮了对吧。这个导航已经实现了它预想的一个功能,现在我们拿我们的商品详情页,就是detail这个页面它作为启动页再测试一下,也没有问题对吧,也显示了这个代码它的作用是良好的。 在这个地方有一点我们需要提示一下,我们这个代码里面是有选择组件,然后再调用其中的方法的代码也就是这个对吧,在主页里面这个地方选择组件然后再调用它的方法,选择这个组件它其实未必是可以选到的,所以如果这个地方我们要避免出错的话我们可以加一个问号,加个问号以后 就是ES6里面的可选链语法,如果是它不是null,然后找到这个组件,调用它的一个方法,这样的一个语法,这是主页,然后在这个商品详情页里面也是一样的一个处理,这个地方加一个问号,还有一个是在用户主页这个地方也加一个,我们再测试一下,没有问题。正常情况下这个页面已经走到了onReady这个地方,按理说它不会出现选择不到的这种情况,但是有一种情况我们稍后可能会遇到,如果是我们当前这个页面,它本身它跟我们的用到的组件,我们现在这个组件tab-bar这个组件是放在我们主包里面,因为它是在app.json里面配置的,如果是我们这个页面是在一个独立分包里面 它是独立的,然后它显示的时候其实主包没有加载,主包里边的组件你也使用不了,这种情况下有可能,这个地方我们要去选择组件的时候,它可能拿到的是一个空值或者是一个undefined,你在一个undefined调用它的方法,显然是不合适的话可能会报错,所以这个地方所有的组件其实都是一样,你如果想万无一失的话,给它加一个问号,这个问题就可以轻松化解了。 这个代码演示就到这里了。
2022-07-14 - SelectorQuery NodesRef.xxx返回null?
[图片] [图片] p.select('#' + e.currentTarget.dataset.pid) 这一步是有数据返回的,但是下一步boundingClientRect回调就返回null了。 网上说搞个setTimeout,但是好像没有效果。 [图片] settimeout没有效果
2020-05-09 - Framework inner error
- 当前 Bug 的表现(可附上截图) Framework inner error (expect FLOW_APPLY_PROPERTY but get another) [图片] 我在开发者工具上试着换了一下基础库,换到较低版本就不报错了,换到最新的基础库就会报错。希望团队能看看问题。 我实在给组件的属性赋值时抛出的异常。 我在页面上用了一个组件 A,给组件A的属性赋值,组件A里面包含组件 B,组件B 的属性是通过组件A的属性给赋值的。恰好这个时候抛出了异常。 这是在页面的代码块: [代码]<[代码][代码]block[代码] [代码]wx:for[代码][代码]=[代码][代码]"{{ comments }}"[代码] [代码]wx:key[代码][代码]=[代码][代码]"id"[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]v-comment-item[代码][代码] [代码][代码]comment-id[代码][代码]=[代码][代码]"{{ item.id }}"[代码][代码] [代码][代码]content[代码][代码]=[代码][代码]"{{ item.content }}"[代码][代码] [代码][代码]created-at[代码][代码]=[代码][代码]"{{ item.created_at }}"[代码][代码] [代码][代码]openid[代码][代码]=[代码][代码]"{{ item.user.openid }}"[代码][代码] [代码][代码]nickname[代码][代码]=[代码][代码]"{{ item.user.nickname }}"[代码][代码] [代码][代码]avatar-url[代码][代码]=[代码][代码]"{{ item.user.avatar }}"[代码][代码] [代码][代码]/>[代码][代码]</[代码][代码]block[代码][代码]>[代码] 这是组件A的WXML代码: [代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]"container"[代码] [代码]wx:if[代码][代码]=[代码][代码]"{{ content }}"[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'author-wrapper'[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]v-avatar[代码] [代码]radius[代码][代码]=[代码][代码]"50%"[代码] [代码]avatar[代码][代码]=[代码][代码]"{{ avatarUrl }}"[代码] [代码]/>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'nickname {{ nickname_is_chines ? "zh-cn" : "" }}'[代码][代码]>{{ nickname }}</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'time-wrapper'[代码][代码]>{{ createdAt }}</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'content-wrapper {{ content_is_chines ? "zh-cn" : "" }}'[代码][代码]>{{ content }}</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'action-wrapper'[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'action-item reply'[代码] [代码]bindtap[代码][代码]=[代码][代码]'onClickReply'[代码][代码]> خەت قالدۇرۇش </[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'action-item delete'[代码] [代码]wx:if[代码][代码]=[代码][代码]"{{ hasAuthor }}"[代码] [代码]bindtap[代码][代码]=[代码][代码]'onClickDelete'[代码][代码]> ئۆچۈرۈش </[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]</[代码][代码]view[代码][代码]>[代码][代码]</[代码][代码]view[代码][代码]>[代码]刚好上面的组件里面还有一个组件B也就是用户头像的组件 v-avatar 在页面给组件A的属性avatar-url赋值的时候抛出异常了。其他属性都没有问题。
2019-04-17 - 怎么阻止导航栏返回按钮的默认跳转行为?
怎么阻止导航栏返回按钮的默认跳转行为?
2022-01-12 - 小程序底部导航栏跳转之前如何拦截?
用户点击底部导航栏进行tabBar的切换,如何根据权限在跳转前进行限制,并非动态生成
2023-09-05 - 小程序导航栏出现返回首页按钮
目前返回首页按钮出现的条件为(需同时满足): 1. 使用了默认导航栏样式(非 custom) 2. 不是首页或 tabbar 页面(在 app.json 中定义的) 3. 是页面栈最底层页面 如果是开发者自己手写的 tabbar 导致的问题,需要在页面的 onShow 中调用 wx.hideHomeButton() https://developers.weixin.qq.com/miniprogram/dev/api/ui/navigation-bar/wx.hideHomeButton.html手动隐藏返回首页按钮。
2019-09-27 - 开放工具报错Fatal: unexpected loadSdkSubPackage case?
运行项目时一开始是正常的,然后就遇到工具报错:Error: Fatal: unexpected loadSdkSubPackage case,尝试了更新开发工具、重新拉取代码后依然无效 [图片]
2023-02-04 - 如何解决“Error: xxx.js 已被代码依赖分析忽略,无法被其他模块引用”报错?
错误原因: 微信开发者工具从 1.05.2201210 版本开始,对小程序项目新增了无依赖文件过滤能力。 如果某个 js 文件被静态分析显示是无依赖文件,在实际运行时又被其他 js 文件 require 引用了,则会在工具模拟器中报错这个错误。 此时,如果你继续预览或者上传代码,则在真机运行环境中会报 xxx.js is not defined 的错误。 解决方式: 修改依赖引用的代码:可根据控制台中的【代码依赖分析异常】提示进行修改。(推荐)关闭过滤无依赖文件:project.config.json 中 settings 选项添加 ignoreDevUnusedFiles: false , ignoreUploadUnusedFiles: false详细分析: 微信开发者工具的无依赖文件过滤能力,是基于代码静态依赖分析的数据来实现的。 也就是会分析小程序项目中的代码内容,如果发现某个 js / wxml / wxss / json 文件没有被使用到,则会将其列为无依赖文件。 无依赖文件在模拟器运行时会被忽略,在上传时也不会打入代码包中,因此可以有效减少代码包大小。 但由于 js 代码的灵活性,代码静态依赖分析功能在某些情况下,无法准确分析出依赖引用关系(控制台中会有对应的 warning 提示),此时部分 js 文件会被误判为无依赖文件,导致报错。开发者需配合提示信息修改代码,才能继续使用此功能。 导致依赖异常的常见情况: 动态引用的情况,如 var a = 'somefile.js'; require(a);将 require 函数赋值给其他变量的情况,如 var a = require; a('somefile.js');
2022-07-04 - 教你怎么监听小程序的返回键
更新:2020年7月28日08:51:11 基础库2.12.0起,可以调用wx.enableAlertBeforeUnload监听原生右上角返回、物理返回以及wx.navigateBack时弹框提示 AIP详情请看: https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.enableAlertBeforeUnload.html //======================================== 怎么监听小程序的返回键? 应该有很多人想要监听用户的这个动作吧,但是很遗憾,小程序不会给你这个API的,那是不是就没辙了? 幸好我们还可以自定义导航栏,这样一来我们就可以监听用户的这一动作了。 什么?这你已经知道啦? 那好咱们就不说自定义导航栏的返回监听了,说一下物理返回和左滑?右滑?(不管了,反正是滑)返回上一页怎么监听。 监听物理返回 首先说一下这个监听方法的缺点,虽说是监听,但是还是无法真正意义上的监听并拦截来阻止页面跳转,页面还是会返回上一页,而后重新载入刚刚的页面,如果这不是你想要的,那可以不用往下看了 其次说一下用到什么东西: wx.onAppRoute、wx.showModal 最后是一些主要代码: 重写wx.showModal,主要是加个confirmStay参数和使wx.showModal Promise化 [代码]const { showModal } = wx; Object.defineProperty(wx, 'showModal', { configurable: false, // 是否可以配置 enumerable: false, // 是否可迭代 writable: false, // 是否可重写 value(...param) { return new Promise(function (rs, rj) { let { success, fail, complete, confirmStay } = param[0] param[0].success = (res) => { res.navBack = (res.confirm && !confirmStay) || (res.cancel && confirmStay) wx.setStorageSync('showBackModal', !res.navBack) success && success(res) rs(res) } param[0].fail = (res) => { fail && fail(res) rj(res) } param[0].complete = (res) => { complete && complete(res) (res.confirm || res.cancel) ? rs(res) : rj(res) } return showModal.apply(this, param); // 原样移交函数参数和this }.bind(this)) } }); [代码] 使用wx.onAppRoute实现返回原来的页面 [代码]wx.onAppRoute(function (res) { var a = getApp(), ps = getCurrentPages(), t = ps[ps.length - 1], b = a && a.globalData && a.globalData.pageBeforeBacks || {}, c = a && a.globalData && a.globalData.lastPage || {} if (res.openType == 'navigateBack') { var showBackModal = wx.getStorageSync('showBackModal') if (c.route && showBackModal && typeof b[c.route] == 'function') { wx.navigateTo({ url: '/' + c.route + '?useCache=1', }) b[c.route]().then(res => { if (res.navBack){ a.globalData.pageBeforeBacks = {} wx.navigateBack({ delta: 1 }) } }) } } else if (res.openType == 'navigateTo' || res.openType == 'redirectTo') { if (!a.hasOwnProperty('globalData')) a.globalData = {} if (!a.globalData.hasOwnProperty('lastPage')) a.globalData.lastPage = {} if (!a.globalData.hasOwnProperty('pageBeforeBacks')) a.globalData.pageBeforeBacks = {} if (ps.length >= 2 && t.onBeforeBack && typeof t.onBeforeBack == 'function') { let { onUnload } = t wx.setStorageSync('showBackModal', !0) t.onUnload = function () { a.globalData.lastPage = { route: t.route, data: t.data } onUnload() } } t.onBeforeBack && typeof t.onBeforeBack == 'function' && (a.globalData.pageBeforeBacks[t.route] = t.onBeforeBack) } }) [代码] 改造Page [代码]const myPage = Page Page = function(e){ let { onLoad, onShow, onUnload } = e e.onLoad = (() => { return function (res) { this.app = getApp() this.app.globalData = this.app.globalData || {} let reinit = () => { if (this.app.globalData.lastPage && this.app.globalData.lastPage.route == this.route) { this.app.globalData.lastPage.data && this.setData(this.app.globalData.lastPage.data) Object.assign(this, this.app.globalData.lastPage.syncProps || {}) } } this.useCache = res.useCache res.useCache ? reinit() : (onLoad && onLoad.call(this, res)) } })() e.onShow = (() => { return function (res) { !this.useCache && onShow && onShow.call(this, res) } })() e.onUnload = (() => { return function (res) { this.app.globalData = Object.assign(this.app.globalData || {}, { lastPage: this }) onUnload && onUnload.call(this, res) } })() return myPage.call(this, e) } [代码] 在需要监听的页面加个onBeforeBack方法,方法返回Promise化的wx.showModal [代码]onBeforeBack: function () { return wx.showModal({ title: '提示', content: '信息尚未保存,确定要返回吗?', confirmStay: !1 //结合content意思,点击确定按钮,是否留在原来页面,confirmStay默认false }) } [代码] 运行测试,Oj8K 是不是很简单,马上去试试水吧,效果图就不放了,静态图也看不出效果,动态图懒得弄,想看效果的自己运行代码片段吧 代码片段 https://developers.weixin.qq.com/s/hc2tyrmw79hg
2020-07-28 - 如何监听滑动页面返回的事件?
在开发小程序过程中如何监听滑动页面返回的事件,使用onBackPress事件没有效果
2023-01-10 - websocket 为什么1分钟自动断开?
服务端使用云托管nodejs环境使用官方示例可以正常连接成功,也可以相互发送消息,但是如果一分钟之内没有交互就会自动断开 code: 1006
2023-04-12 - APP-SERVICE-SDK:setStorageSync:fail
- 当前 Bug 的表现(可附上截图) 小程序后台日志报错 APP-SERVICE-SDK:setStorageSync:fail write DB data fail;at pages/index/index onReady function;at api request success callback function
2019-07-26 - 2.26.1版本小程序BUG?WE后台频繁报错。
JS分析/错误内容详情 Script error. Script error. Empty stack, maybe muted error. (xweb=false) 报错的全都是基础库2.26.1版本,希望官方协助解决。
2023-04-01 - websocket invalid http status?
使用讯飞的websocket,在开放工具中可以正常连接和使用真机调试或者发布体验版都提示invalid http status。已经加入socket合法域名wss://ise-api.xfyun.cn有人遇到吗?怎么解决?
2021-04-05 - 小程序违规, 申诉已经通过, getPhoneNumber 功能仍不可用, 麻烦给看看?
这个是违规原因, 该用户微信未绑定手机号, 当使用 getPhoneNumber g功能时, 微信提醒他绑定手机号. 这个弹窗真的是微信getPhoneNumber功能自己的, 我们是无辜的... [图片] [图片] 申诉结果已经通过, 但是线上版本 getPhoneNumber 功能现在仍然是不可用状态, 麻烦官方运营童鞋抓紧给看下 AppID: wx03b265ee61c46412[图片]
2022-08-05 - getPhoneNumber接口调用违规?
[图片] [图片] 违规内容,点击微信快捷登录 调用getPhoneNumber接口获取手机号码进行登录,全局搜索未找到"微信账号还没有绑定手机号",初步怀疑是该用户微信未绑定手机号码,微信官方弹窗,请问这种情况下该如何整改??
2023-05-22 - 本地存储大小限制为0、本地存储无故清空
最近遇到好多次本地存储突然清空的情况,很大概率排除了自身业务代码的原因,于是开始在代码中加入了部分log来记录此类问题,以下是2个案例,(数据记录的分别是wx.getSystemInfoSync()和wx.getStorageInfoSync()获取的数据)发现limitSize: 0 (正常不应该是10240么) 案例1 {"screenWidth":360,"pixelRatio":3,"system":"Android 5.1","benchmarkLevel":7,"windowWidth":360,"brand":"Meizu","screenHeight":640,"version":"6.6.6","fontSizeSetting":16,"language":"zh_CN","windowHeight":570,"model":"m3 note","platform":"android","SDKVersion":"2.0.9"} {"keys":[],"currentSize":0,"limitSize":0} 案例2 {"screenWidth":360,"benchmarkLevel":8,"windowHeight":608,"screenHeight":680,"language":"zh_CN","version":"6.6.7","system":"Android 8.0.0","fontSizeSetting":18,"pixelRatio":3,"model":"HWI-AL00","statusBarHeight":24,"brand":"HUAWEI","windowWidth":360,"platform":"android","SDKVersion":"2.0.9"} {"limitSize":0,"keys":[],"currentSize":0}
2018-06-13 - 小程序如何监听阻止左侧向右滑动返回上一页面?
现在有个需求左侧向右滑动返回上一页面我们先出现我们自己的一个弹框处理一些逻辑,可是现在不知道要如何阻止这个返回呢?
2023-05-08 - 要测试tabbar页onUnload,怎么退出小程序?
开发者工具退不出,预览怎么退?
2020-04-02 - 关于微信用户撤回授权信息通知的一些疑问?
今天收到一封微信团队发送的电子邮件,内容如下 尊敬的开发者: 根据相关法律法规,用户撤回同意后开发者应当主动删除用户信息。 对于微信用户撤回授权信息,平台将每日一次邮件同步通知,请你及时删除附件中用户的相关授权信息(相关字段释义详见下方开发者社区文档说明)。 你也可以通过接收事件通知即时进行处理,能力参考: 小程序用户撤回: https://developers.weixin.qq.com/miniprogram/dev/framework/security.html#%E6%8E%88%E6%9D%83%E7%94%A8%E6%88%B7%E8%B5%84%E6%96%99%E5%8F%98%E6%9B%B4 ; 公众号用户撤回H5授权信息: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/authorization_change.html ; 移动应用用户撤回: https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/authorization_change.html ; 网站应用用户撤回: https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/authorization_change.html 。 微信团队 2021-12-24 对于上述内容有如下疑问: 1.根据相关法律法规,用户撤回同意后开发者应当主动删除用户信息,想知道相关的法律法规具体指那个? 2.关于删除用户信息这个操作,是删除涉及的字段还是整条记录?使用别的内容替换是否可行?
2021-12-24 - 小程序在分包使用某插件,为什么在分包引入后会增大主包代码体积?
QIYUSDK插件 微信最新版 基础库2.27.1 虽然可以在分包内引用插件,但是插件依然占用主包大小,导致不能上传或预览小程序。
2022-11-16 - 小程序引用第三方的小程序插件,这个插件占用小程序的代码包大小吗?
小程序引用第三方的小程序插件,这个插件会占用小程序的代码包大小吗?
2022-11-15 - 自定义组件 attached 与父页面 onLoad执行顺序问题,该如何传值?
一个自定义组件,里面attached执行的代码如下 attached() { console.log("attached:"+this.data.masterId) this.getData() } 而调用它的页面里是这样 wxml: <attachments masterId="{{lessonId}}" /> TS文件 onLoad(routeParams: any) { console.log('page onload') this.setData({ lessonId: routeParams.id }) }, 因为组件的参数是在wxml里面赋值的,而这个参数是onload时候获取的。 实际执行,通过控制台可以看到,是先调用 attached,再调用 onLoad 。这样组件就无法通过传值给属性来获取数据。 请高手指点应该如何处理?多谢多谢!
2021-11-10 - 你不知道的小程序系列之生命周期执行顺序
再次开始之前先问几个问题: 你是否知道[代码]Page[代码]生命周期 与 [代码]pagelifetimes[代码] 生命周期执行顺序? 你是否知道[代码]behaviors[代码]中的生命周期与组件生命周期执行顺序? 你是否知道[代码]Page[代码]生命周期 与 组件[代码]pagelifetimes[代码]生命周期执行顺序? 要回答上面的问题,首先我们看看小程序生命周期有哪些: App onLaunch onShow onHide Page onLoad onShow onReady onHide onUnload Component created attached ready moved detached 想一下加载一个页面(包含组件)的加载顺序,按照直觉小程序加载顺序应该是这样的加载顺序(以下列子中[代码]Component[代码]都是同步组件): App(onLaunch) -> Page(onLoad) -> Component(created) 但其实并不然,小程序的加载顺序是这样的: 首先执行 [代码]App.onLaunch[代码] -> [代码]App.onShow[代码] 其次执行 [代码]Component.created[代码] -> [代码]Component.attached[代码] 再执行 [代码]Page.onLoad[代码] -> [代码]Page.onShow[代码] 最后 执行 [代码]Component.ready[代码] -> [代码]Page.onReady[代码] 其实也不难理解微信这么设计背后的逻辑,我们先看下官方的的生命周期: [图片] 可以看到,在页面[代码]onLoad[代码]之前会有页面[代码]create[代码]阶段,这其中就包含了组件的初始化,等组件初始化完成之后,才会执行页面的[代码]onLoad[代码], 之后页面[代码]ready[代码]事件也是在组件[代码]ready[代码]之后才触发的。 下面我们来看看 [代码]Behavior[代码], [代码]Behavior[代码] 与 [代码]Vue[代码]中的 [代码]mixin[代码] 类似,猜想下其中的执行顺序: Behavior.created => Component.created 测试下来和预期相符,其实在[代码]Vue[代码]的文档中有一段这样的描述: 另外,混入对象的钩子将在组件自身钩子之前调用。 这样的设计和主流设计保持一致。接下来我们看看 [代码]pageLifetimes[代码],有[代码]show[代码]和[代码]hide[代码]生命周期对应页面的展示与隐藏,预期的执行顺序: pageLifetime.show => Page.onShow 测试下来也和预期相符,那么我们可以推断出如下的结论: 当页面中包含组件时,组件的生命周期(包括pageLifetimes)总是优先于页面,[代码]Behaviors[代码]生命周期优先于组件的生命周期。但其实有个例外:页面退出堆栈,当页面[代码]unload[代码]时会执行如下顺序: Page.onUnload => Component.detached 看了以上的分析你应该知道了答案,最后做个总结(demo): [图片] 最后的最后布置个作业 异步组件(异步渲染的组件,通常是通过if条件判断是否渲染)的生命周期执行顺序是怎样的,pagelifetimes会不会执行?
2020-01-10 - 自定义组件初始化时因为默认值不同导致 prop 的 observer 被调用
- 当前 Bug 的表现(可附上截图) 在自定义组件 Component 的 properties 中定义 prop 的缺省值以及 observer 函数。 当使用该组件需要初始化该组件时,若 prop 接收外部传入的实参与该 prop 的默认值不相等时,会导致 observer 被立即调用一次。 - 预期表现 prop 的缺省值应该是组件未接收到外部传参时,使用的缺省值作为默认值,这属于组件初始化工作,不应该视为 prop 发生了变化。 所以当组件初始化时,如果 prop 接收的外部传参与缺省值不相等时,不触发 observer 调用是不是更合理一点? - 提供一个最简复现 Demo 代码片段:wechatide://minicode/8SCwknmx7D3z
2018-10-23 - 微信开发者工具创建的插件报错:WebAssembly.instantiate()?
新创建的插件就报这个错: VM22 WAService.js:2 TypeError: WebAssembly.instantiate(): Argument 0 must be a buffer source or a WebAssembly.Module object 请问有什么解决办法没有?
2021-01-31 - WXWebAssembly.instantiate方法的第一个参数,如何通过远程下载本地实例化?
根据报错提示,第一个参数需要传入一个绝对路径的.wasm文件,如pages/index/hello.wasm 如果需要将远程的wasm下载到本地再实例化应该如何实现呢,报错明确提示了,不能以wxfile://或http的文件路径开头,所有还有其他读取存储后文件绝对路径的且获取出来不为wxfile:前缀的绝对路径,api可以调用吗? wasm资源文件超出了2m,希望可以走远程下载到本地再实例化 const info = {}; const cloudWasm = 'https://cdn.com/hello.wasm' wx.downloadFile({ url:cloudWasm, success:res=>{ const {tempFilePath} = res; // 如何将tempFilePath转成绝对路径呢? const fs = wx.getFileSystemManager(); const { env:{ USER_DATA_PATH } } = wx; // 当前用户设备的环境目录 const wasmfilename = tempFilePath.slice(tempFilePath.lastIndexOf('/') + 1);// 提取文件名和后缀 fs.saveFileSync(tempFilePath, wasmdir + wasmfilename); const wasmdir = USER_DATA_PATH + "/wasm/"; // 在当前用户环境下新建一个目录 const obsoluteWasmFilePath = `${tempFilePath}/${wasmfilename}`; WXWebAssembly.instantiate(obsoluteWasmFilePath,info).then(suc=>{ console.log('初始化成功') },err=>{ console.log('初始化失败') }) } } )
2021-04-07 - miniprogram-ci 这个小程序官方包 在引入第三方库时,调用上传命令会报错
官方文档: https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html 由于这个npm包代码未开源(代码压缩混淆了),没有相应的github 提bug区域,故此将bug提在这里 重现环境: miniprogram-ci 版本: 1.0.11、1.0.12 window10 企业版 64位系统 nodejs v10.16.3 npm 6.11.3 注意:mac os系统上没有此问题 最小可重现代码: https://github.com/bigmeow/miniprogram-ci-bug 重现步骤 1. 用小程序开发者工具新建立一个项目, npm init 2. 安装 `npm i @vant/weapp -S --production` 和 `npm i miniprogram-ci -D` 3. 编写 build.js, 修改其中的appid和私钥,后台关闭白名单 4. 运行命令 `node build.js` 问题 如果不引入第三方库,构建npm和上传都成功; 引入了第三方库,构建npm成功,上传失败报错;但是直接点击小程序开发者工具的上传则无问题 [图片] 报错代码: "miniprogram-ci": "1.0.11" 版本错误信息: (node:21612) UnhandledPromiseRejectionWarning: Error: ["usingComponents"]["van-icon"]: "../icon/ind ex" not found at Object.throwError (C:\project\github\bug\node_modules\miniprogram-ci\dist\utils\common.js:1: 274) at _checkComponentPath (C:\project\github\bug\node_modules\miniprogram-ci\dist\json\common.js:1 :2012) at Object.exports.checkComponentPath.t [as checkComponentPath] (C:\project\github\bug\node_modu les\miniprogram-ci\dist\json\common.js:1:2427) at checkComponentPath (C:\project\github\bug\node_modules\miniprogram-ci\dist\json\page\page.js :1:1537) at compilePageJSON (C:\project\github\bug\node_modules\miniprogram-ci\dist\json\page\page.js:1: 2249) (node:21612) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated e ither by throwing inside of an async function without a catch block, or by rejecting a promise whic h was not handled with .catch(). (rejection id: 1) (node:21612) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the futu re, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. "miniprogram-ci": "1.0.12" 、 "miniprogram-ci": "1.0.13"、 "miniprogram-ci": "1.0.14" 版本错误信息: (node:23640) UnhandledPromiseRejectionWarning: Error: ["usingComponents"]["van-icon"]: "../icon/index" not found at Object.throwError (C:\project\github\bug\node_modules\miniprogram-ci\dist\utils\common.js:1:274) at _checkComponentPath (C:\project\github\bug\node_modules\miniprogram-ci\dist\json\common.js:1:2120) at Object.exports.checkComponentPath.t [as checkComponentPath] (C:\project\github\bug\node_modules\miniprogram-ci\dist\json\common.js:1:2535) at checkComponentPath (C:\project\github\bug\node_modules\miniprogram-ci\dist\json\page\page.js:1:1537) at compilePageJSON (C:\project\github\bug\node_modules\miniprogram-ci\dist\json\page\page.js:1:2249) (node:23640) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:23640) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. 2020年03月31日0.05分更新: "miniprogram-ci": "1.0.18" 版本已经解决上述问题,又发现一个新的问题,在上传时打印的日志: [图片] 找到出解析出问题的那段: [图片] 是 第三库里的wxml文件里直接写wxs 才会出现?
2020-03-31 - 小程序链接生成与使用规则调整公告
各位开发者: 为确保小程序链接合理使用,自 2022 年 4 月 11 日起,URL Scheme 和 URL Link (以下统称为 “链接” )接口能力规则将进行以下调整: 每个 URL Scheme 或 URL Link 有效期最长 30 天,均不再支持永久有效的链接、不再区分短期有效链接与长期有效链接;链接生成后,若在微信外打开,用户可以在浏览器页面点击进入小程序。每个独立的链接被用户访问后,仅此用户可以再次访问并打开对应小程序,其他用户无法再次通过相同链接打开该小程序;单个小程序每天生成链接数(URL Scheme 和 URL Link 总数)上限为 50 万条。 对于上述 1,在开发层面,相应的服务端接口 urlscheme.generate 和 urllink.generate 将进行以下调整: is_expire 值固定为 true,可不再传该值,若传值为 false 也与 true 一样会生成到期失效链接;若 expire_type 传值为 0,需注意 expire_time 传值的时间戳不超过 30 天,即该参数最长传值有效期为 30 天;若 expire_type 传值为 1,需注意 expire_interval 传值范围为 [1, 30],即该参数最长传值间隔天数为 30。详细对比见下表: [图片] 已使用该后端接口的开发者可以不进行任何修改,不会出现返回异常。若传值超过新规则合法值,或声明使用永久有效的链接,则均会被赋最长有效期值(30天);需注意以上新规则生效后的有效期和访问规则变化。 在本次规则调整生效前已经生成的链接,也将自动生效以下规则: 如果有效期超过30天或长期会被降级为30天有效,开始时间从调整日期开始计算;在调整生效后,只能被1个用户访问。 当前已使用微信云开发 静态网站H5跳小程序 与 短信跳小程序、微信服务平台短信服务为用户提供链接的功能不受影响,但同样适用以上规则。 微信团队 2022年3月9日 相关QAQ1:每天下发的短信量级超过50万条,不够用怎么办? A1:可将生成 scheme 的时机改为在用户打开 H5 时再生成: [图片]
2023-09-26 - (17)分享功能调整背后的故事
有时候我们使用一个小程序会遇到以下情形: 我们打开一个小程序,就看见提示“分享到5个群,可以获得一张20元的优惠券”,吸引我们去无脑分享到不同的群里; 打开某个小游戏,提示我“一定要分享到xx个群,才能继续玩游戏”; …… 而我们在群里打开这类小程序,仍然是提示我分享的信息,这类功能无疑打断了我们对小程序/小游戏正常的功能使用。 我们收到了很多用户对这类小程序/小游戏的抱怨。这类分享并非是用户主动自发的,而是受到了某类利益的诱惑,或是被迫分享。这样的内容充斥在群里、小程序里,对用户造成了骚扰,是对分享功能的滥用。 在原来的分享接口中,用户发起分享动作之后,可以通过 success 、fail、complete等回调来判断用户是否完成了最后的分享动作。通过这个能力,开发者是可以将产品交互在分享这个能力上做得比较自然和顺畅。但却被上述情形的小程序滥用。在我们权衡了分享功能带来的利弊后,我们打算回收这个能力。调整为:我们将不再支持分享回调参数 success 、fail 、complete 。即开发者无法判断用户最终是否完成了分享动作,也无法获取到分享成功后的回调参数shareTicket 。 接下来将与大家介绍此次分享功能调整后,小程序的调整建议。 对应小程序调整建议 此次调整可能影响到两种分享功能的用法。 第一种:通过判断用户最终是否有分享来做分支逻辑的小程序。 例如,通过判断 success 回调触发,来判断用户是否分享出去了,进而给奖励,如果用户没有分享出去则不给奖励。这类功能是我们平台不倡导的,后续将没有办法实现。 如果是需要在分享完成后变更当前页面的状态,可以适当调整交互方案。例如过去赠送代金券后显示“等待领取”等应用场景,可以改成在分享后继续保留“赠送”按钮,但提示用户一个代金券只能被一人领取,重复赠送无效。 第二种:获取用户分享之后的 shareTicket ,换取群唯一标识 openGId ,进而显示对应群的相关信息的小程序。 例如,部分小程序实现了群内的排行信息,通过分享小程序到某个群里,可以查看该群内成员的排行榜。 此次调整后,用户分享完成后无法立刻显示该群的排行榜信息,但仍可在用户从群消息点击进入小程序时显示该群的排行榜信息。 因此建议适当修改产品流程,在用户分享小程序之时,提示用户可进入群内查看群排行等信息。避免调整策略生效之后带来的交互不完整影响。 调整覆盖范围提示 近期新提交的版本中将会受到此策略的影响。 除此之外,调整策略在即将发布的基础库版本 2.3.0 生效,该基础库版本对应本月即将发布的微信客户端版本(暂定版本号 6.7.2)。即:近期提交审核的小程序版本,在基础库版本 2.3.0 以下的环境中仍不受此策略影响,仅在基础库版本 2.3.0 以上的环境受影响。 开发者需要注意,近期提交审核的版本都需要考虑兼容上述调整带来的影响,请各位开发者及时调整分享能力。
2018-08-17 - 开发者工具总出现routeDone with a webviewId 错误?
routeDone with a webviewId 1070 that is not the current page(env: macOS,mp,1.06.2301040; lib: 2.29.0)
2023-01-15 - 基础库版本2.27.2 突然报错
[图片] 最新版的基础库突然报了 routeDone with a webviewId 206 that is not the current page 这个错,之前从来都没有出现过,但不影响运行,目前不知道是什么原因,求解答
2022-11-16 - 大佬们,这是报的个什么错,自从基础库升级到2.27.2以后?
自从升级到2.27.2基础库以后,每次编译都会报这个错,并且下面的报错中,数字6会随着编译一次增加1,是个什么情况啊? routeDone with a webviewId 6 that is not the current page(env: Windows,mp,1.06.2209190; lib: 2.27.2) [图片]
2022-11-17 - 渲染层错误 Expect END descriptor with depth
页面加载完成后,控制台出现报错“渲染层错误”,截图如下: [图片] 控制台报错日志: Error: Expect END descriptor with depth 0 but get another at i.value (:39360/__pageframe__/__dev__/WAWebview.js:1) at Function.G [as _startCb] (:39360/__pageframe__/__dev__/WAWebview.js:1) at n (:39360/__pageframe__/__dev__/WAWebview.js:1) at h (:39360/__pageframe__/__dev__/WAWebview.js:1) at :39360/__pageframe__/__dev__/WAWebview.js:1 at t.(:39360/appservice/anonymous function) (http://127.0.0.1:39360/__pageframe__/__dev__/WAWebview.js:1:94975) at :39360/__pageframe__/pageframe.html:1 at :39360/__pageframe__/pageframe.html:1 at :39360/__pageframe__/pageframe.html:1 at Array.forEach (<anonymous>) 今天抽时间查了下原因,主要发现了2个原因造成了这个错误: 1、.js中有个变量赋值没有做处理,把undefined赋值给了一个数组变量,假如这个数组变量名为arr, 然后又在.wxml页面中用了这个数组arr。 然后页面加载完成后控制台出现了这个“渲染层错误”。 处理变量赋值后,就 不报这个错了。 2、子组件中的一个if使用造成了,这个渲染层错误, 后面把这个if改成了通过style样式来控制。就不报这个错了。 截图对比一下: 控制台报“渲染层错误”代码:[图片] 改后不报错代码:[图片] 提出疑惑:为什么大部分地方使用if并没有报错,只是偶尔有个地方使用了if才在控制台报这个错? 这是什么原理呢?不清楚,求高手解答!
2019-05-09 - 开发者工具上传代码报错:Error: 系统错误,错误码:80082 ?
经测试剔除掉app.json中的插件引用后恢复正常(该插件有权限,已在后台添加,使用两年了),查查什么原因?
2023-02-16 - 上传错误,原因:Error: 系统错误,错误码:-80082
查了好多地方都不知道哪里出错一直提示 上传错误,原因:Error: 系统错误,错误码:-80082
2018-11-08 - 关于补充小程序、插件用户隐私保护指引说明
为进一步规范开发者的用户个人信息处理行为,保障用户合法权益,小程序、插件中涉及处理用户个人信息的开发者,无论是通过调用涉及用户个人信息的相关接口,还是自行收集用户个人信息,在提交代码版本前,均需补充相应用户隐私保护指引,具体如下: 一、 如小程序、插件有涉及收集用户个人信息(包含通过接口形式收集、通过非接口的形式收集)开发者需在【小程序管理后台-设置-功能设置-用户隐私保护指引】(如果是第三方开发者代开发小程序可通过接口进行配置)/【小程序管理后台-功能-小程序插件-基本设置-用户隐私保护说明】针对具体使用目的与用途进行说明填写,并补充完整隐私指引内容。 二、针对隐私指引说明内容,有如下要求: 1、隐私指引说明内容需与代码包内引用相关接口一致; 2、隐私指引说明内容文字表述需清晰、完整、告知用户处理相应信息的目的与用途; 3、在代码提审环节将对以上要求进行核验,如未满足相应要求,则无法通过代码版本审核,将影响开发者后续版本提审。 平台预计于11月1日对相关接口进行隐私指引说明审核,请开发者及时补充完善隐私指引说明,避免影响相关服务及用户体验。 微信团队 2021年10月29日
2023-09-26 - 《用户服务协议》及《隐私政策》怎么添加?
你好,你的小程序涉及收集、使用和存储用户个人信息,请增加《用户服务协议》及《隐私政策》,明确告知收集用户个人信息的使用目的、方式和用途 ,并取得用户授权同意后,才能获取用户收集用户个人信息。 是因为我获取了身份证号吗?是的话应该怎么添加呀?
2021-12-13 - 小程序如何跳转至微信浏览器?
个人开发者不能使用web-view,怎么能实现小程序跳转至微信内置浏览器打开网页呢! 小程序打开关联公众号文章,点击公众号的阅读原文即可打开微信内置浏览器,这儿是怎么实现的,应该在小程序中可以跳转到微信内置浏览器吧?
2022-04-07 - 社区专家用户&2022年度社区突出贡献者颁奖|社区与你 未来可期!
2022 年,社区与各位 “社友” 一起 许下新年愿望,一直 为女性开发者鼓舞,不时吐槽 与产品经理的相爱相杀故事,使用 开发者专属的方式有趣表达爱,分享自己的 开发者专属小故事。成为开发者不是一件容易的事情,但的确是一件值得自豪的事情! 这一年,各位 “社友” 真诚发问、认真回答,让社区充满「提问者认为该回答有用」、「官方认为该回答有用」的认可。每一个回答都是对开发者朋友的支持,每一行代码都是对专业技术的坚守,每一篇文章都是对代码知识的沉淀。 微信开放社区为社区专家用户以及突出贡献者们准备了年度答谢礼物,表彰与感谢他们对同路人的支持、对社区的贡献、对技术的致敬! 2023 年已经悄然而至,新的一年期待有更多的技术突破,更多元的技术交流,更高效的技术开发体验。社区与各位开发者一起码到成功,全年无 Bug!社区与你,未来可期! 社区专家用户 [图片] 2022 年度社区突出贡献者 注:每位个人突出贡献者获得 1 套新年礼包,每位企业突出贡献者获得 2 套新年礼包 青寒、拾忆、Memory、吴川市菜虫网络科技有限公司:2022 年共获得 12 次社区月度突出贡献者(排名不分先后) 社区将为以上 4 位突出贡献者分别颁发专属新年礼包,礼物包括: 微信相框、微信旺盛礼盒、微信旺柴三件套、跳一跳运动套装、语音条抱枕、微信开放社区突出贡献者红包封面 [图片] 进狱系明星经纪人、小黎、Mr.Zhao、上海微盟企业有限公司:2022 年共获得 9 次社区月度突出贡献者(排名不分先后) 社区将为以上 4 位突出贡献者分别颁发专属新年礼包,礼物包括: 好事成双茶具、微信旺盛礼盒、微信旺柴三件套、语音条抱枕、微信开放社区突出贡献者红包封面 [图片] 立十、四哥派、brave、北京热点互动教育科技有限公司:2022 年共获得 6 次及以上社区月度突出贡献者(排名不分先后) 社区将为以上 4 位突出贡献者分别颁发专属新年礼包,礼物包括: 跳一跳运动套装、微信旺盛礼盒、微信旺柴三件套、语音条抱枕、微信开放社区突出贡献者红包封面 [图片] 八九、陈宇明、读书人。、老张、茜茜又困了🐽、圣殿骑士、一笑皆春、Charlie、Hlxuan.、Jianbo、v、杭州起码科技有限公司、临沂维百特网络科技有限公司、上海微喵网络科技有限公司、西安众邦网络科技有限公司、辛集启年网络科技有限公司:2022 年获得过社区月度突出贡献者(排名不分先后) 社区将为以上 16 位突出贡献者分别颁发专属新年礼包,礼物包括: 微信旺柴三件套、微信开放社区突出贡献者红包封面 [图片] 具体实物礼物款式可能有细微调整,以实物为准,预计 1 个月内联系发出。 微信团队 2023年01月16日
2023-01-16 - 构建npm包时报错(SyntaxError: Unexpected token )?
npm install p-limit安装好后,在构建npm时报错SyntaxError: Unexpected token (28:10) p-limit: index.js import Queue from 'yocto-queue'; export default function pLimit (concurrency) { if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) { throw new TypeError('Expected `concurrency` to be a number from 1 and up'); } const queue = new Queue(); let activeCount = 0; const next = () => { activeCount--; if (queue.size > 0) { queue.dequeue()(); } }; const run = async (fn, resolve, args) => { activeCount++; const result = (async () => fn(...args))(); resolve(result); try { await result; } catch { } next(); }; const enqueue = (fn, resolve, args) => { queue.enqueue(run.bind(undefined, fn, resolve, args)); (async () => { // This function needs to wait until the next microtask before comparing // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously // when the run function is dequeued and called. The comparison in the if-statement // needs to happen asynchronously as well to get an up-to-date value for `activeCount`. await Promise.resolve(); if (activeCount < concurrency && queue.size > 0) { queue.dequeue()(); } })(); }; const generator = (fn, ...args) => new Promise(resolve => { enqueue(fn, resolve, args); }); Object.defineProperties(generator, { activeCount: { get: () => activeCount, }, pendingCount: { get: () => queue.size, }, clearQueue: { value: () => { queue.clear(); }, }, }); return generator; } yocto-queue: index.js /* How it works: `this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value. */ class Node { value; next; constructor(value) { this.value = value; } } export default class Queue { #head; #tail; #size; constructor() { this.clear(); } enqueue(value) { const node = new Node(value); if (this.#head) { this.#tail.next = node; this.#tail = node; } else { this.#head = node; this.#tail = node; } this.#size++; } dequeue() { const current = this.#head; if (!current) { return; } this.#head = this.#head.next; this.#size--; return current.value; } clear() { this.#head = undefined; this.#tail = undefined; this.#size = 0; } get size() { return this.#size; } * [Symbol.iterator]() { let current = this.#head; while (current) { yield current.value; current = current.next; } } }
2021-11-25 - 构建npm报错message:发生错误 SyntaxError: Unexpected token
构建npm报错message:发生错误 SyntaxError: Unexpected token
2021-05-20 - 【干货】微信内置浏览器缓存清理
之前做过很多公众号的项目,项目写完后给客户看项目,客户一而再再而三的修改元素向左挪1px,向右挪2px。改好之后让客户看,客户说我特泽发克,你啥都没有修改,你竟然骗我!!! 这其实就是微信内置浏览器的缓存在作祟啦,那么如何清理微信内置浏览器的缓存呢? 你们是否知道 ios版微信 和 android版微信 的内置浏览器的内核是不一样的呢? android版微信内置浏览器(X5内核) 在安卓版微信内打开链接 http://debugx5.qq.com 拉到调试页面的最底端,勾选上所有的缓存项目,点击清除。 [图片] 点击确定之后即可完成清除微信浏览器缓存的操作。 ios版微信内置浏览器(WKWebView) ios版微信内置浏览器内核并不是 X5内核,而是使用的ios的浏览器内核WKWebView,所以安卓手机的那种方案对ios手机用户不生效,因为那个链接压根打不开 只要微信用户退出登录,然后重新登录,ios版微信内置浏览器内核即可清除,不行的话,你们回来打我 有人说了:“IOS中 设置—通用----存储空间 就会看到“正在计算空间”计算完了会清理一点清理即可”,这种办法当然也可以,但是这种办法不光是清理微信内置浏览器的缓存,同时也清理其他的一些数据,比如朋友圈的视频图片和聊天记录等等缓存,而且容易误删某些想留下的数据,对于开发而言,我认为退出重新登录是最好的解决办法。
2020-01-08 - miniprogram-ci 下载 sourcemap 报错
使用 miniprogram-ci 下载 sourcemap 经常报下述错误: download source map failed: resp body is not a valid json 应该是下载超时导致,但是 ci.getDevSourceMap 并没有提供控制超时时间的选项。 另外,sourcemap 下载时,既下了__FULL__,又下了各个包单独的,但一般情况下用户只会二选一取用。可否提供选项忽略或者指定下载哪些包的 sourcemap。
2020-08-30 - 小程序setData
setData setData 是小程序开发中使用最频繁的接口,也是最容易引发性能问题的接口。 Object 以 key: value 的形式表示,将 this.data 中的 key 对应的值改变成 value。 具体的介绍请看微信开发文档:https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips.html 注意: 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。 this.setData 两种情况赋值 触发渲染 页面 xxx.js 中 data 的数据 [代码]lunList: [[代码][代码] [代码][代码]{ id: 0, [代码][代码]choose: [代码][代码]false[代码][代码], [代码][代码]},[代码][代码] [代码][代码]{ id: 1, [代码][代码]choose: [代码][代码]false[代码][代码], [代码][代码]},[代码][代码] [代码][代码]{ id: 2, [代码][代码]choose: [代码][代码]false[代码][代码], [代码][代码]}[代码][代码] [代码][代码]][代码][代码]showlun: [代码][代码]function[代码] [代码](e) {[代码][代码] [代码][代码]var[代码] [代码]_this = [代码][代码]this[代码][代码], index = e.currentTarget.dataset.id;[代码][代码] [代码][代码]console.log(e, index) [代码][代码]//index,表示点击的第几个索引[代码][代码] [代码][代码]if[代码] [代码](_this.data.lunList[index].choose == [代码][代码]false[代码][代码]) {[代码][代码] [代码][代码]_this.data.lunList[index].choose=[代码][代码]true[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]_this.data.lunList[index].choose=[代码][代码]false[代码][代码] [代码][代码]}[代码][代码] [代码][代码]_this.setData({[代码][代码] [代码][代码]lunList:_this.data.lunList[代码][代码] [代码][代码]})[代码][代码] [代码][代码]console.log(_this.data.lunList)[代码][代码] [代码][代码]}[代码]ps:数据一旦过大,再js中操作整个数据渲染页面 [代码]showlun: [代码][代码]function[代码] [代码](e) {[代码][代码] [代码][代码]var[代码] [代码]_this = [代码][代码]this[代码][代码], index = e.currentTarget.dataset.id;[代码][代码] [代码][代码]console.log(e, index)[代码][代码] [代码][代码]//重点 字符串组合的形式, this.setData 自动识别为 ["lunList[2].choose"] 这样直接操作 数据中的某一项直接赋值[代码][代码] [代码][代码]var[代码] [代码]ss = [代码][代码]'lunList['[代码] [代码]+ index + [代码][代码]'].choose'[代码] [代码] [代码][代码]if[代码] [代码](_this.data.lunList[index].choose == [代码][代码]false[代码][代码]) {[代码][代码] [代码][代码]_this.setData({[代码][代码] [代码][代码][ss]: [代码][代码]true[代码][代码] [代码][代码]})[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]_this.setData({[代码][代码] [代码][代码][ss]: [代码][代码]false[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}[代码][代码] [代码][代码]console.log(_this.data.lunList)[代码][代码] [代码][代码]}[代码]ps:对于对象或数组字段,可以直接修改一个其下的子字段,这样做通常比修改整个对象或数组更好
2019-06-21 - miniprogram-ci上传小程序经常失败20003 statusCode: 50,什么原因呢?
通过miniprogram-ci 调用preview upload时,经常上传失败。周五失败频率更高。 上传请求如下: request url: https://servicewechat.com/wxa/ci/testSourceURL?codeprotect=0&type=miniProgram&appid=wxffb7d80f8c50ac5c&version=0.0.1&desc=%E5%BC%80%E5%8F%91%E7%89%88-%E5%BC%80%E5%8F%91%E7%89%88&robot=2&path=pages%2Fhome%2Fhome%3Fa%3D1&debugLaunchInfo=%7B%22scene%22%3A1011%2C%22path%22%3A%22pages%2Fhome%2Fhome%22%2C%22query%22%3A%7B%22a%22%3A%221%22%7D%7D 错误日志如下: Error: {"errCode":-1,"errMsg":"inner test source fail statusCode: 503"} at innerUpload (/usr/lib/node_modules/@jd/minici/node_modules/miniprogram-ci/dist/ci/upload.js:1:3517) at processTicksAndRejections (internal/process/task_queues.js:93:5) at async preview (/usr/lib/node_modules/@jd/minici/node_modules/miniprogram-ci/dist/ci/preview.js:1:977) at async Object.preview (/usr/lib/node_modules/@jd/minici/node_modules/miniprogram-ci/dist/utils/report.js:1:1403)
2022-01-07 - web-view中调用websocket,ios13以上onerror报错isTrusted?
下面是js代码 socket = new WebSocket(uri); socket.onopen = function () { console.log("connected to " + uri); } socket.onclose = function (e) { console.log("connection closed (" + e.code + ")"); } socket.onmessage = function (e) { console.log("message received: " + e.data); } socket.onerror = function (e) { alert(JSON.stringify(e));//这里报错{"isTrusted":"true"} console.log("error"); }
2021-09-07 - ipad下getSystemInfoSync获取的信息始终不变
在ipad中,我写入下列代码 [代码]App({[代码][代码] [代码][代码]onShow() {[代码][代码] [代码][代码]wx.getSystemInfo({[代码][代码] [代码][代码]success(res) {[代码][代码] [代码][代码]console.log(res);[代码][代码] [代码][代码]}[代码][代码] [代码][代码]});[代码][代码] [代码][代码]},[代码][代码]})[代码] 我通过横屏进入时,打印下列值: { SDKVersion:"2.6.4" albumAuthorized:true batteryLevel:43 bluetoothEnabled:false brand:"iPhone" cameraAuthorized:true deviceOrientation:"landscape" errMsg:"getSystemInfo:ok" fontSizeSetting:17 language:"zh_CN" locationAuthorized:true locationEnabled:true microphoneAuthorized:true model:"iPad Air 2 (WiFi)<iPad5,3>" notificationAlertAuthorized:true notificationAuthorized:true notificationBadgeAuthorized:true notificationSoundAuthorized:true pixelRatio:2 platform:"ios" screenHeight:768 screenWidth:1024 statusBarHeight:20 system:"iOS 12.1.4" version:"7.0.3" wifiEnabled:true windowHeight:698 windowWidth:1024 } 然后我隐藏,通过竖屏进入时,返回的对象完全相同,也就是说`windowHeight`和`windowWidth`在屏幕方向改变时并不会变化,`deviceOrientation`也是,似乎这些信息在载入小程序后就完全固定了
2019-03-22 - 关于 wx.getSystemInfoSync() 的属性 wifiEnabled 状态不正确
1: 打开wifi,执行代码 console.log('sys info: ', wx.getSystemInfoSync())输出 : [图片] 2: 关闭wifi 执行代码 console.log('sys info: ', wx.getSystemInfoSync())输出 : [图片]
2021-03-09 - 更新了一下工具导入项目报错了?
昨晚更新完开发者工具后打开以前的小程序项目后报错,打不开了 [图片] [图片] 报了这种错误:UNKNOWN ERROR: TypeError [ERR_INVALID_PROTOCOL]: Protocol"http:" not supported. Expected "https:" 换了三个项目都是报了同样的错误
2021-01-09 - 使用wx.request请求接口为什么提示600001?
使用getPhoneNumber组件获取到相关信息后传给后台接口授权,接口提示600001,在真机中才会,在开发工具不会[图片][图片]
2022-08-15 - 小程序有没有办法在内嵌h5中 使用百度地图
小程序有没有办法在内嵌h5中 使用百度地图?
2019-03-13 - 公众号关联小程序上限是多少?
目前只看到每个月可以关联一共13个小程序,但是总数是多少有限制吗,是否这个月关联了13个,下个月还可以关联新的13个?
2021-03-25 - ENOENT: no such file or directory?
使用开发者工具进行上传时候遇到的问题,应该是文件或目录不存在的问题,但是报错信息显示的不是一个路径而是一整段代码,有没有大神知道这是怎么回事? [图片] Error: ENOENT: no such file or directory, open ''use strict'; //app.js App({ onLaunch: function onLaunch() { var _this = this; // 展示本地存储能力 var logs = wx.getStorageSync('logs') || []; logs.unshift(Date.now()); wx.setStorageSync('logs', logs); // 登录 wx.login({ success: function success(res) { // 发送 res.code 到后台换取 openId, sessionKey, unionId } }); // 获取用户信息 wx.getSetting({ success: function success(res) { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: function success(res) { // 可以将 res 发送给后台解码出 unionId _this.globalData.userInfo = res.userInfo; // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (_this.userInfoReadyCallback) { _this.userInfoReadyCallback(res); } } }); } } }); }, globalData: { userInfo: null } });'
2019-08-07 - Failed to load resource: net::
今天一直好好的。。。ide突然报了这个错,官方的samplecode 也是这个错 Failed to load resource: net::ERR_NAME_NOT_RESOLVED
2017-01-12 - 小程序打开一个外部H5页面,不用web-view能否实现?
在小程序内部点击按钮要关闭当前小程序。在打开一个h5页面。不用web-view 能否实现?
2021-11-11 - 关于微信 OpenSDK 适配 iOS 16 系统的说明
背景微信 iOS OpenSDK 通过剪切板在应用和微信间进行数据传递,在用户同意后完成授权登录、分享等功能。具体说明如下: 1、应用通过 OpenSDK 跳转到微信。在应用内,OpenSDK 会将业务数据写入剪切板;然后在拉起微信后,微信从剪切板中读出业务数据,完成相关功能; 2、微信完成相关功能后,微信将相关业务数据(例如授权登录结果、错误信息等)写入剪切板,然后跳转回应用。在应用内,OpenSDK 从剪切板中读出数据,回调给开发者。 在 iOS 16 系统上,读取其它应用写入剪切板的数据时,系统会阻塞调用,弹窗提示,让用户手动选择是否允许读取。如下图所示: [图片] [图片] 为了提升用户体验,微信和 OpenSDK 进行数据传输方式的改造,尽量避免使用剪切板传递数据。具体说明如下: 1、对于一般传输数据的接口,会在 Scheme 或者 Universal Link 中携带相关数据; 2、对因传输数据量较大等原因无法使用上述数据传输方式的接口,保持通过剪切板传递数据。 因此,开发者需要应用升级 OpenSDK,并配合微信客户端 8.0.24 及以上版本使用。 升级指引为了支持在 Scheme 或者 Universal Link 传递数据,微信客户端版本要求 8.0.24 及以上,OpenSDK 版本要求 1.9.6 及以上,需要微信客户端版本和 OpenSDK 版本同时满足要求。 当前 OpenSDK 版本低于 1.8.6若原有集成的 OpenSDK 版本低于 1.8.6,请先参考 OpenSDK 接入指南,完成 Universal Link 跳转方式的接入。然后按照下述内容,继续接入剪切板适配功能。 当前 OpenSDK 版本大于等于 1.8.6更新 OpenSDK 版本后,在 Xcode 中,选择你的工程设置项 -> 选中 “TARGETS” 一栏 -> 找到 “info” 标签栏的 “LSApplicationQueriesSchemes” -> 在原有 weixin 和 weixinULAPI 的基础上,添加 weixinURLParamsAPI。如下图所示: [图片] 新增读取剪切板控制能力集成 1.9.6 及以上版本的 OpenSDK 后,仍需要读取剪切板数据的情况有以下 2 种: 1、旧版本兼容:从版本低于 8.0.24 的微信客户端跳转到应用; 2、因数据量较大等原因无法在 Scheme 或者 Universal Link 传递。 为了提升用户体验,在 iOS 16 系统上,OpenSDK 将在读取剪切板前请求开发者授权,由开发者自行决定是否允许 OpenSDK 读取剪切板中的业务数据以及何时进行剪切板业务数据读取。 WXApiDelegate 接口在原有 WXApiDelegate 协议上,新增 onNeedGrantReadPasteBoardPermissionWithURL:completion 函数,用于 iOS 16 及以上的系统,控制 OpenSDK 剪切板的读取。 示例代码如下: @protocol WXApiDelegate @optional - (void)onReq:(BaseReq*)req; - (void)onResp:(BaseResp*)resp; /* ! @brief 用于在iOS16以及以上系统上,控制OpenSDK是否读取剪切板中微信传递的数据以及读取的时机 * 在iOS16以及以上系统,在SDK需要读取剪切板中微信写入的数据时,会回调该方法。没有实现默认会直接读取微信通过剪切板传递过来的数据 * 注意: * 1. 只在iOS16以及以上的系统版本上回调; * 2. 不实现时,OpenSDK会直接调用读取剪切板接口,读取微信传递过来的数据; * 3. 若实现该方法:开发者需要通过调用completion(), 支持异步,通知SDK允许读取剪切板中微信传递的数据, * 不调用completion()则代表不授权OpenSDK读取剪切板,会导致收不到onReq:, onResp:回调,无法后续业务流程。请谨慎使用 * 4. 不要长时间持有completion不释放,可能会导致内存泄漏。 */ - (void)onNeedGrantReadPasteBoardPermissionWithURL:(nonnull NSURL *)openURL completion: (nonnull WXGrantReadPasteBoardPermissionCompletion)completion; @end 若不实现 onNeedGrantReadPasteBoardPermissionWithURL:completion 函数,OpenSDK 在需要读取剪切板时,直接调用读取剪切板接口,读取微信传递过来的数据,用于回调通知 onReq: 和 onResp:。 若实现 onNeedGrantReadPasteBoardPermissionWithURL:completion 函数,开发者需要通过调用 completion(),通知 SDK 允许读取剪切板中微信传递的数据, 支持异步。 实现函数后,如果不调用 completion() 通知 OpenSDK 读取剪切板,将收不到 onReq: 或者 onResp: 回调,请谨慎操作! 示例代码如下: - (void)onNeedGrantReadPasteBoardPermissionWithURL:(NSURL *)openURL completion: (WXGrantReadPasteBoardPermissionCompletion)completion { //开发者可展示相关UI提示用户 [self showReadPasteBoardNotice]; //允许OpenSDK读取剪切板 dispatch_after(delayTime, dispatch_get_main_queue(), ^{ completion(); }); } 微信团队 2022年7月18日
2022-07-18 - 如何在Page里获取到 app.json里面的数据
小程序启动后,app.json是被加载到哪个变量里了,我需要取出来读取. 有懂的说一下吗
2018-06-21 - js获取app.json里的数据
app.json里面配置了tabbar的list数组,在js里能有办法获取到吗?我想判断在页面中根据this.route判断它是不是tabbar里面配置的页面
2018-04-12 - 2021/12/30 升级到最新版本,小程序预览报错,怎么回事? 之前是好的。
2021/12/30 升级到最新版本,小程序预览报错 [图片] message:Error: miniprogram/app.js: file: app.js Cannot find module '@babel/plugin-proposal-private-methods' Require stack: - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\8e3c9a4c80bda5bf8b2d5f0dc11b0f27\WeappCode\package.nw\js\common\compiler\utils\babel_helper.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\8e3c9a4c80bda5bf8b2d5f0dc11b0f27\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\compilejs.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\8e3c9a4c80bda5bf8b2d5f0dc11b0f27\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\index.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\8e3c9a4c80bda5bf8b2d5f0dc11b0f27\WeappCode\package.nw\js\common\compiler\core\worker_thread\worker.js appid: wxc1aac5a39469910e openid: o6zAJsyz1lP43Nu4pXMKsFBOVjzY ideVersion: 1.05.2112292 osType: win32-x64 time: 2021-12-30 10:09:53
2021-12-30 - 更新新建项目报错
今天更新开发者工具,新建项目报错,报错内容如下: app.js错误: Error: module "app.js" is not defined at require (VM13 WAService.js:2) at <anonymous>:7:9 at doWhenAllScriptLoaded (appservice?t=1640829246817:1199) at HTMLScriptElement.scriptLoaded (appservice?t=1640829246817:1227) at HTMLScriptElement.script.onload (appservice?t=1640829246817:1236)(env: Windows,mp,1.05.2112292; lib: 2.17.0) (anonymous) @ VM24:9 doWhenAllScriptLoaded @ appservice?t=1640829246817:1199 scriptLoaded @ appservice?t=1640829246817:1227 script.onload @ appservice?t=1640829246817:1236 load (async) (anonymous) @ appservice?t=1640829246817:1235 (anonymous) @ appservice?t=1640829246817:1277 VM13 WAService.js:2 Error: module "app.js" is not defined at require (VM13 WAService.js:2) at <anonymous>:7:9 at doWhenAllScriptLoaded (appservice?t=1640829246817:1199) at HTMLScriptElement.scriptLoaded (appservice?t=1640829246817:1227) at HTMLScriptElement.script.onload (appservice?t=1640829246817:1236)(env: Windows,mp,1.05.2112292; lib: 2.17.0) errorReport @ VM13 WAService.js:2 thirdErrorReport @ VM13 WAService.js:2 (anonymous) @ VM13 WAService.js:2 f @ VM13 WAService.js:2 s @ VM13 WAService.js:2 c @ VM12 asdebug.js:1 window.onerror @ VM8:10 doWhenAllScriptLoaded @ appservice?t=1640829246817:1199 scriptLoaded @ appservice?t=1640829246817:1227 script.onload @ appservice?t=1640829246817:1236 error (async) t.default @ VM8:10 (anonymous) @ VM8:10 n @ VM8:1 (anonymous) @ VM8:1 (anonymous) @ VM8:1 VM13 WAService.js:2 Error: module "app.js" is not defined at require (VM13 WAService.js:2) at <anonymous>:7:9 at doWhenAllScriptLoaded (appservice?t=1640829246817:1199) at HTMLScriptElement.scriptLoaded (appservice?t=1640829246817:1227) at HTMLScriptElement.script.onload (appservice?t=1640829246817:1236)(env: Windows,mp,1.05.2112292; lib: 2.17.0) errorReport @ VM13 WAService.js:2 thirdErrorReport @ VM13 WAService.js:2 (anonymous) @ VM13 WAService.js:2 f @ VM13 WAService.js:2 s @ VM13 WAService.js:2 (anonymous) @ VM13 WAService.js:2 value @ VM13 WAService.js:2 (anonymous) @ VM13 WAService.js:2 doWhenAllScriptLoaded @ appservice?t=1640829246817:1199 scriptLoaded @ appservice?t=1640829246817:1227 script.onload @ appservice?t=1640829246817:1236 error (async) (anonymous) @ VM13 WAService.js:2 (anonymous) @ VM13 WAService.js:2 (anonymous) @ VM13 WAService.js:2 2[sitemap 索引情况提示] 根据 sitemap 的规则[0],当前页面 [pages/index/index] 将被索引 [ appservice 生成错误] utils/util.js: file: utils/util.js Cannot find module '@babel/plugin-proposal-private-methods' Require stack: - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\utils\babel_helper.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\compilejs.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\index.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\worker.js(env: Windows,mp,1.05.2112292; lib: 2.17.0) [ appservice 生成错误] app.js: file: app.js Cannot find module '@babel/plugin-proposal-private-methods' Require stack: - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\utils\babel_helper.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\compilejs.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\index.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\worker.js(env: Windows,mp,1.05.2112292; lib: 2.17.0) [ appservice 生成错误] pages/index/index.js: file: pages/index/index.js Cannot find module '@babel/plugin-proposal-private-methods' Require stack: - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\utils\babel_helper.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\compilejs.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\index.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\worker.js(env: Windows,mp,1.05.2112292; lib: 2.17.0) [ appservice 生成错误] pages/logs/logs.js: file: pages/logs/logs.js Cannot find module '@babel/plugin-proposal-private-methods' Require stack: - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\utils\babel_helper.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\compilejs.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\index.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\worker.js(env: Windows,mp,1.05.2112292; lib: 2.17.0) [ appservice 生成错误] .eslintrc.js: file: .eslintrc.js Cannot find module '@babel/plugin-proposal-private-methods' Require stack: - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\utils\babel_helper.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\compilejs.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\task\index.js - C:\Users\Administrator\AppData\Local\微信开发者工具\User Data\2a1954bbe6cd9e8fe4f1f171d120c9ea\WeappCode\package.nw\js\common\compiler\core\worker_thread\worker.js(env: Windows,mp,1.05.2112292; lib: 2.17.0) Page "pages/index/index" has not been registered yet.
2021-12-30 - “右滑手势返回”能力调整
各位开发者,大家好。 为了提升用户操作的流畅性,同时让用户在微信内拥有一致的操作体验,“右滑手势返回”将成为基础配置,即所有小程序内都可以从屏幕左侧边缘向右滑动返回上一个界面。 在即将发布的7.0.5客户端版本中,页面配置中的 [代码]disableSwipeBack[代码] 属性将不再生效,请开发者及时调整。
2019-05-31 - 上传时报错,请问是什么原因?Unexpected token o in JSON at positi
message:SyntaxError: Unexpected token o in JSON at position 1 appid: wx************0c80 openid: o6z****************************098AzU ideVersion: 1.06.2204182 osType: win32-x64 time: 2022-04-26 13:03:43
2022-04-26 - wx.createSelectorQuery(),获取元素的高度,获取到不准确为什么?
[图片][图片]
2019-09-20 - 请问小程序内嵌H5可以跳转到其他小程序吗?
在A小程序内嵌的H5页面,可否跳转到B小程序呢?
2021-02-22 - 微信小程序可以用lottie动画吗?
安卓和IOS版本里部分动画是用lottie实现的,小程序可以使用lottie的json文件吗?
2018-11-19 - Lottie-前端实现AE动效
项目背景 在海外项目中,为了优化用户体验加入了几处微交互动画,实现方式是设计输出合成的雪碧图,前端通过序列帧实现动画效果: [图片] 序列帧: [图片] 动画效果: [图片] 序列帧: [图片] 帧动画的缺点和局限性比较明显,合成的雪碧图文件大,且在不同屏幕分辨率下可能会失真。经调研发现,Lottie是个简单、高效且性能高的动画方案。 Lottie是可应用于Android, iOS, Web和Windows的库,通过Bodymovin解析AE动画,并导出可在移动端和web端渲染动画的json文件。换言之,设计师用AE把动画效果做出来,再用Bodymovin导出相应地json文件给到前端,前端使用Lottie库就可以实现动画效果。 [图片] Bodymovin插件的安装与使用 关闭AE 下载并安装ZXP installer https://aescripts.com/learn/zxp-installer/ 下载最新版bodymovin插件 https://github.com/airbnb/lottie-web/blob/master/build/extension/bodymovin.zxp 把下载好的bodymovin.zxp拖到ZXP installer [图片] 打开AE,在菜单首选项->常规中勾选☑️允许脚本写入文件和访问网络(否则输出JSON文件时会失败) [图片] 在AE中制作动画,打开菜单窗口->拓展->Bodymovin,勾选要输出的动画,并设置输出文件目录,点击render [图片] 打开输出目录会看到生成的JSON文件,若动画里导入了外部图片,则会在images中存放JSON中引用的图片 前端使用lottie 静态URL https://cdnjs.com/libraries/lottie-web NPM [代码]npm install lottie-web [代码] 调用loadAnimation [代码]lottie.loadAnimation({ container: element, // 容器节点 renderer: 'svg', loop: true, autoplay: true, path: 'data.json' // JSON文件路径 }); [代码] vue-lottie 也可以在vue中使用lottie [代码] import lottie from '../lib/lottie'; import * as favAnmData from '../../raw/fav.json'; export default { props: { options: { type: Object, required: true }, height: Number, width: Number, }, data () { return { style: { width: this.width ? `${this.width}px` : '100%', height: this.height ? `${this.height}px` : '100%', overflow: 'hidden', margin: '0 auto' } } }, mounted () { this.anim = lottie.loadAnimation({ container: this.$refs.lavContainer, renderer: 'svg', loop: this.options.loop !== false, autoplay: this.options.autoplay !== false, animationData: favAnmData, assetsPath: this.options.assetsPath, rendererSettings: this.options.rendererSettings } ); this.$emit('animCreated', this.anim) } } [代码] loadAnimation参数 参数名 描述 container 用于渲染动画的HTML元素,需确保在调用loadAnimation时该元素已存在 renderer 渲染器,可选值为’svg’(默认值)/‘canvas’/‘html’。svg支持的功能最多,但html的性能更好且支持3d图层。各选项值支持的功能列表在此 loop 默认值为true。可传递需要循环的特定次数 autoplay 自动播放 path JSON文件路径 animationData JSON数据,与path互斥 name 传递该参数后,可在之后通过lottie命令引用该动画实例 rendererSettings 可传递给renderer实例的特定设置,具体可看 Lottie动画监听 Lottie提供了用于监听动画执行情况的事件: complete loopComplete enterFrame segmentStart config_ready(初始配置完成) data_ready(所有动画数据加载完成) DOMLoaded(元素已添加到DOM节点) destroy 可使用addEventListener监听事件 [代码]// 动画播放完成触发 anm.addEventListener('complete', anmLoaded); // 当前循环播放完成触发 anm.addEventListener('loopComplete', anmComplete); // 播放一帧动画的时候触发 anm.addEventListener('enterFrame', enterFrame); [代码] 控制动画播放速度和进度 可使用anm.pause和anm.play暂停和播放动画,调用anm.stop则会停止动画播放并回到动画第一帧的画面。 使用anm.setSpeed(speed)可调节动画速度,而anm.goToAndStop(value, isFrame)和anm.goToAndPlay可控制播放特定帧数,也可结合anm.totalFrames控制进度百分比,比如可传anm.totalFrames - 1跳到最后一帧。 [代码]anm.goToAndStop(anm.totalFrames - 1, 1); [代码] 这样的好处是可以把相关联的JSON文件合并,通过anm.goToAndPlay控制动画状态的切换,如下图例中一个JSON文件包含了2个动画状态的数据: [图片] 图片资源 JSON文件里assets设置了对图片的引用: [图片] 若想统一修改静态资源路径或者设置成绝对路径,可在调用loadAnimation时传入assetsPath参数: [代码]lottie.loadAnimation({ container: element, renderer: 'svg', path: 'data.json', assetsPath: 'URL' // 静态资源绝对路径 }); [代码] 功能支持列表 即使用bodymovin成功输出了JSON文件(没有报错),也会出现动效不如预期的情况,比如这是在AE中构建的形象图: [图片] 但在页面中渲染效果是这样的: [图片] 这是因为使用了不支持的Merge Paths功能 [图片] 因此对设计师而言,创建Lottie动画和往常制作AE动画有所不同,此文档记录了Bodymovin支持输出的AE功能列表,动画制作前需跟设计师沟通好,根据动画加载平台来确认可使用的AE功能。 除此之外,尽量遵循官方文档里对设计过程的指导和建议: 动画简单化。创建动画时需时刻记着保持JSON文件的精简,比如尽可能地绑定父子关系,在相似的图层上复制相同的关键帧会增加额外的代码,尽量不使用占用空间最多的路径关键帧动画。诸如自动跟踪描绘、颤动之类的技术会使得JSON文件变得非常大且耗性能。 建立形状图层。将AI、EPS、SVG和PDF等资源转换成形状图层否则无法在Lottie中正常使用,转换好后注意删除该资源以防被导出到JSON文件。 设置尺寸。在AE中可设置合成尺寸为任意大小,但需确保导出时合成尺寸和资源尺寸大小保持一致。 不使用表达式和特效。Lottie暂不支持。 注意遮罩尺寸。若使用alpha遮罩,遮照的大小会对性能产生很大的影响。尽可能地把遮罩尺寸维持到最小。 动画调试。若输出动画破损,通过每次导出特定图层来调试出哪些图层出了问题。然后在github中附上该图层文件提交问题,选择用其他方式重构该图层。 不使用混合模式和亮度蒙版。 不添加图层样式。 全屏动画。设置比想要支持的最宽屏幕更宽的导出尺寸。 设置空白对象。若使用空白对象,需确保勾选可见并设置透明度为0%否则不会被导出到JSON文件。 预览效果 由于以上所说的功能支持问题会导致输出动画效果不确定性,设计师和前端之间有个动画效果联调的过程,为了提高联调效率,设计师可先进行初步的效果预览,再把文件交付给前端。 方法1:输出预览HTML文件 渲染前设置所要渲染的文件 [图片] 勾选☑️Demo选项 [图片] 在输出的文件目录中就可找到可预览的demo.html文件 方法2:LottieFiles分享平台 把生成的JSON文件传到LottieFiles平台,可播放、暂停生成文件的动画效果,可设置图层颜色、动画速度,也可以下载lottie preview客户端在iOS或Android机子上预览。 [图片] LottieFiles平台还提供了很多线上公开的Lottie动画效果,可直接下载JSON文件使用 [图片] 交互hack Lottie的不足之处是没有对应的API操纵动画层,若想做更细化的动画处理,只能直接操作节点来实现。比如当播放完左图动画进入惊讶状态后,若想实现右图随鼠标移动而控制动画层的简单效果: [图片][图片] 开启调试面板可以看到,lottie-web通过使用<g>标签的transform属性来控制动画: [图片] 当元素已添加到DOM节点,找到想要控制的<g>标签,提取其transform属性的矩阵值,并使用rematrix解析矩阵值。 [代码]onIntroDone() { const Gs = this.refs.svg.querySelectorAll('svg > g > g > g'); Gs.forEach((node, i) => { // 过滤需要修改的节点 ... // 获取transform属性值 const styleArr = node.getAttribute('transform').split(','); styleArr[0] = styleArr[0].replace('matrix(', ''); styleArr[5] = styleArr[5].replace(')', ''); const style = `matrix(${styleArr[0]}, ${styleArr[1]}, ${styleArr[2]}, ${styleArr[3]}, ${styleArr[4]}, ${styleArr[5]})`; // 使用Rematrix解析 const transform = Rematrix.parse(style); this.matrices.push({ node, transform, prevTransform: transform }); } } [代码] 监听鼠标移动,设置新的transform属性值。 [代码]onMouseMove = (e) => { this.mouseCoords.x = e.clientX || e.pageX; this.mouseCoords.y = e.clientY || e.pageY; let x = this.mouseCoords.x - (this.props.browser.width / 2); let y = this.mouseCoords.y - (this.props.browser.height / 2); const diffX = (this.mouseCoords.prevX - x); const diffY = (this.mouseCoords.prevY - y); this.mouseCoords.prevX = x; this.mouseCoords.prevY = y; this.matrices.forEach((matrix, i) => { let translate = Rematrix.translate(diffX, diffY); const product = [matrix.prevTransform, translate].reduce(Rematrix.multiply); const css = `matrix(${product[0]}, ${product[1]}, ${product[4]}, ${product[5]}, ${product[12]}, ${product[13]})`; matrix.prevTransform = product; matrix.node.setAttribute('transform', css); }) } [代码] 进一步优化 看到一个方法,在AE中将图层命名为[代码]#id[代码]格式,生成的SVG相应的图层id会被设置为id,命名为[代码].class[代码]格式,相应的图层class会被设置为class [图片] 试了下的确可以,如下图,因此可通过这个方法快速找到需要操作的动画层,进一步简化代码: [图片] 小结 Lottie的缺点在于若在AE动画制作的过程不注意规范,会导致数据文件大、耗内存和性能的问题;Lottie-web的官方文档不够详尽,例如assetsPath参数是在看源码的时候发现的;开放的API不够齐全,无法很灵活地控制动画层。 而优点也很明显,Lottie能帮助提高开发效率,精简代码,易于调试和维护;资源文件小,输出动画效果保真;跨平台——Android, iOS, Web和Windows通用。 总的来说,Lottie的引用可以替代传统的GIF和帧动画,灵活利用好提供的属性和方法可以控制动画的播放,但需注意规范设计和开发的流程,才可以更高效地完成动画的制作与调试。
2019-03-25 - 地理位置接口新增与相关流程调整
一、地理位置接口新增说明 由于精确地理位置接口只允许部分类目的小程序申请使用,为了满足开发者在更多场景使用地理位置接口,自 2022 年 7 月 14 日起,新增获取模糊地理位置接口(wx.getFuzzyLocation)。同时为保障用户合法权益,该接口调用前需进行准入开通申请,该接口准入规则与 wx.chooseLocation 一致。 wx.getFuzzyLocation 接口说明: 1、该接口返回的是经过模糊处理的经纬度坐标; 2、该接口支持返回 wgs84 或 gcj02 两种类型的坐标; 3、该接口需要用户授权 scope.userFuzzyLocation。 二、app.json 的配置指引 为了开发者能够正常使用获取模糊地理位置等接口,以及后续对于代码提审环节的优化(见「三、地理位置接口使用流程」),自 2022 年 7 月 14 日起,开发者在使用地理位置相关接口时(共计 8 个,见表1),需要提前在 app.json 中进行配置。 1、需配置的接口列表 [图片] 表1 2、配置规则 1)在代码中使用的地理位置相关接口(共计 8 个,见表1),开发者均需要在 app.json 中 requiredPrivateInfos 配置项中声明,代码格式如下: [图片] 2)表1中模糊位置信息(序号1)和精确位置信息(序号2-5)是互斥的,即声明了模糊位置信息就无法声明精确位置信息。若同时声明模糊位置信息和精确位置信息,则在编译代码时出现错误; 3)注意:自 2022 年 7 月 14 日后发布的小程序,如果未在 app.json 中声明表1中的相关接口,则小程序调用这些接口(表1)时会出现错误,在 2022 年 7 月 14 日之前发布的小程序不受影响; 4)对于第三方开发者,需要在上传代码时通过参数在 ext.json 中声明其需调用的地理位置相关接口,配置规则和普通小程序的配置规则相同。 三、地理位置接口使用流程 自 2022 年 7 月 14 日起,开发者如需在最新版本发布后使用地理位置相关接口,除需完成接口权限开通外,还需在 app.json(或ext.json)配置环节,具体如下: 1、接口权限开通 以下 8 个接口需完成准入开通流程:wx.getFuzzylocation、wx.getLocation、wx.onLocationChange、wx.chooseAddress、wx.choosePoi、wx.chooseLocation、wx.startLocationUpdate、wx.startLocationUpdateBackground 1)普通开发者:需要在 “小程序管理后台 -「开发」-「开发管理」-「接口设置」” 中完成权限申请; 2)第三方开发者:可通过 apply_privacy_interface 接口完成权限申请。 2、app.json(或 ext.json)配置 1)普通开发者:需在 app.json 中声明其需调用的地理位置相关接口,具体配置流程见「二、app.json 的配置指引」; 2)第三方开发者:需要在上传代码时通过参数在 ext.json 中声明其需调用的地理位置相关接口(配置方式:可通过 commit 接口配置)。 同时,为了提升开发者体验,平台在代码提审环节会协助开发者对地理位置接口进行检测,如检测出代码中包含未完成准入开通的地理位置接口,平台将再次提醒开发者确认是否需使用相关接口。 1)普通开发者:若无需使用,开发者可在提审时确认不使用该接口,即可正常进行代码提审。小程序审核通过且新版本发布完成后,平台将对小程序确认不使用的接口关闭使用权限; 2)第三方开发者:若无需使用,可在提审时通过参数声明不使用该接口(声明方式:可通过 submit_audit 接口配置),即可正常进行代码提审,审核通过后发布上线,将对其声明不使用的接口关闭使用权限。 以上调整将仅对所有小程序生效。 微信团队 2022年6月1日
2023-09-26 - 小程序 request:fail -7:net::ERR_TIMED_OUT 报错 ,有知道原因的?
[图片]
2022-06-18 - skyline 版本的基础库对自定义tabBar支持有问题?
基础库版本:2.24.6-skyline (我不知道为啥会是这个版本) 代码片段:https://developers.weixin.qq.com/s/JJB2UemD77Ad 问题描述:在 custom-tab-bar 组件中引用了其它组件,通过开发预览码扫码进入小程序,首次基本上展示正常,但是通过“重新进入小程序”再次进入,custom-tab-bar 中引入的组件就会渲染异常,后续再打开基本也是异常,截图如下: 首次打开页面展示: [图片] 首次打开 wxml 展示: [图片] 重新进入小程序页面展示: [图片] 重新进入小程序 wxml 展示: [图片] vConsole 报错: [图片] 基础库截图: [图片]
2022-06-23 - 关于web-view的返回问题
- 需求的场景描述(希望解决的问题) 当前我们小程序通过页面跳转进入到一个包含web-view的页面,src中的地址就是我们的业务域名地址,里面嵌入的是H5页面,我们通过点击H5页面中的一些链接,跳转到H5页面中的其他页面,无论进入的页面层级有多少层,安卓手机点击左上角都是直接返回到小程序的上一个页面,而不是H5页面里面的上一个页面,苹果支持跳转到上一个页面,安卓的物理返回按钮也支持返回H5的上一级页面。但是此时,点击返回到当初第一次进入H5页面的时候,再点击苹果上的返回按钮或者安卓的物理返回键,H5页面跳转就失控了,直接跳转到其他层级的H5页面。 问题就是小程序的返回按钮完全是黑盒操作,我们没法在web-view做有效的预防直接跳转的判断。 - 希望提供的能力 希望提供返回按钮的监听事件,并返回是否返回上一页这种功能。这样就可以确保点击小程序返回的时候能够对web-view中的H5页面返回进行兼容,更友好一些。
2018-09-06 - 小程序转发分享到微信群,微信群会显示 【该消息类型暂不能显示】
小程序转发分享到微信群,微信群会显示 【该消息类型暂不能显示】,有的手机转发会有这个问题?什么原因
2017-09-25 - 微信小程序分享到群后,在不能转发到其他群?提示:该消息类型暂不能展示
我们开发的房产小程序,供经纪人卖房用的。 我们把小程序分享到我们自己运营的微信群后,我们在群里,就不能对这条房源转发。如果转发到其他群就提示:该消息类型暂不能展示 我们运营的群上百个,很多时候 都是群发群用的,但是我们开发的小程序 只要转发就提示:该消息类型暂不能展示 这是什么问题呢??我们设置的问题?还是限制 官方有明确说明么?
2019-09-12 - 复制任意微信小程序页面路径
以下以微信小程序“虎牙直播”为例,演示如何复制微信小程序页面的路径。 1.进入小程序的“关于虎牙直播”页面 [图片] 2.点击右上角的“…”进入“更多资料”页面 [图片] [图片] [图片] 3.复制AppID:wx74767bf0b684f7d3 4.进入小程序后台输入appid并搜索,然后点下一步 [图片] 5.鼠标移动到“获取更多页面路径”,在弹出窗口输入当前登陆的小程序的任意开发者微信号,然后点击开启,出现顶部的“开启入口成功”就可以使用手机访问“虎牙直播”任意页面进行复制了 [图片] 6.某个直播间的页面路径:pages/main/liveRoom/index.html?anchorUid=1678113423&source=search[图片] PS:复制出来的页面路径在小程序里使用的时候记得删除 .html 才能正常访问。
2020-01-16 - 半屏小程序怎么打开目标小程序的分包页面?
怎么使用 wx.openEmbeddedMiniProgram 或者 wx.navigateToMiniProgram 打开目标小程序的分包页面?
2022-03-14 - CI报错 get new ticket fail innerCode:-80011?
ci上传代码时,报出如下错误,请问是什么问题。 Error: Error: {"errCode":-1,"errMsg":"get new ticket fail: innerCode: -80011"} at Object.upload (/Users/admin/Desktop/veer-mp-frontend/node_modules/miniprogram-ci/dist/upload/upload.js:1:3785) at processTicksAndRejections (internal/process/task_queues.js:97:5) at async Object.preview (/Users/admin/Desktop/veer-mp-frontend/node_modules/miniprogram-ci/dist/upload/preview.js:1:677) { code: 20002 } appid是wxc75f0a2b2511d538
2020-07-25 - 小程序/小游戏后端获取当前appid、版本号和接口环境控制
写在前面的话 我们的后端架构是基于微服务的平台化架构,提供了一套通用的接口,所有的小程序/小游戏都走这套接口,由负载均衡统一分发,这样就需要区分是哪个应用的哪个版本访问的接口,以便准确的处理数据。 解决方案 一、请求时将 [代码]appid[代码] 和版本信息放入参数中提交给后端。 优点:简单,直接。 缺点:只能将信息传给后端,而后端无法控制小程序/小游戏端逻辑。 二、使用 wx.getAccountInfoSync 接口获取账号信息。 优点:官方提供的API。 缺点:里面只有 [代码]appid[代码],没有版本信息,存在和 [代码]方案一[代码] 同样的问题且不支持小游戏。 三、后端获取Referer信息,从里面获取信息。 优点:wx.request 中 [代码]header[代码] 内 [代码]Referer[代码] 的值是默认生成不可以设置的且格式固定。 缺点:无法区分开发版本、体验版本和审核版本, [代码]方案一[代码] 的问题依然存在。 四、自己维护版本信息,提供一个远程的版本信息同步接口。 优点:可扩展性高。 缺点:开发时需要定义版本信息,小程序/小游戏每次打开时都需要同步版本信息。 最佳方案 我们选择了 [代码]方案三[代码] 配合 [代码]方案四[代码] 来实现,主要原因是因为 wx.request 中 [代码]header[代码] 内 [代码]Referer[代码] 的值是默认生成不可以设置的且格式固定,并且里面包含了 [代码]appid[代码] 和 [代码]版本号[代码] [小程序自己的版本号,并不是我们自己定义的版本号,且只有线上版本的] 的信息。小程序/小游戏端无需增加参数后端即可获取这些信息。 [代码]Referer[代码] 的格式固定为: [代码]https://servicewechat.com/{ appid }/{ version }/page-frame.html [代码] 其中 [代码]{ appid }[代码] 为小程序的 [代码]appid[代码],[代码]{ version }[代码] 为小程序的版本号,版本号为 [代码]0[代码] 表示为开发版本、体验版本以及审核版本,版本号为 [代码]devtools[代码] 表示为开发者工具,其余为正式版本。 以上描述摘自官方文档 网络 的章节 开发版本、体验版本以及审核版本的 [代码]version[代码] 都为 0 ,然而在开发过程中后端分为 [代码]dev[代码] 、[代码]test[代码] 、[代码]uat[代码] 、[代码]prod[代码] 等不同的环境,只使用 [代码]方案三[代码] 并不能完美的解决问题,这种方式前端并不能获取到当前版本的状态,无法动态的切换访问的环境,如果都去通过负载均衡去分发,反而给负载均衡带来了压力,所有环境都部署在外网也不现实。 于是我们想到了一个解决办法,也就是 [代码]方案四[代码],自己维护版本号。通过版本状态来判断当前版本需要请求的环境。 实现思路 小程序/小游戏分为开发版本、体验版本、审核版本和线上版本。 开发版本是由开发者进行上传才可以访问的,开发者工具模拟器、预览和真机调试的不会出现在这里。 体验版本是由管理员选定某个人提交的开发版本作为体验版的。 审核版本也是由管理员选定某个人提交的开发版本进行提交审核的。 线上版本是审核版本审核通过后,管理员进行发布的。 不同角色的人员如何访问对应的版本 角色 环境 版本 小程序/小游戏的访问方式 开发 dev 使用开发者工具模拟器、预览或真机调试进行访问 测试 test 开发版本 使用 [代码]小程序助手[代码] 小程序,访问不同开发人员上传的版本 验收 uat 体验版本 扫描体验版二维码或使用 [代码]小程序助手[代码] 小程序进行访问体验版 审核 prod 审核版本 只有审核人员可以访问 用户 prod 线上版本 发布后全网可以访问 小程序/小游戏端定义自己的版本号,新版本开发时,版本号进行升级,同时后端数据库中添加当前开发中的小程序/小游戏版本号,并标识当前这个版本号的状态为 [代码]dev[代码] 开发阶段,提交测试时将版本号的状态修改为 [代码]test[代码] 测试阶段,用户验收时将版本号的状态修改为 [代码]uat[代码] 验收阶段,后续版本的做法以此类推。 后端提供一个接口,小程序/小游戏端打开后,首先调用这个接口进行状态同步,参数为当前的版本号,接口返回版本的状态。小程序/小游戏中通过硬编码的方式,根据状态来判断当前需要访问的环境地址。 需要后端先上线版本号管理的功能。 每个环境中的接口 [代码]pathname[代码] 是固定不变的,会变动的只有 [代码]origin[代码]。 举例: [代码]生产环境中的一个接口 https://examplp.com/api/login 验收环境中的一个接口 http://10.10.10.10:8080/api/login 测试环境中的一个接口 http://192.168.1.100:8080/api/login 开发环境中的一个接口 http://localhost:8080/api/login [代码] 其中 [代码]/api/login[代码] 为 [代码]pathname[代码] 是固定不变的,变动的只有前面的域名也就是 [代码]origin[代码],小程序/小游戏端只需要根据版本号的状态去修改 [代码]origin[代码] 就可以了。 注意:使用这套方案时,一定要防止版本信息同步接口过度依赖而影响主业务的事情发生,请做好兼容处理。 功能扩展 通过这套流程不但可以动态的切换小程序/小游戏端访问不同环境的后端接口,还可以动态的停止线上的某个版本。 接口再扩展一个 [代码]openid[代码] 的参数,也可以指定某个人的访问环境。比如测试需要使用线上版本将接口转到测试环境等。
2019-02-20 - 不同小程序网络请求来源地址内 version 版本号都是同一个
网络请求的 [代码]referer[代码] header 不可设置。其格式固定为 [代码]https://servicewechat.com/{appid}/{version}/page-frame.html[代码],其中 [代码]{appid}[代码] 为小程序的 appid,[代码]{version}[代码] 为小程序的版本号,版本号为 [代码]0[代码] 表示为开发版、体验版以及审核版本,版本号为 [代码]devtools[代码] 表示为开发者工具,其余为正式版本; 同一个开发者2个不同的小程序,网络请求来源地址内 version 版本号都是同一个,这个是正常的么? https://servicewechat.com/wxc288d7ec3a4b423d/92/page-frame.html https://servicewechat.com/wx02a1d3c1f0639092/92/page-frame.html
2019-04-18 - 如何生成小程序的指定页面二维码?
1、登录“微信公众平台" https://mp.weixin.qq.com/ 2、工具-生成小程序码 [图片] 3、输入小程序名称或appId或账号原始ID,搜索小程序。一定要开始允许被搜索。找到之后点击“下一步”。 我一般感觉用appId最方便。 4、输入指定的“小程序页面路径“,这个可以在小程序开发者工具中找到。 [图片] 5、点击”确定“,得到相应的小程序二维码。 [图片] 6、在这里没有下载文件的功能,我使用截图方式,保存的图片。 目前,我觉得使用这种方式是最方便,最安全的。也看到过使用草料生成小程序二维码,但是,要提供appId 和 APP Secret ,总觉得不够安全。 下面是草料的链接:https://cli.im/weapp
2021-11-29 - template 是否支持递归的template?
template 中递归调用,调试时前台直接警告[图片] template 中可以存在递归吗?
2018-07-31 - 小程序模板不支持递归和动态生成多个
小程序模板不支持递归使用,为了要实现和递归一样的功能,要定义多个结构相同模板名称不同的模板,重复使用大量相同代码,hack 点的办法是使用 for 循环生成多个模板,然而这也不支持。。 [代码]<view wx:for="{{[1,2,3,4,5]}}" wx:key="">[代码] [代码] [代码] [代码] [代码][代码]<[代码][代码]template[代码] [代码]name[代码][代码]=[代码][代码]"template{{index}}"[代码][代码]>[代码] [代码] [代码] [代码] [代码]<block wx:if="{{node.haveChild}}"> [代码] [代码][代码]<[代码][代码]template[代码] [代码]is[代码][代码]=[代码][代码]"template{{1 + index}}"[代码] [代码]data[代码][代码]=[代码][代码]"{{node.child}}" [代码][代码]/>[代码] [代码] [代码] [代码] </block>[代码] [代码] [代码] [代码] </template[代码][代码]>[代码] [代码] [代码] [代码]</view>[代码]
2017-10-12 - 调用jserr_list接口时,data为空,但是我在管理台是能看到错误列表的,这是为什么?
// 调用jserr_list接口时,data为空,但是我在管理台是能看到错误列表的,这是为什么? curl --location --request POST 'https://api.weixin.qq.com/wxaapi/log/jserr_list?access_token=access_token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Cookie: wxuin=36093342443566' \ --data-urlencode 'appVersion=0' \ --data-urlencode 'errType=0' \ --data-urlencode 'startTime=2021-10-28' \ --data-urlencode 'endTime=2021-11-04' \ --data-urlencode 'keyword=' \ --data-urlencode 'openid=' \ --data-urlencode 'orderby=pv' \ --data-urlencode 'desc=2' \ --data-urlencode 'offset=0' \ --data-urlencode 'limit=1' // 返回 { success: true, openid: '', data: [], totalCount: 0, errcode: 0, __rpcCount: 2 } // 设置Content-Type: application/json curl --location --request POST 'https://api.weixin.qq.com/wxaapi/log/jserr_list?access_token=access_token' \ --header 'Content-Type: application/json' \ --data-urlencode 'appVersion=0' \ --data-urlencode 'errType=0' \ --data-urlencode 'startTime=2021-10-28' \ --data-urlencode 'endTime=2021-11-04' \ --data-urlencode 'keyword=' \ --data-urlencode 'openid=' \ --data-urlencode 'orderby=pv' \ --data-urlencode 'desc=2' \ --data-urlencode 'offset=0' \ --data-urlencode 'limit=1' // 直接报错 {"errcode":-1,"errmsg":"system error rid: 6184d6fd-4e59e751-59dd38bb"} 问题终结 startTime和endTime的格式必须是yyyy-MM-dd HH:mm:ss,文档上写的是yyyy-MM-dd,我改了下时间格式就成功了。
2021-11-05 - 交易类小程序纠纷投诉能力处理指引
为进一步保障小程序平台用户的合法权益,督促开发者向用户提供更好的服务,平台将针对小程序交易投诉处理规则做出以下更新: 1、和解环节开发者处理时效由72h改为48h,执行环节开发者处理时效由72h改为48h 2、和解环节开发者超时未处理,平台将判定开发者责任并做出相应处理,包括但不限于采取扣除保证金、先行垫付、扣减交易体验分等措施。 该时效调整将在2024年3月25日正式生效,请开发者及时关注。 一、一、交易类纠纷处理通知机制 1、为便于小程序开发者及时获知小程序交易投诉情况,平台将于每天早上10:00向小程序的管理员及运营者推送通知,通知内容为截至前一天24时该小程序账号内待开发者处理的投诉单详情。 2、通知查看路径: 1)小程序管理后台:右上角「通知」查询通知记录; [图片] 2)微信移动端:通知下发给小程序管理员与运营者,可搜索「微信公众平台」查看通知记录。 [图片] 二、二、交易类投诉处理操作指引 1、登陆小程序管理后台并核实投诉 登录小程序管理后台—功能—交易保障—交易投诉;查看待处理的投诉单,并尽快完成投诉单详情的核实与处理。 [图片] 2、和解环节:同意和解/拒绝和解 核实投诉后,若同意与用户和解,请在时效内上传与用户的沟通说明、物流信息或者退款凭证等,平台将推送和解详情给用户。 核实投诉后,若双方未达成和解,请选择拒绝和解并上传相关凭证,平台将推送不和解详情给用户。 若开发者未在处理时效内作任何处理,纠纷单将自动流转至平台介入处理状态,平台将判定开发者责任并做出相应处理,包括但不限于平台先行垫付,扣除开发者保证金,扣减交易体验分等措施。 [图片] [图片] 注:开发者和解时效为72h。选择同意和解或拒绝和解后,用户会收到确认投诉处理结果的通知,若用户认可开发者的处理结果,投诉将完结;若不同意,用户可申请平台客服协助处理。(2024年3月25日后发起的投诉单和解时效更改为48h) 3、平台处理环节:下发举证&判定责任 若用户不认可开发者投诉处理结果并申请平台介入,平台将根据现有纠纷凭证是否有效,要求开发者/用户补充相关凭证;若平台要求开发者补充纠纷凭证,投诉单状态将流转至【待开发者补充凭证】,处理时效为48h(特殊场景为24h),请务必如实填写并上传沟通说明、物流信息或退款凭证等信息;开发者/用户补充凭证后,平台将根据已有材料与凭证进行判责。 [图片] [图片] 4、开发者执行环节:上传处理凭证 若平台判为开发者责任,投诉单状态流转为【待开发者上传处理凭证】,处理时效为72h(特殊场景为48h),请尽快提交微信支付退款单号、交易流水、转账单号或物流单号等凭证,供平台核实是否已执行平台判责。(2024年3月25日后发起的投诉单处理时效更改为48h) [图片] [图片] 5、平台核实环节 若平台根据开发者上传的处理凭证判断开发者已执行平台判责,该投诉单将完结; 若开发者上传的处理凭证信息不准确,平台无法判断其已执行平台判责/超时未上传处理凭证,平台将根据实际情况对开发者进行交易体验分的扣减,对用户进行先行赔付等措施。 6、商家申诉环节 若平台判定商家责任后,开发者不认可平台的判责结果,可在投诉单完结后的72h内发起申诉,平台会根据申诉环节上传的相关材料进行申诉判定;每个投诉单仅支持一次申诉,申诉超时/申诉失败后不支持再次发起申诉。 若申诉成功,则开发者无需按照《微信小程序交易服务违规管理规则》中的第三章违规处理措施缴纳违约金; 若申诉失败,则开发者仍需按照《微信小程序交易服务违规管理规则》中的第三章违规处理措施缴纳违约金。 [图片] [图片] 三、小程序实物交易纠纷处理规则 平台介入处理争议时,开发者应遵守以下约定: 开发者及用户就订单产生交易争议时,双方可以选择自行协商。如用户向平台提起交易投诉,双方协商未果或开发者未作处理,平台有权根据本规则及相关法律法规介入对争议的处理。 当开发者因自身系统、管理、人力等原因出现异常大量维权或舆情事件,且开发者不具备及时处理能力,为保障双方交易安全,平台可主动介入处理。 平台处理交易争议期间,开发者及用户应当按照平台下发的站内信、模版消息、短信、电话或邮件通知及时提供凭证。 平台处理争议期间,若任何一方无正当理由,未按照举证要求提供凭证的,平台有权按照实际收集到的凭证做出处理。 平台做出判责后,开发者应当按照要求及时履行相应义务。 如开发者行为违反相关法律法规或平台规则,因此而可能产生的用户损失或额外赔偿费用将由开发者自行承担。 详情可查看微信小程序实物交易争议处理规则 四、常见问题 1、用户交易投诉的入口在哪? 小程序—页面右上角“…”—反馈与投诉—交易投诉 [图片] 2、如何更改通知接收者? 目前,交易投诉待处理通知会发送给当前小程序的管理员及运营者。若希望取消或者增加推送成员,可登录微信公众平台—管理—成员管理,更换或添加管理员及运营者。 [图片] 3、上传凭证需要注意什么?如果超时未处理怎么办? 上传前务必确保提交的证据材料的真实性、完整性、及时性和准确性;平台处理争议期间,请按照举证要求的内容提供凭证。 为保障用户的体验,请在规定时间内完成核实和处理;否则,开发者应承担超时未处理、举证超时的后果,平台有权按照实际收集到的凭证做出判责,同时根据平台规则对开发者进行扣减交易体验分等措施。 4、除了在小程序管理后台处理投诉,是否有其他方式处理交易投诉? 若开发者在网页端登陆小程序管理后台处理投诉存在困难,平台提供移动端工作台—小程序助手处理投诉,投诉处理流程与PC端一致;同时平台提供线上接口,开发者可通过接口接入自己内部系统处理投诉。 移动端工作台:微信主页搜索「小程序助手」—登陆小程序—管理功能—交易投诉 [图片] 接口文档:可点击查看交易投诉处理接口文档:投诉信息推送 | 微信开放文档 5、交易体验分是什么?为什么被扣分了?扣分后会受到什么处罚? 为保障小程序平台用户的合法权益,平台将对开发者在其小程序的违规行为进行判定,根据违规行为的严重程度对该小程序扣减不同分值的交易体验分,并在小程序交易体验分扣减至相应节点时,对开发者采取相应违规处理措施。 具体规则与案例解析可点击《微信小程序交易服务违规管理规则》、微信小程序交易体验分常见问题指引查看。 6、申诉需要提供哪些凭证才算有效凭证?哪类申诉不支持通过? 开发者需针对用户投诉问题的有效反驳凭证,建议同时提供相关图片进行佐证。 开发者在投诉单处理环节中,包含和解环节/举证环节/商家执行环节,若任意一环节存在未回复或以话术、无效字符回复的情况,不予申诉通过;用户投诉开发者服务态度问题,被平台判定问题属实,不予申诉通过;用户投诉开发者服务意愿类问题,如强制退款、或未按订单页面承诺进行服务履约(如配送超时,商品无货强制退款等),被平台判定投诉属实,不予申诉通过。 7、为什么要收取违约金? 当开发者存在违反《微信小程序交易服务违规管理规则》的行为,需要按规则3.1缴纳违约金;开发者有申诉的权利,可在投诉单完结后的72h内发起申诉,平台要求缴纳的违约金来源为"已过申诉时效或平台认定申诉不成立的违规投诉单"。 8、不缴纳是否有限制措施? 若开发者未按期足额支付违约金的,平台将采取限制小程序搜索、限制支付能力等处理措施。请参考《微信小程序交易服务违规管理规则》的违规行为及对应处理措施。 9、违约金是否可以开具发票? 小程序mp后台(mp.weixin.qq.com-功能-交易保障-消费者资金保障-违约金)模块,支持对单笔缴纳流水进行发票开具,请开发者仔细阅读开票的注意事项并填写准确信息。
03-22 - 分包异步化 分包难题不用怕
在小程序开发过程中,你是否对分包问题感到困扰? 多业务的分包难以划分 分包体积膨胀 下载并注入无用代码 插件无法实现分包处理 …… 为解决上述问题,微信团队提供【分包异步化】新能力,实现跨分包组件、跨分包方法,成功解决分包难、分包不合理等问题。 • • 分包异步化原理 • • 原有的分包隔离机制导致各分包之间无法引用自定义组件或逻辑代码,因此导致分包难等一系列问题。分包异步化能力打通不同分包的引用关系,解决小程序代码包合理化的问题,支持跨分包组件、跨分包方法。 [图片] • • 跨分包组件 • • 当使用其他分包组件时,代码包需要增加占位组件 (component placeholder),实现页面高效配置。例如页面展示时,分包 (subpackageB) 仍未下载,进行以下操作实现跨分包组件: 1. 使用组件 <simple-list> 代替 <list>,使用 <view> 代替 <card>,完成页面渲染 2. 完成渲染后,开始下载和注入分包 3. 完成分包下载和注入后,将占位组件替换成真正的组件 // subPackageA/pages/index.json { "usingComponents": { "button": "../../commonPackage/components/button", "list": "../../subPackageB/components/full-list", "simple-list": "../components/simple-list" }, "componentPlaceholder": { "button": "view", "list": "simple-list" } } • • 跨分包方法 • • 在小程序开发过程中,通过require回调函数或requireAsync异步调用2种方法,分包异步化能够引用其他分包的逻辑代码。具体操作如下: // subPackageA/index.js // 使用回调函数风格的调用 require('../subPackageB/utils.js', utils => { console.log(utils.whoami) // Wechat MiniProgram }) // 或者使用 Promise 风格的调用 require.async('../commonPackage/index.js').then(pkg => { pkg.getPackageName() // 'common' }) • • 兼容性要求 • • 分包异步化能力要求基础库版本 2.17.3 及以上(正式发布需在 mp 设置最低版本基础库 2.17.3)。平台能力兼容安卓微信、iOS 微信、1.05.2104272 及以上版本的微信开发者工具。更低版本的基础库兼容工作预计在一个月后完成。 • • 总结 • • 实现分包异步化能力后,主包的「公有」性质被削弱,「前置」性质显得更重要(优先于所有分包注入运行且默认注入运行)。开发者可以根据自身业务诉求,结合分包异步化,进行小程序调优,实现更快的启动速度、按需下载和注入代码包、合理处理公有组件等效果。
2021-09-16 - 获取微信accesstoken提示appid missing rid,请问这个是什么错?
获取微信accesstoken提示appid missing rid,请问这个是什么错?
2020-07-30 - 怎么判断设备是手机还是平板?
通过下边那个参数判断?
2019-12-19 - 推荐好物圈报错
[图片] 代码: [图片]app.json [图片] detail.json [图片] detail.wxml
2019-06-11 - 直播插件live-player-plugin 使用中报 error?
报错: Error: This application has not registered any plugins yet. Error: This application has not registered any plugins yet. at t.checkWxConfig (https://lib/WASubContext.js:2:1593908) at t.requirePlugin (https://lib/WASubContext.js:2:1596310) at https://usr/app-service.js:4654:2 使用的插件配置: plugins: { "live-player-plugin": { "version": "1.2.4", "provider": "wx2b03c6e691cd7370" } } 微信客户端版本:7.0.12、7.0.13、7.0.16、7.0.19、7.0.20等都有出现
2020-12-19 - 小程序直播提交代码显示没有权限?
我们是第三方平台服务商模式,问题如下: 开放平台wx511c51039f561228已经有直播权限,并且已经全网发布;小程序wx2bc8ff5b297791a2没有直播权限,但是添加为第三方平台的开发小程序后,就有了直播权限,也看到了小程序直播插件,在MP后台创建直播都没有问题;我们使用开发小程序为模板通过接口给客户创建了小程序wx77218d7d3f9c19ad,然后提交包含直播组件的代码时,报错了:miniprogram has no permission to plugin[wx2b03c6e691cd7370]尝试通过插件接口给小程序wx77218d7d3f9c19ad添加直播插件时,报错:this plugin can not apply hint: [xeICRHuhE-.lAT3a]请问一下大家,这个问题怎么解决呢,不知道怎么让创建的小程序也具有直播权限,官方文档也没有这块的说明,谢谢大家! --------------------防尘分割线---------------------------------------- (20200620)我觉得可能是wx77218d7d3f9c19ad没有直播资格,所以无法添加直播插件, 在分析了小程序wx77218d7d3f9c19ad的直播资格问题之后, 我上传了一个商城, 并且发布到了外网, 进行了一笔0.01元的支付, 接下来等两天看看是否能安装插件了. --------------------防尘分割线---------------------------------------- (20200622) 今天试了下,添加仍然报 : Error: 系统错误,错误码:-1,system error [20200622 10:46:25][wx77218d7d3f9c19ad 后台接口继续提示: {"errcode":48001,"errmsg":"api unauthorized hints: [vEKCbWXBe-6C3Fha!]"} ------------------无语分割线---------------------------------------- (20200628) 端午前6.23 , 我解绑了开发小程序, 并且发布了商城代码到开发小程序wx2bc8ff5b297791a2, 然后支付了, 今天查看发现已经开通了直播资格 然后我再将它绑定到第三方平台. 现在的情况是: 第三方平台的直播资格已经开通, 开发小程序的直播资格已经开通, 创建的小程序满足所有条件(已经在线支付) 然而创建的小程序依然无法使用直播插件. 有没有官方技术人员来看下这个问题, 这不是我一个人遇到了, 这是一个普遍性问题, 麻烦重视一下.
2020-06-28 - 微信小程序Provisional headers are shown 模拟器正常,真机请求异常?
实际上所有接口请求 都有 Provisional headers are shown 但是 其中部分接口正常,唯独请求列表的时候返回数据有问题,说是请求失败也不是,请求返回了数据,只是返回的数据不正确,例如请求一个列表,正常模拟器返回报文是 data: { dataList:[ {},{},{},... ], total: 156 } 这是正常的数据,但是一旦到真机调试上面 返回报文就尴尬了, 请求 同样200成功,并且返回了数据,但是数据内容是错误的 data: { dataList:{ dataList:{} }, total: 156 }, 并且警告 Provisional headers are shown我对比了请求报文完全一样,勾选校验https证书 和不勾选返回结果都一样, 实际上是有https证书的, 更尴尬的事,这些接口在模拟器包括其他平台请求都是正常的,唯独在微信小程序真机上面请求会出问题,所以真不知道怎么玩儿了,特么要是请求失败了还好排查,这个请求就真机出问题了,还特么相当于半成功状态,都不知道怎么下手了。。。有没有大佬知道啥情况 求指点。。
2020-01-03 - 请求登录头中被插入​ 导致请求失败?
给后台提交code获取access_token ios真机请求被阻隔,前端问题,和后台都检测了。ssl也是没问题。结果我在别处复制了一遍接口居然ok了。以为编码问题,给请求体加上也不行。后面只能去对比字符,结果可好在请求不同的接口上找到了​ 现在我给替换成空就好了,但是请问这个怎么在请求头上插入进去的,我现在不知道原因。如果大家有这样的问题,请注意一下。 https://developers.weixin.qq.com/community/develop/doc/000822a5088e7828cbf9cb2935a400
2020-03-03 - 给后台提交code获取access_token ios真机请求被阻隔?
[图片] 请求代码 wx.request({ url: 'https://xxxx', //仅为示例,并非真实的接口地址 method: 'post', data: { code: res.code }, success (res) { console.log(res.data) } }) 开发者工具没有问题。但是ios 真机就不行。用真机测试出现目前问题,我看很多人说ssl证书问题,但是我这里也没有报错。 只有前台打印 [图片]
2020-03-01 - “公众号菜单跳转小程序”功能介绍与设置指引
产品简介:微信公众号给小程序提供多个入口,让小程序可以通过更多的途径有效触达用户。 优势:免费多样式的小程序入口。 接入方式:无需开发,公众平台后台设置。 关键词:公众号小程序打通。 [图片] 01 设置小程序关联公众号 设置路径:公众号后台-小程序-小程序管理-添加-关联小程序 由管理员扫码验证后,输入关联小程序appid,在对应小程序后台确认关联即可。 [图片] 02 设置公众号菜单跳转小程序 设置路径:公众号后台-功能-自定义菜单-设置菜单内容为跳转小程序 [图片] (注:公众号后台链接https://mp.weixin.qq.com)
2020-01-14 - 小程序富文本解析利器mp-html
小程序富文本解析利器mp-html [图片] 微慕小程序是资讯、媒体类小程序,因为对富文本内容和媒体内容的显示有较高的需求。对于富文本解析,微慕小程序以前采用的开源的wxParse组件,不过wxParse组件存在很多的问题且已经停止维护支持,随着微慕小程序功能不断的增加和优化,wxParse组件已经无法适应,同时对wxParse二次开发优化的难度比较大,基于此微慕团队考虑寻找更合适的解析组件,经过朋友的推荐和我们的考察,最终选择开源组件:mp-html(https://jin-yufeng.gitee.io/mp-html),这个组件堪称小程序富文本解析利器。微慕团队对mp-html组件二次开发后可以与微慕小程序完美兼容,微慕小程序专业版v3.8.0加入了该组件。mp-html组件给富文本的内容提供了不少出色的功能。 全面支持html标签小程序大多数都是基于html标签来渲染和显示内容的,mp-html组件支持以下列表标签和属性,同时支持id、style、class、align、height、width 属性。几乎可以完美兼容html的标签内容,并保持web内容和小程序内容在显示上兼容性,页面渲染的性能很强。 组件对html标签支持的稳定性很好: 1.标签名中可以含有 : 等特殊字符(如 o:p) 2.标签名和属性名大小写不敏感 3.属性值可以不加引号、加单引号、加双引号,也可以却缺省(默认 true) 4.属性之间可以没有空格(通过引号划分)、有空格(可以多个)、有换行符 5.支持正常格式、CDATA 等多种形式的注释 同时,对于一些错误情况,程序也能够自动处理: 1.标签首尾不匹配 2.属性值中冒号不匹配 3.标签未闭合 自定义样式配置样式(css)是富文本中最重要的内容之一,组件提供多种样式设置的方法,可以进行灵活的自定义设置,让小程序端的文本显示更丰富。 1.行内样式 这是最常用的样式设置方法,直接将需要的样式放在对应标签的 style 属性中即可,这种方式仅作用于单个标签,优先级最高 2.tag-style 这是本组件独有的一种样式设置方式,可以给某一种标签名设置默认的样式,可以通过 tag-style 属性设置,具体用法见对应说明 3.外部样式 如果希望将某些样式固定的用于渲染,可以添加到 tools/config.js 的 externStyle 字段中,该方法仅支持 class 选择器(2.1.0 版本起支持标签名选择器),优先级最低。 需要调整优先级时,可以通过设置 !important 实现。 另外,通过引入 style 插件,还可以实现匹配 style 标签中样式的功能。 图片加载在富文本内容里图片显示非常重要,mp-html在图片显示上充分考虑小程序的特点,主要提供一下功能: 1。占位图 支持设置图片未加载完成时的占位图 loading-img 和加载出错时的占位图 error-img 2.懒加载 内容较长、图片较多时,开启懒加载有助于改善性能,需要时可通过 lazy-load 属性开启 3.自动预览 图片被点击时,将自动放大预览,如不需要,可通过 preview-img 属性关闭。还可以在 imgtap 事件中进行自定义处理 自动预览通过特定的处理,可以实现左右滑动查看所有图片、预览重复链接不错位等效果 4.预览高清图 同一张图片,可以给显示时和预览时设置不同的链接地址以达到最佳效果 设置方式 1:给 img 标签增加一个 original-src 即可 设置方式 2:通过 imgList 的 api 进行设置 5.长按弹出菜单 微信和百度平台支持图片长按时弹出菜单,可以进行保存、分享等操作,如不需要,可通过 show-img-menu 属性关闭 6.装饰图片处理 有时对于一些小的装饰性图片,可能不希望产生上述效果,此时可以给 img 标签设置 ignore 属性,将屏蔽预览、弹出菜单等操作,提升体验。 在链接内的、src 为 data url 且没有设置 original-src 的图片,默认为不可预览的小图片。 7.支持原大小显示 本组件通过合理转换,基本实现了和 html 中 img 的相同效果:没有设置宽度时按原大小显示;设置了宽度时按比例缩放;同时设置宽高时按设置的值显示。不必去考虑小程序中的 mode 等问。。 8.支持 svg 虽然小程序中不支持 svg 系列标签,本组件通过在解析过程中转为 data url 图片的方式实现了 svg 的显示。 表格和列表小程序中没有 table 标签,使得显示表格一直是一个难题,mp-html解决了这个问题,并支持独立横向滚动,支持含有合并单元格的表格,常用表格属性(border, cellspacing, cellpadding, align). 组件主要通过以下三种方式显示表格 显示方式适用情况说明rich-text 标签表格内部没有链接、图片等特殊标签效果最佳,几乎不需要进行转换table 布局表格内有特殊标签但没有使用合并单元格需要进行一定转换,将 table, tr, td 等标签转为对应的布局grid 布局表格内有特殊标签且使用了合并单元格需要进行复杂的转换将合并单元格用 grid 布局表现出来 对于列表支持也非常友好,完全兼容html里的列表。 1.支持多层嵌套 支持嵌套多层列表,对于无序列表,不同的层级会显示不同的黑点格式。 2.支持多种有序列表格式 通过设置 ol 标签的 type 属性,可以显示数字、字母、罗马数字等多种形式的标号。 3.支持不显示标号 支持通过设置 list-style:none 的方式不显示 li 标签开头的标号。 支持音频和视频对于音频和视频支持自动暂停、多源加载、自动添加控件。 1.自动暂停 在存在多个视频的情况下,同时播放可能会影响体验,本组件支持在播放一个视频的时候自动暂停其他所有视频,如不需要,可通过 pause-video 属性关闭 音频在引入 audio 插件后也可以实现此效果 2.多源加载 不同平台支持播放的格式不同,只设置一个 src 可能会出现兼容性问题导致无法播放,因此本组件支持像 html 中一样给 video 和 audio 设置多个 source,将按照顺序进行加载,直到可以播放,最大程度上避免无法播放 3.自动添加控件 对于既没有设置 controls 也没有设置 autoplay 的标签将自动把 controls 属性设置为 true,避免无法播放,影响体验。 支持多个平台的小程序支持小程序包括:微信小程序,qq小程序,百度小程序,支付宝小程序,头条小程序
2021-08-12 - 小程序浮窗怎么没了?
小程序浮窗怎么没了? 是官方关掉的吗?
2020-08-20 - 做个优秀的小程序 - 体验评分
随着小程序的开发迭代,慢慢的我们会更加关注小程序的质量,今天来讲讲小程序的隐藏功能 -- 体验评分。 为什么需要体验评分 我们多做一点,就可以给用户更好的体验。(窃喜) 当然,做为开发者的我们,动动鼠标点一点就能帮助我们发现问题,是不是很愉快~~ 接下来我们来看看怎么使用体验评分? 怎么使用体验评分 体验评分的能力目前开放在【微信开发者工具 - 调试器 - Audits】 操作步骤:运行体验评分 - 一顿操作 - 获取体验报告 - 一顿优化。 (优化其实是一个圈,新代码加上之后也要继续关注哦~) [图片] 体验评分实践 我们用《小程序示例》来操作一波看看效果~ 01. 运行体验评分 使用开发者工具打开小程序,调试器区域切换到 Audits 面板,就一个“运行”按钮,点它。 [图片] 02.一顿操作 然后在工具上对小程序进行操作,比如:我点开了 “接口 - 媒体 - 音频 - 播放 ”。 [图片] 03.获取体验报告 操作完之后,点击“停止”,我们就可以获取到体验报告(简单~)。 [图片] 拿到报告之后,我们就可以看到总分 98,最佳实践 80。往下拉会有扣分的实际原因。 看第一条是 “发现正在使用废弃接口”,报告已经很清楚的告诉我们使用了废弃组件 audio,我们根据报告进行优化即可。 [图片] 04.一顿优化 按照报告优化完之后,我们可以继续进行体验评分功能确认优化是否完善。这是一个有用的圈圈⚪⚪⚪ 我们来讲几个优化过程中遇到的问题,咳咳咳 存在图片没有按原图宽高比显示 [图片] 在测试预览图片的时候,发现图片被挤了,体验评分告诉我们宽高比有问题,发现是 <image> 使用了默认的 mode (scaleToFill:缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素)。所以通过添加 mode="aspectFill" (缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。)来解决宽高比的问题。 [图片] [图片] 发现固定底部的可点击组件可能不在iPhone X安全区域内 [图片] 这个问题我们用手机测试是正常的,但是体验评分给了提示,所以就来看看实现方式是不是有问题: 原有方式:通过接口监听systemInfo.model.indexOf('iPhone X') 给 view 添加专属 class 官方推荐:官方推荐的方式是用 wxss 来兼容,不一定只有 iPhone X 下面会有安全区域 [图片] 发现正在使用废弃接口 [图片] 这个问题对一些老旧代码来说很有用,比如示例很久之前写的 auto-focus,由于基本没有改动,所以代码就一直保持不变。使用体验评分的时候检测到了这个属性是废弃属性,所以我们更换了可用属性 focus 来解决问题。 [图片] 体验评分总结 使用体验评分进行小程序示例的优化,有以下优点: 可以发现代码中使用的废弃api,避免后续踩坑根据实际操作发现相关耗时久的情况,预先发现体验问题合理的视觉/交互检测,提前做好兼容资源使用检测,用合适的资源做好小程序当然,体验过程中也有不足: 开发者工具不支持预览的 组件 / API 暂不支持体验评分(听说官方已经在努力推进啦)一起体验评分 如果你也在做小程序优化,欢迎使用体验评分来优化哦~ 预祝大家都拿 100婚 !!! [图片] 体验评分文档传送门 如果你有疑问,请在下方评论区留言给binnie,㊗️大家都没有bug,✌️✌️✌️
2020-12-04 - miniprogram-ci 20003 errCode:-10008 ?
20003 Error: {"errCode":-10008,"errMsg":"invalid ip: 121.*.**.**, reference: https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html"} (node:11192) UnhandledPromiseRejectionWarning: Error: Error: {"errCode":-10008,"errMsg":"invalid ip: 121.*.**.**, reference: https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html"} at upload (/www/wwwroot/hg.feisu.pro/wxapp/node_modules/miniprogram-ci/dist/upload/upload.js:1:3899) at processTicksAndRejections (internal/process/task_queues.js:97:5) at async Object.upload (/www/wwwroot/hg.feisu.pro/wxapp/node_modules/miniprogram-ci/dist/utils/report.js:1:1409) at async /www/wwwroot/hg.feisu.pro/wxapp/upload.js:10:24 (node:11192) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:11192) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
2021-04-07 - ios11 进入白屏,报Can't find variable: __wxAppCode_错误~紧急
机型:iphone 8pro ios版本 11.2.1 微信版本7.0.8 预期:正常显示 结果:多台ios手机白屏, 报错:can't find variable: __wxAppCode__ global code@https://servicewechat.com/wx92dac0551b5086d4/0/page-frame.html:1:232 [图片]
2019-12-23 - iOS真机selectorQuery获取高度非常不准怎么破?急!
我在movable-view里显示一个后台获取的列表,在获取数据之后通过selectorQuery获取每个分类(ingredientCategory)的高度,加起来之后设置到movable-view的高度上。 开发工具和安卓真机上都没问题,iOS上差距巨大。正常应该是1702px高度的时候iOS上获取回来只有284.9357px,而且<view class="categoryTitleBlock>在页面上显示的高度是0,但是这个类的高度在css里写了的是80rpx。 已经尝试过了在this.setData({})的回调里设置高度,也试了回调里设置setTimeOut再设置高度,问题依旧,请问怎么解决?谢谢! wxml <movable-area> <movable-view style="height: {{panelHeight}}px"> <view class="ingredientCategory" wx:for="{{ingredientList}}" wx:for-index="cat"> <view class="categoryTitleBlock"> <text class="titleText" style="margin-left: 30rpx">{{item.c.name}}</text> </view> <ingredient class="ingredient" wx:for="{{item.f}}" wx:for-index="food"ingredient="{{item}}"></ingredient> </view> <view class="ingredientCategory">...</view> <view class="ingredientCategory">...</view> </movable-view> </movable-area> 自适应高度js setPanelHeight: function() { this.createSelectorQuery().selectAll('.ingredientCategory').fields({ computedStyle: ['height'] }, res => { if (!res) { console.log('no selection') return } console.log(res) let height = 0 for (let i = 0; i < res.length; i++) { height += Number(res[i].height.slice(0, -2)) } this.setData({ panelHeight: height + 340 }) console.log(height) }).exec() },
2021-06-03 - 关于onUnload 与 onHide触发问题?
小程序 点击胶囊关闭按钮时会触发onHide么? 小程序 点击胶囊关闭按钮挂载到后台直到小程序卸载会触发本页面的onUnload 么?
2019-08-30 - 用typescript开发的能不能隐藏与ts文件同名的js文件呢?
用typescript开发的能不能隐藏与ts文件同名的js文件呢? 刚刚误点点到js文件没发现,改了好久,然后点一下编译,白写了
2020-06-03 - 小程序运行时崩溃和黑屏
有些机型在使用小程序时.会出现程序奔溃和黑屏的情况.即使右边的圆点关闭后,重新打开小程序也不行.还有把微信后台关掉也不行. 请问会有什么情况会导致.
2018-12-21 - 小程序尝试开启quic不成功,是否有成功案例?
使用nginx-quic模块编译的nginx,使用chrome访问走的quic协议,使用小程序访问未走quic协议。使用caddy并开启experimental_http3,chrome访问也走的quic协议,小程序未走quic协议。小程序wx.request是否真正支持quic协议,还是我服务器配置有问题?
2021-05-13 - wx.request 参数 enableHttp2 无效?
服务器端nginx开启http2,小程序访问,protocol还是http/1.1
2021-06-25 - wx.request() 在 v2.10.4 新支持的 enableCache 字段的具体作用是?
API 名称:wx.request() 最低基础库:v2.10.4 具体字段:enableCache 文档链接:https://developers.weixin.qq.com/minigame/dev/api/network/request/wx.request.html 问题:当 enableCache 为 true 时,具体作用是什么?是指支持 HTTP 1.1 的强缓存或协商缓存吗?
2020-11-16 - 小程序webview缓存清除
请问小程序webview里面的缓存怎么清,样式怎么改都是以前的,直接在微信访问链接都改了,小程序里面的还没改。非常严重!!!!!!!希望有人帮我顶上去,让官网的人看到,给出一个有效的解决方案!
2018-09-23 - 使用 webpack 打包小程序
前言 针对目前市面上出现的各种小程序,如百度小程序,支付宝小程序,字节跳动小程序,快手小程序。 小程序原生开发对于开发者的开发体验并不是很友好,那如何解决这个问题呢? 问题点 样式预处理 TypeScript支持 多环境打包支持 可扩展性 如在小程序内支持md文档格式,json格式等 多端支持 问题如何解决 使用webpack 来处理以上一系列问题 webpack 官方介绍就是静态文件的打包器 [图片] 上图所做的工作就是 项目中所有的静态文件 如js wxss wxml png jpg 通过webpack处理,可以输出到特定环境下可以运行的代码,webpack就是导入一些入口文件然后通过编译输出结果 [图片] 回顾小程序 首先小程序由项目入口组成 脚本逻辑 [图片] 配置 [图片] 其次小程序也由页面/组件 组成 脚本逻辑 模版 样式 配置 因为小程序的项目中每个文件都是独立的,比如小程序一个页面由js,json,wxml.wxss组件,而不是像web一样可以将文件打包在一起,这样我们使用webpack打包小程序就有一定的限制条件,既然输出的结果一定要按照小程序的规范,那么入口文件也要根据要求去操作,可能webpack 配置就不是一个单页面的配置,就要考虑使用多入口的方式实现,那么就要解决如下问题点: 确定入口文件 在小程序的app.json中会有一个pages 里面都是小程序中所有的页面,那么我们可以通过一个方法getPages获取这些页面的所有内容如js,json,wxss,wxml等信息,但是有个问题就是因为页面中可能包含有很多组件部分,所以还需要去解析页面组件的依赖,可以通过页面json中 usingComponents 配置去解析 [图片] [图片] 如图所示,页面有很多组件组成,我们可以通过一个方法getComponents方式,用递归的方式获取到项目页面中所有的组件信息,包含组件模版,样式 编译模版 问题点:webpack 无法直接去编译小程序的wxml文件 如何解决:可以自定义一个loader去解析这些文件,让webpack能够识别到。 [图片] [图片] 通常导出⼀一个函数,⼊入参为上⼀一个 loader 的返回值,可以有多个⼊入参,通常为源码 返回值⼀一般为处理理后的代码,如要返回多个值,⽤用 this.callback() 使⽤用 loader-utils 来辅助处理理,例例如通过 loader-utils 获取 loader 传⼊入 options,⼀个 loader 只处理理单一事务 处理样式 可以使用如下loader编译小程序样式 saas-loader/less-loader -> postcss-loader -> css-loader -> filer-loader [图片] 处理配置 考虑一个问题,小程序的配置文件是一个json文件,我们是否可以通过webpack的file-loader去编译 [图片] 上图中的确可以处理我们页面的配置文件,但是有个问题就是如果页面文件夹中出现另一个json文件,比如是一些静态数据的json文件,我们知道小程序是不能从本地引用本地文件,所以必须要通过一个loader去做这些事 [图片] 移除不必要的文件 [图片] 通过file-loader 打包之后会出现以下红色框的文件,但是我们小程序是不需要这些文件的,那么如何移除呢?我们知道webpack的编译过程是 [图片] Compiler 负责⽂文件监听和启动编译,包含完整 webpack 配置,全局唯⼀ compiler.hooks.* entryOption run watchRun compilation Compilation 第⼀次以及监听到⽂文件变化创建,包含当前模块信息、编译⽣生成资源等信息 compilation.hooks.* buildModule optimize beforeChunkAssets optimizeChunkAssets [图片] 编译结果输出还不是很优雅还需要完善,后续要通过抽离公共代码,封装一些插件优化。。。
2020-04-28 - 用__wxConfig.envVersion区分小程序体验版,开发板,正式版
在开发过程中,通常测试版和正式版的api的根路径不同,需要在发布时手动去更改路径,这就显得很繁琐,然后官方也没有给出相应的判断环境的api,其实小程序是预设了这个api的,只是不知道为什么没有公布出来,这个api就是 __wxConfig 关键点 — __wxConfig 在控制台中打印__wxConfig可以得到一下数据 [图片] 其中的envVersion为运行环境,有以下几个值 envVersion: ‘develop’, //开发版 envVersion: ‘trial’, //体验版 envVersion: ‘release’, //正式版 其中的platform为运行的平台 有Android ios devtools 等 之前一直不知道微信小程序可以用__wxConfig.envVersion区分小程序体验版,开发板,正式版 目前在官方文档没有查到相关资料,但是亲测可用 [代码] envVersion 类型为字符串 envVersion: 'develop', //开发版 envVersion: 'trial', //体验版 envVersion: 'release', //正式版 [代码] 具体代码可参考如下截图 [图片] 20191120 其实在我们的开发过程中是不需要这个变量的,因为我们开发版、体验版、和生产版是三个不同的小程序,所以不需要根据环境变量来区分 20191121摘自社区帖子 [代码]const env = typeof __wxConfig !== "undefined" ? __wxConfig.envVersion || "release" : "release"; const isProd = env === "release"; const protocol = isProd ? "https://" : "http://"; const baseApi = { develop: "testapi.com", trial: 'readyapi.com', release: "api.com" }; export const api = protocol + baseApi[env]; [代码]
2019-11-20 - __subContextEngine__.loadJsFiles is nota function?
开发工具调试没问题,但是真机调试就有问题,就会报错[图片]
2021-06-18 - 微信小程序右滑动关闭关闭当前页面,如何禁止这个事件
微信小程序向右滑动可以关闭当前页面,可是我不想让用户滑动关闭当前页面,该如何屏蔽这个动作?
2018-06-13 - jweixin-1.6.0.js导入及调用?
http://res.wx.qq.com/open/js/jweixin-1.6.0.js 这个东西在react中怎么导入,好像不能npm install,如果使用标签引入后,怎么获取文档中的wx对象
2020-09-10 - onShareAppMessage支持异步了?
最近需要做一个分享时需要异步生成图片去分享的需求,但尝试了好多方法, 虽说都可以生成图片,但在onShareAppMessage里更换分享图时发现分享图并没有替换上, 而是自动取了页面截图,说明异步的方式是行不通的, 看了好多帖子也都是因为onShareAppMessage不支持异步的问题。 但是老板给我分享了一个小程序, 这个小程序在分享商品详情时可以明显看出分享图是通过异步合成的, 尝试了多种方法,百思不得其解, 有没有大佬能分析一下他们的实现思路。 [图片]
2020-06-19 - wx.getLocation是限制的使用次数嘛?
最近首页调用wx.getLocation获取用户位置但是出现了第一次可以正常,第二次开始报错频繁调用,让修改为wx.onLocaltionChange,
2021-03-09 - jssdk,调用getLocation后不执行complete回调?
ios执行完success回调后执行complete回调,但是去到安卓机上面就只是执行了success回调,而且success里面调用的方法也没有被执行[图片][图片]
2020-11-18 - 小程序插件的代码包有大小限制吗
小程序插件的代码包有大小限制吗
2018-10-17 - ios13.5+系统webview中页面后退不会刷新页面,而是被挂起了进程,导致页面中的脚本不运行
ios13.5+系统webview中页面后退不会刷新页面,而是被挂起了进程,导致页面中的脚本不运行
2020-06-03 - 微信开发者工具下载的 sourcemaps 怎么用。
什么是 Sourcemaps uglifyjs、bable 等工具会对 源代码 进行编译处理生成编译后的代码(下称目标代码),而 sourcemaps 就是保留了目标代码在源代码中的 位置信息 --------- 大神分割线 --------- 如何解读 Sourcemaps Sourcemaps 是一个 json [代码]{ "version": 3, "sources": ["a.js", "b.js"], // 源文件列表,这个表示是由 a.js 和 b.js 合并生成 "names": ["myFn", "test"], // 如果开启了变量名混淆,这里会保留变量名在源文件中名字信息 "sourcesContent: [], // 可选项,保存源码信息,顺序与 sources 字段对应,chrome 的 sources 面板中源码使用了这个字段的内容进行展示 "sourceRoot": "", // 源文件所在的目录信息 "file": "dist.js", // 可选,编译后的文件名 "mappings": "" // 这个是重点,是目标代码和源文件的位置的映射关系 } [代码] mappings 目标文件"行"的信息 mappings 是使用 ; 分隔的,每个部分对应目标代码的行 如: “;AAAA;AAAA,BBBB;;” 本例子目标文件有 4 行 第 0 行和第 3 行没有源文件对应信息,所以这两行是编译过程中加入的代码 目标文件的"列"信息 如: “AAAA,CAEA,CAEA;” ‘,’ 表示行内的位置信息分隔符 本例表示目标文件的这一行有三个有效的位置信息。 位置信息的第一位表示目标文件的列的 偏移 信息 本例中,表示列的信息是 ‘A’、‘C’、‘C’,对应的数字为 0、+1、+1,(vlq 编码,在线编解码工具) 注意,这个是偏移信息; 列数从 0 开始,依次累加偏移值可以算出当前的位置信息对应的真正的列 所以本例中表示的是目标文件的第 n 行中的第 0 列,第 1 列,第 2 列(没错是第 2 列) 源文件的信息 如:‘AAAA;ACAA;ADAA;’ 位置信息的第二位表示源文件的信息,本例子中是 ‘A’、‘C’、‘D’,对应数字是 0、+1、-1 如果 sourcemaps 中的 sources 字段只有一个文件的话,那么位置信息中第二位一直是 A(不需要偏移) 假设 sourcemaps 中 sources: [‘a.js’, ‘b.js’] 本例的意思是 AAAA: 目标文件第 0 行第 0 列 对应 第 0 个文件 a.js ACAA; 目标文件第 1 行第 0 列 对应 第 1 个文件 b.js ADAA; 目标文件第 2 行第 0 列 对了 第 0 个文件 a.js (偏移是 -1 又回到了 a.js) 源文件的行信息 位置信息的第三位表示源文件中的行的信息, 理解了位置偏移的概念,我们很容易理解 如:‘AACA,CACA;AACA;‘ 那么 AACA: 目标文件的第 0 行第 0 列 对应 第 0 个文件的第 1 行 CACA: 目标文件的第 0 行第 0+1 列 对应 第 0 个文件的第 1+1 行 AACA:目标文件的第 1 行第 0 列 对应 第 0 个文件的第 1 行 (注意:’;’ 后的行列偏移信息归 0) 源文件中的列信息 位置信息的第四位表示源文件中的列的信息 如:'AAAA,CAAC;' 那么 AAAA: 目标文件的第 0 行第 0 列 对应 第 0 个文件的第 0 行第 0 列 CAAC: 目标文件的第 0 行第 0+1 列 对应 第 0 个文件的第 0 行第 0+1 列 位置信息的第五位 第五位表示变量的偏移,对应 sourcemaps 中的 names 字段,表示目标文件中的变量名对应域源文件中的变量 如:’AAAA,CAACC;AAAAD;' sourcemaps 中 names 字段是 [‘a’, ‘b’] 那么 AAAA: 目标文件的第 0 行第 0 列 对应 第 0 个文件的第 0 行第 0 列,没有变量的信息 CAACC: 目标文件的第 0 行第 0+1 列 对应 第 0 个文件的第 0 行第 0+1 列,有变量信息,变量在源文件中是 ‘b’ (0+1=1) AAAAD: 目标文件的第 1 行第 0 列 对应 第 0 个文件的第 0 行第 0 列,有变量信息,变量在源文件中是 ‘a’ (1-1=0) --------- 大神分割线 --------- 怎么使用 Sourcemaps Q: 线上小程序报错,我怎么通过 sourcemaps 还原到源代码中? A: 如报错 appservice.js 1:15000, 表示目标文件第一行 第 15000 列位置报错。根据上文介绍的,通过 mappings 字段算。 Q: 不会。 A: 如果你会写代码的话,参考下边 [代码]import fs = require('fs') import {SourceMapConsumer} from 'source-map' async function originalPositionFor(line, column) { const sourceMapFilePath = '如果你不真的替换的成 sourcemaps 在硬盘中的位置,那你还是放弃自己写代码吧。 ' const sourceMapConsumer = await new SourceMapConsumer(JSON.parse(fs.readFileSync(sourceMapFilePath, 'utf8'))) return sourceMapConsumer.originalPositionFor({ line, column, }) } originalPositionFor(出错的行,出错的列) [代码] Q: 不会写代码 A: 下载最新版的开发者工具,菜单-设置-拓展设置-调试器插件 [图片] [图片] Q: 为啥都是 null? A: 每个小程序版本都应该对应一个sourcemap文件。 运营中心那里下载的 sourcemap 是对应线上最新的小程序版本。但运营中心的报错集合了多个小程序版本。拿旧小程序版本的报错信息,和最新版本的 sourcemap,是匹配不出的。开发者工具和ci 上传的时候,会提示下载对应版本的 sourcemap 信息,可以自助保存。 [图片] Q: 怎么确定有没有版本对应上 A: 下载的 sourcemap 中有个 wx 字段,标明了该 sourcemap 文件对应小程序版本号。 [图片] [图片] 前提 1.确保发生错误的小程序版本和下载回来的 sourcemap 版本是一致的。 a. 下载 sourceMap 文件,可在 mp 后台或开发者工具上传成功弹窗下载 2.确保 map 文件和发生错误的 js 文件是对应的。sourcemap 的目录和文件说明 a. APP 是主包,FULL 是整包(仅在不支持分包的低版本微信中使用),其他目录是分包 b. 每个分包下都有对应的 app-service.js.map 文件。 c. 如果是使用了按需注入特性(app.json中配置了lazyCodeLoading),那么每个分包下还会有 appservice.app.js.map(对应分包下非页面的js),和所有页面的 xxx.js.map 以上事情都确保正确之后,还是出现行列号匹配不出来的情况。那就需要进一步排查。 线上运行的小程序 sourcemap 文件是怎么生成的? 处理流程:源码 [ a.js a.js.map b.js b.js.map ] -> 开发者工具(JS转 ES5,压缩)-> 微信后台(合并 js 文件)[ appservice.app.js appservice.app.js.map]。 注意:如果源码在交给工具之前是经过了 webpack 等打包工具的处理,那源码这里需要有 map 文件。否则不需要存在 map 文件。 可以看出,map 文件经过三个步骤的处理,每个步骤都有可能导致出错,因此开发者需要先排查,是否是前两个步骤出错导致的 map 文件失效的。 如何排查前两个步骤产生的 map 文件是否有问题。 1.排查 a.js.map 文件是否有问题。 a. 可以在 a.js 的代码中写一下 throw new Error(‘test sourcemap’)。 b. 使用了 webpack 的情况下,要构建为生产环境的版本。 c. 在开发者工具模拟器中运行对应的页面,看看控制台中的报错,错误行列号是否能正常映射到源文件。 2.排查 开发者工具(JS转 ES5,压缩)步骤是否有问题。 在排查完第一步的基础上,点击预览,用微信上扫码预览,并打开调试 vConsole 功能,检查 vConsole 中是否有报错信息,检查报错信息中的行列号是否能正常映射到源文件。 如何排查 微信后台(合并 js 文件)是否有问题。 a. 一定要先排查完前两个步骤再来排查这一步,一般情况下,这一步是不会出错的。 b. 如果有问题,也只会导致 map 文件中的行号信息出现偏移。比如 Error 信息中显示报错地址是 100: 200,行号是 100。那么你可能直接用 100: 200 在 map 文件中搜索不出信息,但是如果 用 150: 200 就可以搜索出来,说明行号偏移了 50。那其他报错也可以偏移 50 后再进行搜索就找到结果。 c. 怎么排查偏移了多少?可以结合 error.message 的内容,初步判断大概错误的内容是什么。把对应的 map 文件放到这个网站上 source-map-visualization 进行搜索,找出哪些相同列号的地方。再结合 error.message 的内容进行判断。 d. 如果排查到是这一步导致的问题,请在社区上联系我们,我们会在后续版本进行修复。 依旧排查不出原因? 先整理一下按照上述步骤排查的结论,再在社区上联系我们协助
2023-02-10 - webview 真机 打不开 localhost网页吗?
webview 真机调试 网页地址的localhost 或者127.0.0.1 打开空白,开发工具可以,为什么呢,手机打开了调试的
2020-04-24