- map组件自定义气泡,带有cover-image,在ios上卡顿?
自定义的点位,使用了cover-image有图片,在ios上一次加载超过10个点位,map组件会卡着不动,等加载完成才能滑动;安卓没有这个问题。 是bug还是什么问题?有什么方法解决吗? 【哭死】 [图片]
2024-02-22 - 小程序性能优化实践
小程序性能优化课程基于实际开发场景,由资深开发者分享小程序性能优化的各项能力及应用实践,提升小程序性能表现,满足用户体验。
2024-10-09 - 调用wx.openPrivacyContract打开的页面为空白页面
调用wx.openPrivacyContract打开的页面无内容,为空白页,跳转后的链接如下 https://mp.weixin.qq.com/wxawap/waprivacyinfo?action=show&appid=wx91afd0234a369160#wechat_redirect
2023-08-16 - 小程序代码审核新手入门篇
微信小程序在注册完成,需提交代码审核通过才能顺利发布,小程序从开发到发布的具体流程:微信小程序完成注册、信息设置、类目设置后,代码提审从开发到发布一般要经过:预览-> 上传代码 -> 提交审核 -> 发布等步骤,以下为大家介绍注册到发布前必经流程及代码审核注意事项: 整体流程 [图片] 一、板块分点 信息设置:昵称(简称)、简介、头像设置 类目设置:小程序服务类目申请 代码审核:流程步骤 小程序功能:小程序的功能可用性、内容完整性等进行整体审核 二、板块审核注意事项 1、信息设置 ①昵称板块: 不直接使用广义归纳类、营销词、热门关键词、产品分类词汇命名 未经授权不得擅自使用他人已注册企业名称、商标、他人姓名命名 详情可参考:https://developers.weixin.qq.com/community/operate/doc/00060288824708b8d588e4ae25bc01 ②简介: 明确介绍小程序的功能点、表达的意思需与实际提供的功能一致 ③头像(logo):选用清晰度高,表达内容应与小程序名称、简介、功能相符,且未经授权不得使用腾讯、微信官方或其他官方头像 2、类目设置 1、①自身运营功能与类目保持一致性(提供社交属性服务,应选择社交类目;提供时政信息服务,应选择时政信息类目) 2e ②注册主体不一样,对应开放类目范围不一样,非个人主体、个人主体、境外主体开放详细可参考: https://developers.weixin.qq.com/miniprogram/product/material/ 3、③当所选类目当涉及需报备送属地网信办审核,建议至少上线前14天进行提交审核,避免因二次审核流程过长,延误项目上线时间,报备类目详情可参考: https://developers.weixin.qq.com/community/operate/doc/00002a6a0b8d98a965993666a51001?blockType=5 3、小程序从开发到发布的具体流程: 微信小程序完成注册、信息设置、类目设置后,从开发到发布一般要经过 预览-> 上传代码 -> 提交审核 -> 发布等步骤,以下为大家介绍代码提审流程的注意事项: 3.1预览 使用开发者工具可以预览小程序,帮助开发者检查小程序在移动客户端上的真实表现。 点击开发者工具顶部操作栏的预览按钮,开发者工具会自动打包当前项目,并上传小程序代码至微信的服务器,成功之后会在界面上显示一个二维码。使用当前小程序开发者的微信扫码即可看到小程序在手机客户端上的真实表现。 [图片] 3.2上传代码 同预览不同,上传代码是用于提交体验或者审核使用的。 点击开发者工具顶部操作栏的上传按钮,填写版本号以及项目备注,需要注意的是,这里版本号以及项目备注是为了方便管理员检查版本使用的,开发者可以根据自己的实际要求来填写这两个字段。 [图片] [图片] 上传成功之后,【登录小程序管理后台 - 版本管理 - 开发版本】就可以找到刚提交上传的版本了,可以将这个版本设置体验版或者是提交审核。 [图片] [图片] 3.3 提交审核 为了保证小程序的质量,以及符合相关的规范,小程序的发布是需要经过审核的。 在开发者工具中上传了小程序代码之后,【登录小程序管理后台 - 版本管理 - 开发版本】找到提交上传的版本。在开发版本的列表中,点击 提交审核 按照页面提示,填写相关的信息,即可以将小程序提交审核。 需要注意的是,请开发者严格测试了版本之后,再提交审核,过多的审核不通过,可能会影响后续的审核时长。 [图片] [图片] [图片] [图片] 3.4 发布审核通过之后,管理员的微信中会收到小程序通过审核的通知,此时可以通过电脑端和手机端两种方式来查看审核通知: ①电脑端:【登录小程序管理后台 -通知中心】中可以看到具体的审核结果 [图片] ②手机端:模板消息代码发布审核结果 [图片] 审核通过后,可以点击发布,即可发布小程序。小程序提供了两种发布模式:全量发布和分阶段发布。全量发布是指当点击发布之后,所有用户访问小程序时都会使用当前最新的发布版本。分阶段发布是指分不同时间段来控制部分用户使用最新的发布版本,分阶段发布我们也称为灰度发布。一般来说,普通小程序发布时采用全量发布即可,当小程序承载的功能越来越多,使用的用户数越来越多时,采用分阶段发布是一个非常好的控制风险的办法。 [图片] 4、小程序功能 ①可用性 a、功能运行稳定:确保功能可打开、运行、无报错 b、体验有登录限制:应在提审之前上传有效测试信息、运行录屏,用于辅助审核判断 详情可参考:https://developers.weixin.qq.com/community/develop/doc/0002caeb3c82583722f9cb09456409 ②登录规范合规性 a、特定范围:首页应明确文案提示,服务仅为特定人群使用 b、公开范围:授权个人信息功能后置,给予用户事前了解功能后,由用户主动使用功能时,再进一步进行授权提醒 详情可参考:https://developers.weixin.qq.com/community/operate/doc/000640bb8441b82900e89f48351401 ③小程序内容完整性:提审前确保运营内容的完整性,避免出现如下无法判断的运营内容导致审核失败 ,具体如下: 【测试商品】示例: [图片] 【功能无具体运营内容】示例: [图片] 本文档为初次提交代码审核的开发者了解提审前必经流程、提审注意事项,如存在上述问题应及时调整、修正,同时提前规划好提审时间,避免后续因存在上述问题审核失败或重复提审导致无法如期上线发布。
2022-08-25 - 地图组件map报欠费,没有使用个性化,引用map就要收费?
<map></map> 这样也报欠费
2023-06-29 - 地图组件使用的时候,显示[Component]<Map>欠费,这个是什么原因?
组件名称:Map、微信版本号:Version 8.0.38 基础库版本号:2.32.3[图片],使用地图组件的时候,提示[Component]<map>收费,但是使用的是小程序内置的腾讯地图,不是第三方的地图,也没有说明欠了多少,去哪里充值。
2023-06-30 - scroll-view需要可以按x和y方向拖动,但需要每次拖动我只要一个方向可拖动,如何实现?
我在微信小程序上,手机真机模拟,会发现斜向拖动,两个方向都会变,效果不是很好请问该如何调整呢?感谢各位! 另外,也试过onscroll中根据当前的滚动距离,动态设置scroll-x和scroll-y为true或false,但是在实际手机体验,设置完后总归要慢一拍,体验并不好 如下是当时的部分代码,都是在onsroll事件中返回的 if(Math.abs(e.detail.deltaY)>=Math.abs(e.detail.deltaX)) { this.scroll_x=false; this.scroll_y=true; } else { this.scroll_x=true; this.scroll_y=false; } this.$nextTick(() => { that.scroll_x=true; that.scroll_y=true; })
2023-05-16 - 小程序scroll-view翻转后 scroll-into-view的替代方案
背景 腾讯云医小程序有医患聊天会话的场景,由于会话场景存在查询历史消息的场景,小程序中按照常规思路加载历史消息时会出现跳动的问题;跳动的原因是由于在’顶部’插入dom,会使得后面的dom被往后面推,然后重新设置scroll-top或者scrol-into-view从而导页面出现跳动;我们尝试采用【 前端开发中聊天场景的体验优化】文章中的方案处理跳动的场景。该文章的核心观点将scroll-view元素通过设置css样式 transform: rotateX(180deg); 进行翻转,这样将历史消对应的dom结构放在尾部,当添加更多的历史消息(dom)时,由于dom是添加在尾部很优雅的绕过了插入历史消息跳动的场景。但是当我们按照这种方式实现后,发现scroll-view元素提供的scroll-into-view属性不好使了。因此有了本文通过计算scrollTop值设置scrollTop来达到相同目的。 复现该问题的小程序代码片段:代码片段 目前已经反馈给官方(官方已确认是内部组件实现暂不支持翻转的场景 基础知识介绍 计算scrollTop涉及到一些web和小程序的基础知识,后面针对这些基础点进行简单介绍 .scroll-into-view 微信小程序提供的scroll-view元素提供了属性 scroll-into-view,该属性的作用是可以将指定dom滚动到scroll-view可见区域内 [图片] 关于boundingClientRect 下图是MDN解释该属性时提供的,从下图中可以看到top/bottom/left/right的值是元素的左上角和右下角相对于视口左上角的水/垂直距离 [图片] 为了更深入理解这些值。给出了一个简易的demo(代码片段),获取实例元素的的boundingClientRect的值后,可以看到这些值是根据元素的border边界进行计算的 [图片] [图片] [图片] 值得注意的是,当元素处于一个滚动区域内部,left/top值是考虑滚动操作的即包含滚动距离的(参考MDN 另外,当我们把容器元素又或者元素自身设置 transform: rotateX/Y(180deg):不会导致top和bottom的值互换(left与right的值互换); 总会有这样的结论,当dom元素的宽度和高度不为0时,top值一定小于bottom值,left值一定小于right值 关于scrollTop 当一个容器的内容的高度大于其容器高度时,overflow不为visible/hidden时,则会出现滚动条。出现滚动条后,内容区域则可以滚动,此时scrollTop的值是容器可视区域的顶部到内容区域顶部的距离,见下面示意图。 [图片] 值得注意的是,滚动条出现在盒模型中的content区域,见下图滚动条不会覆盖padding/border部分。因此上面说到内容区域高度超过容器高度并不严谨,严谨的说法应该是超过容器的content区域的高度。 [图片] 如果此时给容器设置css样式: transform: rotateX(180deg); 即沿垂直方向翻转180度,scrollTop的值会发生变化吗。 下面我们看下实际的对比效果,为了方便查看滚动条的效果,给滚动条轨道(红色部分)以及滑块(黑色部分)添加了背景色,发现整个元素包括滚动条在内一并进行了翻转。 正常情况(左侧),应用翻转css样式(右侧) [图片] [图片] 翻转后的scrollTop值示意图 [图片] 通过计算scrollTop值来模拟scroll-into-view效果(针对scroll-view翻转的场景j) 由于boundingClinetRect的值是包含border边界的,因此当数据项包含padding,border等区域不会影响这里的计算过程,可以认为下面示意图中的数据项部分的边界是border边界; 由于滚动条是出现在content区域,因此容器元素的的border-top/padding-top不为0时,会影响计算流程,因此这里分为两种情况进行介绍: 2.1 假设scroll-view元素的的border-top/padding-top为0 2.2 假设scroll-view元素的的border-top/padding-top不为0 border-top/padding-top为0的情况 为了方便说明计算过程,我定义三种状态,初始态、中间态、最终态 示意图中的区域说明 白色背景的为视口, 绿色背景的是容器(scroll-view)的可视区域, 灰色区域是内容区域,并且内容区域的高度超过了容器的高度, 红色区域是一个数据项 [图片] 现在的目标是将数据项从初始态滚动到最终态即scroll-into-view的效果:border的上边界与可视区域上边界对齐 第一步:从初始态达到中间态 根据上面关于scrollTop的描述,这里如果scrollTop的值是targetDistance即数据项的底部到内容区域的底部的距离,就可以达到中间态,因此现在的目标是求targetDistance 初始状态的已知变量 初始状态下的的scrollTop值:currentScrollTop (由于容器发生翻转,所以scrollTop视觉上指向容器下方) 数据项的boundingClientRect.bottom为 itemBottom 容器的boundingClientRect.bottom为 contianerBottom 通过示意图很容易得出 [代码]targetDistance = currentScrollTop + (containerBottom - itemBottom) [代码] 第二步:从中间到达最终态 已知变量:容器高度:containerHeight、数据项高度:itemHeight 最终态是数据项的顶部距离容器顶部,从示意图中看到中间态到最终态的scrollTop是减少了的,减少的值其实就是cotainerHeight - itemHeight 经过第一步和第二步我们就可以得到scrollTop的计算公式 [代码]let itemScrollTop = currentScrollTop + containerBottom - itemBottom itemScrollTop -= (containerHeight - itemHeight) => itemScrollTop = currentScrollTop + containerBottom - itemBottom - (containerHeight - itemHeight) [代码] border-top/padding-top不为0的情况 [图片] 根据上面第一种情况的介绍的思路,很容易得到下面结果,不再赘述(X 就是容器padding-top + border-top的值) [代码]let itemScrollTop = currentScrollTop + containerBottom - itemBottom - X itemScrollTop -= (containerHeight - itemHeight - X) => itemScrollTop = currentScrollTop + containerBottom - itemBottom - X - (containerHeight - itemHeight - X) => itemScrollTop = currentScrollTop + containerBottom - itemBottom - (containerHeight - itemHeight) [代码] 【结论】两种情况最终的计算过程是一样的,因此在实现的过程中不需要进行区分 代码实现 代码片段见:https://developers.weixin.qq.com/s/y1X11dmr7AqC 视图层代码 [代码]{{item.content}} #scroll-view { position: absolute; top: 50px; bottom: 50px; width: 100%; background-color: rgba(0, 0, 0, 0.1); // 关键case transform: rotateX(180deg); } [代码] 逻辑层核心代码 [代码]scrollTo () { const itemId = '#item_id_50' const containerId = '#scroll-view' Promise.all([this._queryBoundingClient(itemId), this._getScrollInfo(containerId)]) .then((res = [[[{}]], {}]) => { const [[[ { bottom: itemBottom, height: itemHeight }]], { bottom: containerBottom, scrollTop, height: containerHeight }] = res let itemScrollTop = containerBottom - itemBottom + scrollTop itemScrollTop -= (containerHeight - itemHeight) this.setData({ scrollTop: itemScrollTop }) }) }, _queryBoundingClient (selector) { // 获取目标dom的相关位置/尺寸信息 return new Promise(resolve => { const query = this.createSelectorQuery(); query.selectAll(selector).boundingClientRect(); query.exec(resolve); }) }, _getScrollInfo (idSelector) { // 用来获取容器层相关位置/尺寸信息 return new Promise(resolve => { const query = this.createSelectorQuery() query.select(idSelector).boundingClientRect() query.select(idSelector).scrollOffset() query.exec((res = [{}, {}]) => { const [{ top, bottom, height }, { scrollHeight, scrollTop }] = res const scrollInfo = { scrollTop, scrollHeight, top, bottom, height } resolve(scrollInfo) }) }) } [代码]
2023-03-23 - 前端架构之路:小程序 Log 日志
前言 后续我会在 [代码]github[代码] 开放源码,并打包至 [代码]npm[代码] ,开发者后续可自行 [代码]install[代码] 调用。 后续 源码地址 及 npm安装方法 将会在该页面更新。 开放时间基于大家需求而定。 通常情况下,日志系统是开发中重要的一环。 但出于种种原因,在前端开发中做日志打印和上报系统却不常见。 但有些特定情况下,日志系统往往有奇效。 比如一个聊天系统中遇到了以下问题: 语音通话中,用户听不到声音 即时通讯中,部分场景用户反馈,消息发送不出去 即时通讯中, A 回复 B 消息时,偶尔对话框不显示 即时通讯中, A 给 B 连续发送两条消息后, B 接收不到第二条的提示 即时通讯中,发送语音消息发送时,用户以为语音已经发送,但实际上录音还在继续。这时用户以为是网络卡了,最后发现自己和其他人说话的声音被录制进去 但是以上几种错误,在后台接口中并没有体现。再加上部分用户手机型号的问题,导致问题很难被定位。 如果我们这里有 [代码]log[代码] ,我们就能很快定位到出问题的代码。 如果不是代码问题,也更有底气回复用户不是我们系统的问题。 如何使用小程序 Log 日志系统 小程序侧提供了两种小程序 Log 日志接口: LogManager ( 普通日志 ) RealtimeLogManager ( 实时日志 ) 官方并没有介绍两者的具体区别,只是强调了 Realtime 的实时性质。 在我看来他们的最大区别就是: [代码]LogManager[代码] 可以让用户有种心安的感觉,因为 [代码]LogManager[代码] 是用户手动反馈的问题。 [代码]RealtimeLogManager[代码] 则对开发者更友好,可以在用户不知情的情况下收集到问题信息,并在用户无感的情况下对问题进行修复。 LogManager 小程序提供的 [代码]Log[代码] 日志接口,通过 [代码]wx.getLogManager()[代码] 获取实例。 注意: 最多保存5M的日志内容,超过5M后,旧的日志内容会被删除。 对于 小程序 ,用户可以通过使用 [代码]button[代码] 组件的 [代码]open-type="feedback"[代码] 来上传打印的日志。 对于 小游戏 ,用户可以通过使用 [代码]wx.createFeedbackButton[代码] 来创建上传打印的日志的按钮。 开发者可以通过小程序管理后台左侧菜单 反馈管理 页面查看相关打印日志。 创建 LogManager 实例 你可以通过 [代码]wx.getLogManager()[代码] 获取日志实例。 括号中可以传参 [代码]{ level: 0 | 1 }[代码] 来决定是否写入 [代码]Page[代码] 的生命周期函数, [代码]wx[代码] 命名空间下的函数日志。 0: 写入 1: 不写入 [代码]const logger = wx.getLogManager({ level: 0 }) [代码] 使用 LogManager 实例 [代码]const logger = wx.getLogManager({ level: 0 }) logger.log({str: 'hello world'}, 'basic log', 100, [1, 2, 3]) logger.info({str: 'hello world'}, 'info log', 100, [1, 2, 3]) logger.debug({str: 'hello world'}, 'debug log', 100, [1, 2, 3]) logger.warn({str: 'hello world'}, 'warn log', 100, [1, 2, 3]) [代码] 用户反馈上传 LogManager 记录的日志 当日志记录后, 用户可以在小程序的 [代码]profile[代码] 页面,单击 反馈与投诉 ,在点击 功能异常 进行日志上传。 开发者处理用户反馈及和用户沟通 开发者可以在小程序后台 管理 -> 用户反馈 -> 功能异常 查看用户反馈的信息。 开发者可以在 功能 -> 客服 下绑定客服微信,绑定后可以在 48小时 内通过微信和反馈用户沟通。 注:沟通需要用户反馈时勾选:允许开发者在 48 小时内通过客服消息联系我。 RealtimeLogManager 小程序提供的 [代码]实时Log[代码] 日志接口,通过 [代码]wx.getRealtimeLogManager()[代码] 获取实例。 注意: [代码]wx.getRealtimeLogManager()[代码] 基础库 2.7.1 开始支持 官方给出实时日志每条的容量上限是 [代码]5kb[代码] 官方对每条日志的定义:在一个页面 onShow -> onHide 之间,会聚合成一条日志上报 开发者可从小程序管理后台: 开发 -> 运维中心 -> 实时日志 进入小程序端日志查询页面 为了定位问题方便,日志是按页面划分的,某一个页面,在onShow到onHide(切换到其它页面、右上角圆点退到后台)之间打的日志,会聚合成一条日志上报,并且在小程序管理后台上可以根据页面路径搜索出该条日志 创建 RealtimeLogManager 实例 你可以通过 [代码]wx.getRealtimeLogManager()[代码] 获取实时日志实例。 [代码]const logger = wx.getRealtimeLogManager() [代码] 使用 RealtimeLogManager 实例 [代码]const logger = wx.getRealtimeLogManager() logger.debug({str: 'hello world'}, 'debug log', 100, [1, 2, 3]) logger.info({str: 'hello world'}, 'info log', 100, [1, 2, 3]) logger.error({str: 'hello world'}, 'error log', 100, [1, 2, 3]) logger.warn({str: 'hello world'}, 'warn log', 100, [1, 2, 3]) [代码] 查看实时日志 与普通日志不同的是,实时日志不再需要用户反馈,可以直接通过以下方式查看实例。 登录小程序后台 通过路径 开发 -> 开发管理 -> 运维中心 -> 实时日志 查看实时日志 如何搭建小程序 Log 日志系统 上面我们知道了小程序的 [代码]Log[代码] 日志怎么使用,我们当然可以不进行封装直接使用。 但是我们直接使用起来会感觉到十分的别扭,因为这不符合我们程序员单点调用的习惯。 那么接下来让我们对这套 Log 系统进行初步的封装以及全局的方法的日志注入。 后续我会在 github 开放源码,并打包至 npm ,需要的开发者可自行 install 调用。 封装小程序 Log 方法 封装 Log 方法前,我们需要整理该方法需要考虑什么内容: 打印格式:统一打印格式有助于我们更快的定位问题 版本号:方便我们清晰的知道当前用户使用的小程序版本,避免出现旧版本问题在新代码中找不到问题 兼容性:我们需要考虑用户小程序版本不足以支持 [代码]getLogManager[代码] 、 [代码]getRealtimeLogManager[代码] 的情况 类型:我们需要兼容 [代码]debug[代码] 、 [代码]log[代码] 、 [代码]error[代码] 类型的 [代码]log日志[代码] 版本问题 我们需要一个常量用以定义版本号,以便于我们定位出问题的代码版本。 如果遇到版本问题,我们可以更好的引导用户 [代码]const VERSION = "1.0.0" const logger = wx.getLogManager({ level: 0 }) logger.log(VERSION, info) [代码] 打印格式 我们可以通过 [代码][version] file | content[代码] 的统一格式来更快的定位内容。 [代码]const VERSION = "1.0.0" const logger = wx.getLogManager({ level: 0 }) logger.log(`[${VERSION}] ${file} | `, ...args) [代码] 兼容性 我们需要考虑用户小程序版本不足以支持 [代码]getLogManager[代码] 、 [代码]getRealtimeLogManager[代码] 的情况 [代码]const VERSION = "0.0.18"; const canIUseLogManage = wx.canIUse("getLogManager"); const logger = canIUseLogManage ? wx.getLogManager({ level: 0 }) : null; const realtimeLogger = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null; export function RUN(file, ...args) { console.log(`[${VERSION}]`, file, " | ", ...args); if (canIUseLogManage) { logger.log(`[${VERSION}]`, file, " | ", ...args); } realtimeLogger && realtimeLogger.info(`[${VERSION}]`, file, " | ", ...args); } [代码] 类型 我们需要兼容 [代码]debug[代码] 、 [代码]log[代码] 、 [代码]error[代码] 类型的 [代码]log日志[代码] [代码]export function RUN(file, ...args) { ... } export function DEBUG(file, ...args) { ... } export function ERROR(file, ...args) { ... } export function getLogger(fileName) { return { DEBUG: function (...args) { DEBUG(fileName, ...args) }, RUN: function (...args) { RUN(fileName, ...args) }, ERROR: function (...args) { ERROR(fileName, ...args) } } } [代码] 完整代码 以上都做到了,就完成了一套 [代码]Log[代码] 系统的基本封装。 [代码]const VERSION = "0.0.18"; const canIUseLogManage = wx.canIUse("getLogManager"); const logger = canIUseLogManage ? wx.getLogManager({ level: 0 }) : null; const realtimeLogger = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null; export function DEBUG(file, ...args) { console.debug(`[${VERSION}] ${file} | `, ...args); if (canIUseLogManage) { logger.debug(`[${VERSION}]`, file, " | ", ...args); } realtimeLogger && realtimeLogger.info(`[${VERSION}]`, file, " | ", ...args); } export function RUN(file, ...args) { console.log(`[${VERSION}]`, file, " | ", ...args); if (canIUseLogManage) { logger.log(`[${VERSION}]`, file, " | ", ...args); } realtimeLogger && realtimeLogger.info(`[${VERSION}]`, file, " | ", ...args); } export function ERROR(file, ...args) { console.error(`[${VERSION}]`, file, " | ", ...args); if (canIUseLogManage) { logger.error(`[${VERSION}]`, file, " | ", ...args); } realtimeLogger && realtimeLogger.error(`[${VERSION}]`, file, " | ", ...args); } export function getLogger(fileName) { return { DEBUG: function (...args) { DEBUG(fileName, ...args) }, RUN: function (...args) { RUN(fileName, ...args) }, ERROR: function (...args) { ERROR(fileName, ...args) } } } [代码] 全局注入 Log 通过该章节的名称,我们就可以知道全局注入。 全局注入的意思就是,不通过手动调用的形式,在方法写完后自动注入 [代码]log[代码] ,你只需要在更细节的地方考虑打印 [代码]log[代码] 即可。 为什么要全局注入 虽然我们实现了全局 [代码]log[代码] 的封装,但是很多情况下,一些新同学没有好的打 [代码]log[代码] 的习惯,尤其是前端同学(我也一样)。 所以我们需要做一个全局注入,以方便我们的代码书写,也避免掉手动打 [代码]log[代码] 会出现遗漏的问题。 如何进行全局注入 小程序提供了 [代码]behaviors[代码] 参数,用以让多个页面拥有相同的数据字段和方法。 需要注意的是, [代码]page[代码] 级别的 [代码]behaviors[代码] 在 2.9.2 之后开始支持 我们可以通过封装一个通用的 [代码]behaviors[代码] ,然后在需要 [代码]log[代码] 的页面进行引入即可。 [代码]import * as Log from "./log-test"; export default Behavior({ definitionFilter(defFields) { console.log(defFields); Object.keys(defFields.methods || {}).forEach(methodName => { const originMethod = defFields.methods[methodName]; defFields.methods[methodName] = function (ev, ...args) { if (ev && ev.target && ev.currentTarget && ev.currentTarget.dataset) { Log.RUN(defFields.data.PAGE_NAME, `${methodName} invoke, event dataset = `, ev.currentTarget.dataset, "params = ", ...args); } else { Log.RUN(defFields.data.PAGE_NAME, `${methodName} invoke, params = `, ev, ...args); } originMethod.call(this, ev, ...args) } }) } }) [代码] 总结 连着开发带整理,林林总总的也有了 [代码]2000+[代码] 字,耗费了三天的时间,整体感觉还是比较值得的,希望可以带给大家一些帮助。 也希望大家更重视前端的 [代码]log[代码] 一点。这基于我自身的感觉,尤其是移动端用户。 在很多时候由于 手机型号 、 弱网环境 等导致的问题。 在没有 [代码]log[代码] 时,找不到问题的着力点,导致问题难以被及时解决。
2022-01-17 - wx.navigateToMiniProgram如何在插件里使用?
https://developers.weixin.qq.com/miniprogram/dev/api/navigate/wx.navigateToMiniProgram.html 需要页面权限:当前是插件页面时,宿主小程序不能调用该接口,反之亦然 这句话啥意思?我是在插件自定义组件里使用,提示“navigateToMiniProgram:fail rejected due to no permission currently in plugin” 如何添加权限?
2022-06-08 - 小程序开发起步
学习 5 节课程,从 0 至 1 做第一个属于你的小程序,深入浅出了解小程序开发。本系列视频,由腾讯课堂 NEXT 学院、微信学堂联合出品。
2022-03-24 - 登录优化:2.0:让你的小程序与用户做朋友
上一篇小程序登录相关的学院课程,我们围绕小程序如何通过优化登录“拉好感”提了几点建议。 前方再次预告,开发人员请及时到场:9月1日起,小程序登录规范规则正式开始执行,未满足登录规范要求的小程序将会被代码审核拦截,请尽快优化。 下面,我们来复习下正确的登录优化姿势。 从陌生人到“知己” 想要“拉好感”并不难,秘诀就在于跟用户做朋友。开发者可以站在用户的角度体验小程序,从而更了解自己的产品。 攻略一:互相认识从自我介绍开始。对于线上仅提供注册功能,服务依赖其他方式提供的小程序,可先让用户知悉小程序功能,再引导用户进行授权。 下面这个ETC小程序,就“秀”了一波:用户可在首页了解小程序相关功能及使用帐号登录的原因,并可先办理ETC再登录。 [图片] [图片] [图片] [图片] [图片] 攻略二:做完介绍,先别急着登录,让对方花点时间了解你。对于服务范围开放的小程序,可先让用户体验了解小程序功能,与其只给用户一个登录选项,不如用“个人魅力”吸引他们。 例如,在这个DJ小程序中,用户可先听音乐蹦迪授权登录后,还能关注作者、风格及电台,或购买周边商品,享受更多服务。 [图片] [图片] [图片] 不过,如果服务范围是特定的,可以直接让用户登录,毕竟你和用户已经是知根知底的“老熟人”了。 攻略三:退一步,给对方留点拒绝的余地。在小程序登录页提供可取消或拒绝的选项按钮,反而更能留下好印象。 以这个拼单小程序为例,用户可先浏览商品信息,查看商品详情。如果用户心动了,点击“我的”进入个人中心授权登录即可下单;如果用户犹豫不决,还可以退出登录页面继续逛。 [图片] [图片] [图片] [图片] 登录优化的Q&A 对规则仍然有疑惑的开发人员,我们也补充了详细的问题解答,希望对你们有帮助—— Q:9月1日后,开发者该如何获得用户的UnionID?用户不登录就没有UnionID,怎么办? UnionID是作为微信体系内,用户帐号在同一主体下不同公众号、小程序及App之间实现数据互通的识别凭证,这个信息本身是匿名化、不敏感且不可反推的。但用户如果在不知情的情况下被获取,并且开发者完成了跨平台或者跨产品的打通,会使得用户产生困惑,为什么同一个用户在帐号A的信息会在帐号B中被展示。 站在用户体验和隐私保护的角度来看,每个人都不希望自己的个人信息在不知情的情况下被获取。因此,开发者要在用户授权登录后,才能获取UnionID 如果用户曾经授权登录过同主体App或关注了同主体公众号,则表示用户已经知情并同意登录,这时开发者可以直接获得UnionID。点击这里查看详情。 如果用户未授权登录,开发者可根据前面的攻略,进一步优化登录体验,让用户更乐意登录使用你的小程序。 unionid就像大型连锁超市(微信内同主体帐号)给客户(用户)发放会员卡(nionid),客户持有会员卡可在连锁超市内享受会员权益。 而用户不知情即被获取unionid,就好比在连锁超市购物后,没有任何信息说明,超市就要求留下手机号码等身份凭证识别信息。下次用户去另一家连锁超市时,超市已清晰记录用户之前的消费记录。这是我们不提倡的。 因此,我们希望在用户对小程序的业务有了解之后,开发者明确告知用户会在什么功能或业务使用unionid打通不同帐号之间的数据。 Q:怎么划分服务范围开放和服务范围特定呢? 举个简单的例子,当你在餐厅、商店消费时,服务员不会要求查看你的身份证明,再为你提供服务,但当你进入学校或公司时,则需先登记才能进去。 因此,服务范围开放是指完全对外开放注册,无需进行特殊身份验证,注册后即可提供线上服务体验的小程序,例如电商、外卖等小程序;服务范围特定则需要进行特殊身份验证,且线上服务仅供特殊身份用户体验,例如学校教学系统、公司员工系统等小程序。 Q:服务范围开放的小程序,可以使用仅提供注册功能小程序的调整方案吗? 如果小程序服务范围属于完全开放,线上仅提供注册功能,其他服务均需以其他方式提供的,例如ETC小程序,可以在首页介绍小程序的服务功能,说明要求使用帐号登录功能的原因后,让用户主动选择登录。 反之则需要让用户进入小程序体验并了解平台功能,在使用需要注册登录才能体验的功能时,才触发登录注册流程。 Q:如果小程序不调用微信个人信息授权,只使用帐号密码或手机号码登录,需要优化吗? 小程序帐号登录,是指开发者在小程序内提供的帐号登录功能,包括但不限于手机号登录、getuserinfo形式登录、邮箱登录等形式。因此,开发者也需根据规范进行优化 再次划重点,请未满足小程序帐号登录规范的开发者们尽快完成优化,为你的小程序增加更多好感度。 未来,我们还将不断优化小程序使用体验,希望开发者与我们一起,让平台生态更加绿色健康。如果你对新规范还有什么疑惑,欢迎在评论区聊聊。
2021-06-23 - 登录优化1.0:你的小程序将会赢得更多用户的青睐!
今天,说一个能为你“拉好感”的改动。 小程序帐号登录功能进行全新的规范升级,包括但不限于手机号登录、邮箱登录等。划重点:从2019年9月1日开始,对于未满足登录规范要求的小程序,我们将会在后续的代码审核环节进行规则提示和修改要求反馈。 用户使用登录功能就像“面基”,第一印象很重要。这几个小改动在提升小程序使用的流畅体验、避免用户对数据采集授权担忧的同时,也将驱动用户更乐意尝试使用小程序服务。来,通过三个问题来解锁正确启用帐号登录的姿势。 跟败好感”的姿势告别 问题一 : 在用户清楚知悉、了解小程序的功能之前,就要求用户进行帐号登录会怎样? [图片] (错误示范:在用户打开小程序后立刻弹出授权登录页) 用户好感-1。刚见面就要牵手未免太尴尬,与其打开小程序后立即跳转提示登录或打开小程序后立即强制弹窗要求登录,不如把主动权交给用户。 用户体验小程序功能后,可以主动点击登录按钮来触发登录流程,也可以选择不登录。 [图片] Tips: 适用于对外开放用户注册流程、无需验证特定范围用户,且注册后即可提供线上服务的小程序。 有个特例, 为学校系统、员工系统、社保卡信息系统等提供服务的小程序,倒是可以直接引导用户进行帐号登录。 [图片] 问题二 : 线上仅提供注册功能,服务依赖其他方式提供的小程序,如ETC注册申请、信用卡申请,在用户未获取任何信息时,首页直接弹框要求登录注册会怎样? [图片] (错误示范:用户进入ETC小程序时立刻弹出授权登录页) 用户好感再-1 。“神秘感”能营造好氛围,但你的小程序都如此优秀了,可以直接告诉用户原因再让他们接受—— 用户在小程序首页了解要求使用帐号登录功能的原因后,可通过登录或注册按钮进行登录操作。 [图片] 问题三 : 在需要登录环节直接跳转登录页面,只给用户一个登录选项会怎样? [图片] (错误示范:登录页面只有登录选项) 用户好感再-N。“霸道总裁”不要太用力,多给些温柔的选项,用户会更快爱上你。 在需帐号登录的环节中,用户可以主动点击登录,或点击取消登录,没有强制登录的行为。 [图片] 姿势掌握了吗?我们希望帮助开发者们能根据正确姿势示范,调整小程序的帐号登录功能,优化用户使用帐号登录功能的体验,更好地与用户相处,同时赢得更多用户的青睐。
2021-06-23 - “分享监听”能力调整
近期我们收到了很多用户对小程序/小游戏中分享功能的投诉:在某些小程序/小游戏中,分享并非是用户主动自发的行为,而是受到了某类利益的诱惑,或是被迫分享。这样的内容充斥在群里、小程序里,对用户造成了骚扰。 分享功能,旨在帮助用户更流畅地与好友分享内容和服务,应是用户自发的行为。在原来的分享接口中,用户发起分享动作之后,可以通过 [代码]success[代码] 、[代码]fail[代码]、[代码]complete[代码]等回调来判断用户是否完成了最后的分享动作。通过这个能力,开发者可以将产品交互在分享这个能力上做得比较自然和顺畅。现在为鼓励用户自发分享喜爱的内容,减少“强制分享至不同群”等滥用分享能力,破坏用户体验的行为,在我们权衡了分享功能带来的利弊后,分享功能将进行以下调整: 10月10日起新提交发布的版本,不再支持分享回调参数 [代码]success[代码] 、[代码]fail[代码] 、[代码]complete[代码],即用户从小程序/小游戏中分享消息给好友时,开发者将无法获知用户是否分享完成,也无法在分享后立即获得分享成功后的回调参数[代码]shareTicket[代码]。该调整可以在基础库 2.3.0及以上版本体验。 此次调整可能影响到三种分享功能的用法。 第一种:判断用户是否分享成功,进而给予用户奖励。 例如:小程序提示用户“分享到5个群,可以获得一张20元的优惠券”。 这类诱导用户分享的行为是我们平台所不倡导的,后续将没有办法实现。 第二种:分享完成后变更当前的页面状态 例如:赠送礼品场景下,用户点击“赠送”按钮,将礼品分享出去,分享成功后,界面展示“等待领取”。 这类场景,我们建议可以适当调整交互方案。例如在分享后继续保留“赠送”按钮,但在页面上提示用户一个礼品只能被一人领取,重复赠送无效。 第三种:通过用户分享之后的 [代码]shareTicket[代码] 获取群唯一标识 [代码]openGId[代码] ,以显示对应群的相关信息。 例如:通过分享小程序到某个群里,可以查看该群内成员的排行榜。 此次调整后,用户分享完成后无法立刻显示该群的排行榜信息,但仍可在用户从群消息点击进入小程序时显示该群的排行榜信息。 10月10日起新提交发布的版本将会受到此调整的影响。 需要各位开发者注意,10月10日起新提交发布的版本将会受到此策略的影响,请及时调整分享相关能力,考虑兼容上述调整带来的影响。 调整策略在基础库 2.3.0 及以上版本生效,该基础库版本对应微信客户端6.7.2版本。另外,考虑到兼容性等问题,在基础库版本 2.3.0 以下的环境中不受此策略影响,小程序/小游戏可继续获取分享回调事件。
2018-09-13 - 修改微信用户信息后,getUserInfo信息什么时候更新?
更新时间:2小时
2020-09-04 - 小程序与小游戏获取用户信息接口调整,请开发者注意升级。
为优化用户体验,使用 wx.getUserInfo 接口直接弹出授权框的开发方式将逐步不再支持。从2018年4月30日开始,小程序与小游戏的体验版、开发版调用 wx.getUserInfo 接口,将无法弹出授权询问框,默认调用失败。正式版暂不受影响。开发者可使用以下方式获取或展示用户信息: 一、小程序: 1、使用 button 组件,并将 open-type 指定为 getUserInfo 类型,获取用户基本信息。 详情参考文档: https://developers.weixin.qq.com/miniprogram/dev/component/button.html 2、使用 open-data 展示用户基本信息。 详情参考文档: https://developers.weixin.qq.com/miniprogram/dev/component/open-data.html 二、小游戏: 1、使用用户信息按钮 UserInfoButton。 详情参考文档: https://developers.weixin.qq.com/minigame/dev/document/open-api/user-info/wx.createUserInfoButton.html 2、开放数据域下的展示用户信息。 详细参考文档: https://developers.weixin.qq.com/minigame/dev/document/open-api/data/wx.getUserInfo.html 请各位开发者注意及时调整接口。
2018-04-16 - 小程序登录、用户信息相关接口调整说明
公告更新时间:2021年04月15日考虑到近期开发者对小程序登录、用户信息相关接口调整的相关反馈,为优化开发者调整接口的体验,回收wx.getUserInfo接口可获取用户授权的个人信息能力的截止时间由2021年4月13日调整至2021年4月28日24时。为优化用户的使用体验,平台将进行以下调整: 2021年2月23日起,若小程序已在微信开放平台进行绑定,则通过wx.login接口获取的登录凭证可直接换取unionID2021年4月28日24时后发布的小程序新版本,无法通过wx.getUserInfo与<button open-type="getUserInfo"/>获取用户个人信息(头像、昵称、性别与地区),将直接获取匿名数据(包括userInfo与encryptedData中的用户个人信息),获取加密后的openID与unionID数据的能力不做调整。此前发布的小程序版本不受影响,但如果要进行版本更新则需要进行适配。新增getUserProfile接口(基础库2.10.4版本开始支持),可获取用户头像、昵称、性别及地区信息,开发者每次通过该接口获取用户个人信息均需用户确认。具体接口文档:《getUserProfile接口文档》由于getUserProfile接口从2.10.4版本基础库开始支持(覆盖微信7.0.9以上版本),考虑到开发者在低版本中有获取用户头像昵称的诉求,对于未支持getUserProfile的情况下,开发者可继续使用getUserInfo能力。开发者可参考getUserProfile接口文档中的示例代码进行适配。请使用了wx.getUserInfo接口或<button open-type="getUserInfo"/>的开发者尽快适配。开发者工具1.05.2103022版本开始支持getUserProfile接口调试,开发者可下载该版本进行改造。 小游戏不受本次调整影响。 一、调整背景很多开发者在打开小程序时就通过组件方式唤起getUserInfo弹窗,如果用户点击拒绝,无法使用小程序,这种做法打断了用户正常使用小程序的流程,同时也不利于小程序获取新用户。 二、调整说明通过wx.login接口获取的登录凭证可直接换取unionID 若小程序已在微信开放平台进行绑定,原wx.login接口获取的登录凭证若需换取unionID需满足以下条件: 如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用2月23日后,开发者调用wx.login获取的登录凭证可以直接换取unionID,无需满足以上条件。 回收wx.getUserInfo接口可获取用户个人信息能力 4月28日24时后发布的新版本小程序,开发者调用wx.getUserInfo或<button open-type="getUserInfo"/>将不再弹出弹窗,直接返回匿名的用户个人信息,获取加密后的openID、unionID数据的能力不做调整。 具体变化如下表: [图片] 即wx.getUserInfo接口的返回参数不变,但开发者获取的userInfo为匿名信息。 [图片] 此外,针对scope.userInfo将做如下调整: 若开发者调用wx.authorize接口请求scope.userInfo授权,用户侧不会触发授权弹框,直接返回授权成功若开发者调用wx.getSetting接口请求用户的授权状态,会直接读取到scope.userInfo为true新增getUserProfile接口 若开发者需要获取用户的个人信息(头像、昵称、性别与地区),可以通过wx.getUserProfile接口进行获取,该接口从基础库2.10.4版本开始支持,该接口只返回用户个人信息,不包含用户身份标识符。该接口中desc属性(声明获取用户个人信息后的用途)后续会展示在弹窗中,请开发者谨慎填写。开发者每次通过该接口获取用户个人信息均需用户确认,请开发者妥善保管用户快速填写的头像昵称,避免重复弹窗。 插件用户信息功能页 插件申请获取用户头像昵称与用户身份标识符仍保留功能页的形式,不作调整。用户在用户信息功能页中授权之后,插件就可以直接调用 wx.login 和 wx.getUserInfo 。 三、最佳实践调整后,开发者如需获取用户身份标识符只需要调用wx.login接口即可。 开发者若需要在界面中展示用户的头像昵称信息,可以通过<open-data>组件进行渲染,该组件无需用户确认,可以在界面中直接展示。 在部分场景(如社交类小程序)中,开发者需要在获取用户的头像昵称信息,可调用wx.getUserProfile接口,开发者每次通过该接口均需用户确认,请开发者妥善处理调用接口的时机,避免过度弹出弹窗骚扰用户。 微信团队 2021年4月15日
2021-04-15