- 小程序中使用ECharts的一种实践 - 基础篇
目前有两种方案,我们先看下两种方案的使用实践,之后看下两种方案的区别与优缺点,最后探讨我们目前应该使用哪种方案。 小程序包体积的提示:小程序单个分包/主包大小不能超过2M,整个小程序所有分包大小不超过20M方案一:使用echarts-for-weixin中的官方组件如何使用:clone官方库 echarts-for-weixin 到本地,将其中的ec-canvas目录复制到自己项目的某个目录下(如components)在自己的组件或页面中,按如下方式使用,// 引入组件 { "usingComponents": { "ec-canvas": "../components/ec-canvas/ec-canvas" } } // 页面中使用 // 页面的js文件 function initChart(canvas, width, height, dpr) { const chart = echarts.init(canvas, null, { width: width, height: height, devicePixelRatio: dpr // 像素比 }); canvas.setChart(chart); var option = { ... }; chart.setOption(option); return chart; } Page({ data: { ec: { onInit: initChart } } }); 这里是一些使用说明: 这里的ec是约定的配置对象,其中约定onInit为canvas组件就绪后的一个回调函数,在这里开发者可以完成获得echart实例,并将echart实例更新到canvas对象上,然后通过setOption可渲染不同的图表。属性canvas-id不能相同如果没有配置ec属性,可以监听init事件,同样可以得到对应的回调参数。属性forceUseOldCanvas,为可配置是否使用旧版canvas,目前强烈不推荐使用,默认为false通过小程序依赖分析可知,ec-canvas 文件夹大小为1006k, 如果直接使用,在只有一个页面的情况下,包体积也将是1010k。如有必要,将 ec-canvas 目录下的 echarts.js 替换为最新版的 ECharts。如果希望减小包体积大小,可以使用自定义构建生成并替换 echarts.js最佳实践推荐设置:使用自定义构建生成并替换echarts.js ,如上面的示例,如果仅选择柱状图,则包体积将缩小到493k将ec-canvas文件夹放在分包的目录中且使用ec-canvas的页面放在分包中,即可在减小主包体积小程序示例代码:https://developers.weixin.qq.com/s/mt5w4Tmr7vM9 方案二:使用插件市场中的“ECharts图表组件”如何使用:可参见此文章及对应插件文档。 该插件提供两种方式 v2.1.1 完整版,插件会计算到小程序的分包(主包)中,该完整版占用978.6k大小v2.1.0 轻量版,没有ECharts依赖库,需自行引入,这里也可以使用官方的自定义构建以减小体积。体积会减少到500k左右下方为使用轻量版的 在mp后台申请添加该插件在app.json中添加该插件(可按需放在主包或分包中) "subPackages": [ { "root": "sub-pages/demos", "pages": [ "index2/index2" ], "plugins": { "echarts": { "version": "2.1.0", "provider": "wx1db9e5ab1149ea03" } } } ] { "plugins": { "echarts": { "version": "2.1.0", "provider": "wx1db9e5ab1149ea03" } } } 3.在使用的组件或页面中添加该插件 { "usingComponents": { "chart": "plugin://echarts/chart" } } 4.在页面中使用 最佳实践推荐设置:使用v2.1.0轻量版,并按需自定义构建引入ECharts文件(必须为v5.1.2版本)将该插件配置到分包中,并在分包中使用该插件,将自定义构建的ECharts文件也放在分包中。因为该插件需要小程序申请,正常预览需要切换为自己的已开通该插件的小程序的appId小程序示例代码:https://developers.weixin.qq.com/s/lEa5U2mW7ZNN 方案比较整体小程序包体积比较[图片][图片] 体积接近 优缺点插件方式-版本为5.1.2,已经很新了,但不是最新版本,echarts-for-weixin可以使用最新版本都支持自定义构建后按需使用推荐方案综上,推荐方案一:官方方案(echarts-for-weixin)可按实际需求进行灵活封装,针对不同场景进行数据更新和实例的销毁:可参考https://juejin.cn/post/7303587697100242982-Vue2中ECharts简单封装的一种实践-详常见问题及不支持的特性见github 进一步的实践可以看下篇:小程序中使用ECharts的一种实践 - 落地篇 如有更好的想法和思考,欢迎评论交流。 参考:[开盖即食]小程序图表插件 ECharts 实战 | 微信开放社区在微信小程序中使用 ECharts - Apache Echartshttps://github.com/ecomfe/echarts-for-weixin微信小程序中使用echarts以及踩坑总结微信小程序使用Echarts和分包的完整步骤小程序快速接入 ECharts 图表插件功能 | 微信开放社区ECharts图表组件 | 小程序插件 | 微信公众平台
03-20 - 一个组件解决隐私授权:小程序用户隐私保护授权弹窗组件
项目链接:https://github.com/94xy/miniprogram-privacy 效果预览: [图片] 使用方法: 1、复制项目 [代码]component[代码] 文件夹中的 [代码]privacy[代码] 文件夹到小程序项目中的组件目录; 2 、在 page.json 中引入组件 { "usingComponents": { "Privacy": "/component/privacy/privacy" } } 3 、在 page.wxml 中使用组件,需要授权显示弹窗,不需要不显示 <Privacy /> 4 、可以在所有使用了隐私接口的页面都加上该组件,授权一次之后使用所有隐私接口不再需要授权 跳过阅读: 可以不阅读就点击“同意”按钮 <Privacy skipRead="{{true}}" /> 流程: 页面显示时使用 wx.getPrivacySetting 接口查询是否需要授权,需要授权则显示组件;用户点击“拒绝”直接退出小程序,用户点击“同意”关闭弹窗并同步给微信,之后可以正常使用所有隐私接口。 注意事项: 2023 年 9 月 15 号之前,默认不会启用隐私相关功能,所以检测不到需要弹窗的情况,可以在 app.json 中配置 "__usePrivacyCheck__": true 之后,接口才可以检测到是否需要弹窗。个人实际情况:我在开发者工具中配置了 "__usePrivacyCheck__": true ,needAuthorization 无论如何返回的都是 false,但在真机模拟的情况下可以返回 true自动打开隐私保护指引界面需在「小程序管理后台」配置《小程序用户隐私保护指引》,官方用户隐私保护指引填写说明。 取消授权: 微信中「微信下拉-最近-最近使用的小程序」中删除小程序可取消授权。 开发者工具中「清除模拟器缓存-清除授权数据」可取消授权。
2023-08-28 - 【干货分享】小程序自定义交易组件开通及打通视频号场景
想要在视频号中拥有交易购物能力,必须接入交易组件,目前包含标准版交易组件和自定义版交易组件两种接入方案,以下是微信给出的对比及适用场景。 [图片] 因为有赞已经为商家小程序提供了完善的电商能力,所以自定义交易组件的方案更适合有赞商家小程序来对接微信视频号。 本文主要分享自定义交易组件开通的流程以及基于有赞场景去接入的时候遇到的一些坑,希望能帮助到大家!~ 一、总流程[图片] 二 、开通微信小程序 这个不必多说,但需要注意的是 1、必须是一个非个人主体的小程序 2、小程序类目需要符合下图要求 [图片] 三、开通微信支付后续的订单创建、同步会拉起微信的收银台完成支付,所以需要小程序开通微信支付的能力 四、检查是否已经开通标准版交易组件标准版和自定义版交易组件是二选一的,所以需要先检查是否开通了标准版交易组件 如果已经开通标准版但没有完成开店任务的话还是可以在微信后台取消使用的; 但如果连开店任务也完成的话,需要先注销(目前微信还没有开放注销功能),如果是有赞的商家的话可以联系有赞客服协助处理 五、授权自定义交易组件权限因为有赞是微信小程序的三方开发服务商,所以需要商家授权自定义交易组件权限,当然如果非服务商开发的话不用关心。 六、申请接入微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/register/apply?access_token=xxxxxxxxx 只需要获取到access_token后请求这个接口即可,接口是同步返回的(历史上是有异步的版本的,这块如果很早接触但没有在维护过的同学要注意了),这个接口请求失败的话可能是以下原因: access_token过期小程序类目不符合已经开通了标准版交易组件七、完成商品接口调试7.1 同步商品类目至微信审核你同步商品的三级类目id以及该类目在微信这边是否要求上传相应的类目资质,需要通过获取微信全量三级类目接口来查询 微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/cat/get?access_token=xxxxxxxxx 根据回参中的 qualification_type 类目资质类型 product_qualification_type 商品资质类型 来判断资质是否需要上传 根据回参中的 qualification 类目资质 product_qualification 商品资质 来查询需要上传资质 将回参中的third_cat_id记录,后续同步商品时会用 需要同步的话,就要调用上传类目资质接口,这是个异步接口,审核结果通过需要通过事件回调获取 微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/audit/audit_category?access_token=xxxxxxxxx 这块资质图片的字段建议先通过上传图片接口换取media_id来传入 7.2 同步品牌至微信审核如果你的同步的商品是一个品牌商品,那么在同步商品之前需要先同步品牌信息至微信审核,在审核通过的回调信息中获取到brand_id,之后同步商品时传入 微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/audit/audit_brand?access_token=xxxxxxxxx 同样的,这块品牌的一些证照图片的字段建议先通过上传图片接口换取media_id来传入 这里导致审核失败的几个原因: 上传证照的图片有问题,譬如有水印、大小超过2M、图片不能正常显示等证照过期 7.3 同步商品至微信审核现在就可以将调用同步商品接口完成商品同步了,也是一个异步接口,需要等审核回调 微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/spu/add?access_token=xxxxxxxxx 这里的tips引用下微信文档上的 注意:[代码]third_cat_id[代码]请根据获取类目接口拿到,并确定其[代码]qualification_type[代码]类目资质是否为必填,若为必填,那么要先调类目资质审核接口进行该[代码]third_cat_id[代码]的资质审核;[代码]qualification_pics[代码]请根据获取类目接口中对应[代码]third_cat_id[代码]的[代码]product_qualification_type[代码]为依据,若为必填,那么该字段需要加上该商品的资质图片;若需要上传某品牌商品,需要按照微信小商店开通规则开通对应品牌使用权限。微信小商店品牌开通规则:点击跳转,若无品牌可指定无品牌(无品牌[代码]brand_id: 2100000000[代码])。库存字段[代码]stock_num[代码]注意如果是0则无法在视频号直播上架该商品。部分特殊品类商品标题需要按照规范上传,请仔细阅读,避免审核不通过。商品标题规则:点击跳转。商品详情字段[代码]desc_info.desc[代码] [代码]desc_info.imgs[代码] 虽然非必填,但一些特殊品类仍然需要上传商品详情,请仔细阅读,避免审核不通过。商品详情规则:点击跳转。 这里应该是有赞场景下去开通自定义交易组件卡点比较严重的一环了,因为有赞的商家基数较大,商品种类较多,所以让商家自己同步一个商品至微信的话很容易被微信审核拒掉。有赞这边给到的一个方案是商家在开通自定义交易组件时,系统会帮商家创建一个简单的测试商品,因为这个商品无类目、无品牌且经验证100%通过商品审核,所以这一环的卡点也就能够被顺利疏通。 八、完成订单接口调试商品同步好后,需要对这个商品用微信支付完成一次交易,并将订单同步至微信 8.1 创建、同步订单因为自定义交易组件历史版本的原因,目前存在两套创建订单并同步至微信的方案 需要后端调用创建订单的微信api获取到ticket,然后小程序获取并通过ticket调用wx.requestPayment来拉起微信收银台(可能会废弃)小程序直接将订单信息通过wx.requestOrderPayment同步给微信,并拉起微信收银台微信这边推荐使用第二套方案 8.2 支付校验1、订单全量同步 如果选择订单全量同步到微信的话,那就不需要支付校验。 2、场景校验后同步 使用scene/check方法先去判断是否为视频号场景(这块后续可能会拓展,交易组件应该还会支持视频号以外的场景),是的话再去同步订单至微信。 这里建议在自定义交易组件接口调试过程中可以全量同步,但后续正常业务下单流程还是通过scene/check方式。因为如果你的小程序商城还支持其他支付方式的话,全量同步订单的话就会有坑,原因是无论你选择哪种创建、同步订单的方式都需要唤起微信支付,这样在原本能支持多种支付方式的场景下只能使用微信支付。 8.3 发布小程序因为创建、同步订单和支付校验有一些小程序的改动,所以小程序还是需要发布版本的。仅是开通流程的话走微信开发者工具也ok。 8.4 支付同步微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/order/pay?access_token=xxxxxxxxx 创建订单并支付成功后调用支付同步接口,就会将订单状态流转待发货 九、完成物流接口调试9.1 订单发货微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/delivery/send?access_token=xxxxxxxxx 9.2 订单收货微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/delivery/recieve?access_token=xxxxxxxxx 十、完成售后接口调试10.1 创建售后微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/aftersale/add?access_token=xxxxxxxxx 10.2 更新售后微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/aftersale/update?access_token=xxxxxxxxx 物流、售后接口的调试,如果只是开通流程的话,建议直接后端自动调用完成,可以减少卡点,帮助快速开通。 十一、完成接入任务11.1 获取接入状态微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/register/finish_access_info?access_token=xxxxxxxxx 回参中的access_info内 spu_audit_success 在商品接口调试成功后会被置为1 pay_order_success 在订单接口调试成功后会被置为1 send_delivery_success 在物流接口调试成功后会被置为1 add_aftersale_success 在售后接口调试成功后会被置为1 11.2 完成所有接入任务微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/register/finish_access_info?access_token=xxxxxxxxx 这个接口可以在上面获取接入状态接口返回的spu_audit_success、pay_order_success、send_delivery_success、add_aftersale_success的字段都为1时一次性调用完成所有。 当下面的任务都被完成后,自定义交易组件就已经完成接入了 6:完成spu接口,7:完成订单接口,8:完成物流接口,9:完成售后接口,10:测试完成,11:发版完成 十二、自定义交易组件接入视频号场景微信接口地址:点击跳转 http请求方式:POST https://api.weixin.qq.com/shop/register/finish_access_info?access_token=xxxxxxxxx 只需要调用场景申请接口来申请视频号场景,然后等待微信申请成功就可以完成自定义交易组件接入视频号了 十三、微信后台添加视频号推广员需要去微信后台添加一个视频号为推广员,然后就可以在这个视频号关联到已经开通自定义交易组件的小程序,关联后就可以上架已经商品同步接口调用通过的商品了。 [图片] [图片]
2021-10-27 - 关于扫普通链接二维码进入小程序的一些经验分享
背景 扫普通链接二维码进入小程序一直是社区的高频问题,大部分同学遇到的问题无非以下几类: 我明明下载并放置了校验文件,配置了规则后依然无法跳转小程序没有读懂文档,误认为给小程序路径配置了参数即可跳转规则和测试链接不匹配规则和测试链接匹配,但是不跳转小程序解决方法 针对第一类问题,列举以下两个例子: [图片] 浏览器能访问到校验文件只是基础,在这个基础上校验文件路径一定要和二维码规则路径匹配才可以 针对第二类问题: 小程序路径是无需配置参数的,属于读不懂文档导致画蛇添足的操作 *-* 针对第三类问题,这里贴一下官方文档,错误类型展示比较全: [图片] 针对第四类问题: 二维码规则配置后,官方需要收录,这里可能会花费一定的时候,稍后再试即可检查一下是否是自身配置有问题,校验文件是否和二维码规则匹配检查二维码规则域名的合法性,域名须通过ICP备案的验证 二维码规则的发布 [图片] 如有错误阐述,欢迎评论指正
2022-07-05 - 为什么扫普通二维码进入小程序页面,onLoad 执行了两次?
扫普通二维码进入小程序页面,onLoad 执行了两次,导致获取二维码中参数失败。因为只有在第一个才能拿到参数,第二次为空。 正常路径进入页面是不会执行两次的。请问大家有谁遇到这种情况。
2022-05-10 - 微信开放平台第三方代实现小程序业务简述
一、微信公众平台-第三方平台开发(什么是第三方平台) 微信公众平台-第三方平台(简称第三方平台)开放给所有通过开发者资质认证后的开发者使用。在得到公众号或小程序运营者(简称运营者)授权后,第三方平台开发者可以通过调用微信开放平台的接口能力,为公众号或小程序的运营者提供账号申请、小程序创建、技术开发、行业方案、活动营销、插件能力等全方位服务。同一个账号的运营者可以选择多家适合自己的第三方为其提供产品能力或委托运营。 从具体的业务场景上说,第三方平台包括以下场景: 1、提供行业解决方案,整体打包公众号或小程序的产品开发等; 2、行业:提供更加专业的运营能力,精细化运营用户公众号或小程序; 3、功能:对公众平台功能的优化,如专门优化图文消息视觉样式和排版的工具,或专门定制的 CRM 用户管理功能,或功能强大的小程序插件等。 二、第三方平台代实现小程序业务 第三方平台代实现小程序业务,即第三方平台帮助旗下已授权的小程序进行代码管理。和普通的小程序开发流程相比,第三方代实现小程序业务,需要先开发完成小程序模板,再将小程序模板部署到旗下小程序帐号中 三、从0到1代实现小程序业务 3.1 微信开放平台注册与认证 在微信开放平台https://open.weixin.qq.com/ 注册帐号,并在账号中心中,完成认证。 [图片] 3.2 创建第三方平台 1)在“微信开放平台-管理中心-第三方平台”创建第三方平台。 [图片] 2)选择对应的服务商类型进行第三方平台创建。 *定制化开发服务商:指具备完整开发独立小程序或插件,并可以提供后续运营的服务商。定制化服务商,可将自己已经开发出的定制化小程序关联到服务商平台中,生成凭证(票据)填充到小程序代码包中进行关联。平台获取开发关系。 *平台型服务商:平台型服务商可以通过一键授权,获得为商户开发部署小程序的权限,代商户完成小程序的开发部署及上线。 [图片] Step 1 : 基本信息填写 平台名称: 名称尽可能能够和自己的业务方向相似,且不要包含测试等字样。 业务标签:有如下几类,可以按照行业划分,也可以按照功能划分,标签选择自己业务范畴之内的即可。 [图片] 平台简介: 这里将显示在详情页中,一般用户从这里获得对平台的业务认知,建议要合理填写。 官方网站: 此处填写你的官网域名,需要注意的是,此处写的地址必须要和此第三方平台的业务描述相一致。否则在审核的时候会被驳回的。 平台图标: 需要自己制作核实的图标,必须保证是108*108像素,仅支持PNG格式,大小不超过300KB。 Step 2 :选择权限 微信开放平台为第三方平台型服务商提供丰富的权限勾选,服务商自由选择需要的权限,所勾选的权限,将在用户授权页面展示。最终服务商可获得的权限,以授权用户选择的权限为准。关于权限详情,可查询第三方平台权限说明 特别提醒,请勿随意全选所有权限,当选择一些没有用到的权限集时,会在全网发布的自动化测试时触发某些检测,导致不能通过。具体可以细看全网发布接入检测说明 [图片] Step 3 :开发资料填写 [图片] 授权发起页域名: 此处填写的是跳转授权页时所在的域名,比如此处填写 w.example.com ,那么授权页必须从这个域名中打开才能正常显示,否则会出错。这在一定程度上防止了授权信息的盗用和滥授权,一般这里填用户授权可以访问的业务域名。这里不校验https,但是需要保证域名是实名且可以公共访问的。 授权测试公众号列表: 由于在创建后并没有全网发布,需要先行做开发测试,这里就是用于测试的公众号、小程序的原始ID。我们需要找到一个任意主体的小程序用来测试,推荐选择自己的,好在接下来的环节中实践。需要注意的是,在全网发布之前,扫描授权页二维码授权的账号只能在这个列表中选择,列表外的没有办法成功授权! 授权事件接收URL: 此处需要填写一个API地址,开放平台向你发送的所有消息均通过请求此URL来完成。在这个地址请求后,需要程序判定消息的类型以及相应的处理方法。在此实践中,此URL主要用来接收开放平台的验证票据(component_verify_ticket) 信息校验Token和消息加解密Key: 这两个主要用来解密开放平台向接收URL发送的消息,或者加密信息向开放平台发送。token填写任意一个字符串即可,key必须保证长度为43位的字符串,只能是字母和数字。 小程序服务器域名: 在授权过来的小程序中配置的合法域名必须在此设置的列表中,本教程小程序使用云开发作为后端服务,所以此处设置的域名没有用到,在使用传统后端服务模式时,建议填写支持小程序后台服务的域名。 小程序业务域名: 在授权过来的小程序中配置的合法域名必须在此设置的列表中,本教程小程序使用云开发作为后端服务,所以此处设置的域名没有用到,在使用传统后端服务模式时,建议填写支持小程序后台服务的域名。 白名单IP地址: 这两个主要用来解密开放平台向接收URL发送的消息,或者加密信息向开放平台发送。token填写任意一个字符串即可,key必须保证长第三方平台所有的API接口必须在白名单列表中的IP才可以成功响应,一般填写自己服务器的公网IP。 更多信息可查询文档申请资料说明 完成上述【基本信息】、【选择权限】和【开发资料】信息填写后,提交审核即可,审核时间1小时以内。审核成功后,就可以使用相关接口进行对应开发。 3.3 平台型服务商代实现小程序基本流程 3.3.1开发准备 1)配置域名并设定授权事件url 2)创建授权事件接收URL的服务监听 微信开放平台向授权事件url发送相关的开发或通知信息,如验证票据等。开放平台向此URL发送的数据是加密过的,具体遵循消息加解密方案。 3)使用接收到的验证票据(component_verify_ticket)获取令牌 令牌是第三方平台接口的调用凭据,根据官方文档-获取令牌可知,我们需要请求API接口:https://api.weixin.qq.com/cgi-bin/component/api_component_token 在请求时需要提供三个参数:component_appid(第三方平台 appid)、component_appsecret(第三方平台 appsecret)、component_verify_ticket(第二步获取的ticket),其中前两个我们可以在开放平台直接获取。 [图片] 4)使用令牌获取预授权码并拼接用户授权链接 预授权码(pre_auth_code)是第三方平台方实现授权托管的必备信息,每个预授权码有效期为 10 分钟。一般我们获取它用来拼接授权链接并发给用户使用。 5)获取第三方调用令牌 3.3.2 小程序模版开发 平台型服务商需要将现成小程序模板通过接口直接上传部署到用户的小程序账号中。具体操作为我们在第三方平台的控制台中可以添加开发小程序。 [图片]选择自己为管理者的小程序账号。在添加流程中,也是需要验证小程序账号密码并通过管理员微信扫码验证的。(这里是输入谁的小程序账号密码?) [图片] 当添加成功之后,我们便可以在公众平台的设置页中看到如下信息的变化,开发小程序所属账号为我们的第三方平台的账号,此时小程序的代码上传便由第三方平台接管。 [图片] 使用微信开发者工具使用此小程序appid创建或导入项目,效果如下,跟普通开发相比,多了一个平台名 [图片] 当我们上传代码时,会提示上传到第三方平台的草稿箱。 [图片] 当上传之后,我们便可以在第三方平台详情页中看到我们上传的代码。 [图片]我们可以点击右边的按钮,直接将代码直接添加到模板库中,也可以删除。 [图片]添加后在模板库中就会出现模板代码,并附带有模板编号,我们便可以通过对应的API接口直接将此模板小程序上传至指定的授权小程序中了,无需再用开发者工具上传提交。 具体关于模板小程序的细则,可以查看官方文档。其中关于extAppid的开发调试属于小程序开发的范畴知识附加,在这里不详细阐述。 3.3.3 小程序模板部署与发布(提审) 小程序模版开发完成后,可以点击全网发布按钮。 [图片] 在发布前会进行自动化测试检查,在本教程推荐的两个权限集勾选,无其他权限集的状态下,只需要验证票据的推送状态。具体可以细看全网发布接入检测说明。 检测通过后,会进行资质审核。主要检查你的官网描述是否和设置的描述相仿。审核通过后,第三方平台业务即可上线,可向所有符合要求的公众号、小程序进行登录授权。
2021-09-09 - wx.faceDetect在iphone手机,第二次调用直接进入到fail函数,请问是什么原因?
在iphone手机上首次呼出图片中这个底部弹窗一切正常,当识别成功或者关闭之后,第二次呼出这个弹窗识别的时候会直接进入fail函数,不管怎样摆正姿势都是这个结果。代码片段:https://developers.weixin.qq.com/s/mUCpIWmW7Xw6[图片][图片]
2022-02-09 - 小程序使用threejs时,IOS显示正常,安卓不加载纹理且是黑色的?
[图片] 左侧是PC端自动真机调试,右侧是本地调试。在苹果手机上真机调试也可以出现图片纹理,但在安卓手机上真机调试就变成黑色的了。 主要代码如下 [图片]
2022-05-24 - 云开发快速入门
如果你想免费、快速的开发出一个完整的项目,用小程序的云开发可能是最好的选择。小程序的云开发所用到的主要是前端开发的知识。 注册微信小程序 小程序的注册非常方便,打开小程序注册页面,按照要求填入个人的信息,验证邮箱和手机号,扫描二维码绑定你的微信号即可,3 分钟左右的时间即可搞定。 注册页面:小程序注册页面 https://mp.weixin.qq.com/ 注册小程序时不能使用注册过微信公众号、微信开放平台的邮箱哦,也就是需要你使用一个其他邮箱才行。 当我们注册成功后,就可以自动登入到小程序的后台管理页面啦,如果你不小心关掉了后台页面,也可以点击小程序后台管理登录页进行登录。 后台管理页:小程序后台管理登录页 https://mp.weixin.qq.com/ 小程序和微信公众号的登录页都是同一个页面,他们会根据你的不同的注册邮箱来进行跳转。 进入到小程序的后台管理页后,点击左侧菜单的开发进入设置页,然后再点击开发设置,在开发者 ID 里就可以看到 AppID(小程序 ID),这个待会我们有用。 注意小程序的ID(AppID)不是你注册的邮箱和用户名,你需要到后台查看才行哦~ 必备工具与云开发文档 大家可以根据自己的电脑操作系统来下载相应的版本,注意要选择稳定版 Stable Build 的开发者工具。 开发者工具:小程序开发者工具下载地址 和学习任何编程一样,官方技术文档都是最值得阅读的参考资料。技术文档大家先只需要花五分钟左右的时间了解大致的结构即可,先按照我们的教学步骤学完之后再来看也不迟哦。 技术文档:云开发官方文档 由于小程序的云开发在不断新增功能,更新非常频繁,所以要确保自己的开发者工具是最新的哦(不然会报很多奇奇怪怪的错误),比如你之前下载过要先同步到最新才行~ 体验云开发模板小程序 安装完开发者工具之后,我们使用微信扫码登录开发者工具,然后使用开发者工具新建一个小程序的项目: 项目名称:这个可以根据自己的需要任意填写;目录:大家可以先在电脑上新建一个空文件夹,然后选择它;AppID:就是之前我们找到的 AppID(小程序 ID)(也可以下拉选择 AppID)开发模式为小程序(默认),后端服务选择小程序·云开发点击新建确认之后就能在开发者工具的模拟器里看到云开发 QuickStart 小程序,在编辑器里看到这个小程序的源代码。 接下来,我们点击开发者工具的工具栏里的预览图标,就会弹出一个二维码,使用微信扫描这个二维码就能在手机里看到这个小程序啦。 如果你没有使用微信登录开发者工具,以及你的微信不是该小程序的开发者是没法预览的哦。 在手机里(或模拟器)操作这个小程序,把小程序里的每个按键都点一遍,看看会有什么反应。我们会发现很多地方都会显示“调用失败”等,这非常正常,我们接下来会通过一系列的操作让小程序不报错。 开通云开发服务 点击微信开发者工具的“云开发”图标,在弹出框里点击“开通”,同意协议后,会弹出创建环境的对话框。这时会要求你输入环境名称和环境 ID,以及当前云开发的基础环境配额(基础配额免费,而且足够你使用哦)。 建议你环境名称可以使用 xly、环境ID自动生成即可,当你的云开发环境出现问题的时候,你可以提供你的环境ID,云开发团队会有专人为你解答。 按照对话框提示的要求填写完之后,点击创建,会初始化环境,环境初始化成功后会自动弹出云开发控制台,这样我们的云开发服务就开通啦。大家可以花两分钟左右的时间熟悉一下云开发控制台的界面。 找到云开发的环境 ID 点击云开发控制台窗口里的设置图标,在环境变量的标签页找到环境名称和环境 ID。 当云开发服务开通后,我们可以在小程序源代码 cloudfunctions 文件夹名看到你的环境名称。如果在 cloudfunctions 文件夹名显示的不是环境名称,而是“未指定环境”,可以鼠标右键该文件夹,选择“更多设置”,然后再点击“设置”小图标,选择环境并确定。 指定小程序的云开发环境 在开发者工具中打开源代码文件夹 miniprogram 里的 app.js,找到如下代码: wx.cloud.init({ // 此处请填入环境 ID, 环境 ID 可打开云控制台查看 env: 'my-env-id', traceUser: true, }) 在 env: 'my-env-id'处改成你的环境 ID,如 env: 'xly-snoop' 下载 Nodejs NodeJS 是在服务端运行 JavaScript 的运行环境,云开发所使用的服务端环境就是 NodeJS。npm 是 Node 包管理器,通过 npm,我们可以非常方便的安装云开发所需要的依赖包。 npm是前端开发必不可少的包(模块)管理器,它的主要功能就是来管理包package,包括安装、卸载、更新、查看、搜索、发布等,其他编程语言也有类似的包管理器,比如Python的pip,PHP的composer、Java的maven。我们可以把包管理器看成是windows的软件管理中心或手机的应用中心,只是它们用的是可视化界面,包管理器用的是命令行Command Line。 下载地址:Nodejs 下载地址 大家可以根据电脑的操作系统下载相应的 NodeJS 安装包并安装(安装时不要修改安装目录,啥也别管直接 next 安装即可)。打开电脑终端(Windows 电脑为 cmd 命令提示符,Mac 电脑为终端 Terminal),然后逐行输入并按 Enter 执行下面的代码: node --version npm --version 如果显示为 v10.15.0 以及 6.11.3(可能你的版本号会有所不同),表示你的 Nodejs 环境已经安装成功。 学编程要仔细,一个字母,一个单词,一个标点符号都不要出错哦。注意输上面的命令时node、npm的后面有一个空格,而且是两个短横杠–。 部署并上传云函数 部署并上传云函数 cloudfuntions 文件夹图标里有朵小云,表示这就是云函数根目录。展开 cloudfunctions,我们可以看到里面有 login、openapi、callback、echo 文件夹,这些就是云函数目录。而 miniprogram 文件夹则放置的是小程序的页面文件。 cloudfunctions里放的是云函数,miniprogram放的是小程序的页面,这并不是一成不变的,也就是说你也可以修改这些文件夹的名称,这取决于项目配置文件project.config.json里的如下配置项: "miniprogramRoot": "miniprogram/", "cloudfunctionRoot": "cloudfunctions/", 但是你最好是让放小程序页面的文件夹以及放云函数的文件夹处于平级关系且都在项目的根目录下,便于管理。 使用鼠标右键其中的一个云函数目录比如 login,在右键菜单中选择在终端中打开,打开后在终端中输入以下代码并按 Enter 回车执行: npm install 如果显示“npm不是内部或外部命令”,你需要关闭微信开发者工具启动的终端,而是重新打开一个终端窗口,并在里面输入 cd /D 你的云函数目录进入云函数目录,比如 cd /D C:\download\tcb-project\cloudfunctions\login进入login的云函数目录,然后再来执行npm install命令。 这时候会下载云函数的依赖模块,下载完成后,再右键 login 云函数目录,点击“创建并部署:所有文件”,这时会把本地的云函数上传到云端,上传成功后在 login 云函数目录图标会变成一朵小云。 在开发者工具的工具栏上点击“云开发”图标会打开云开发控制台,在云开发控制台点击云函数图标,就能在云函数列表里看到我们上传好的“login”云函数啦。 上传所有云函数 接下来我们按照这样的流程把其他所有云函数(如 openapi)都部署都上传,也就是要执行和上面相同的步骤,总结如下: 右键云函数目录,选择在终端中打开,输入 npm install命令下载依赖文件; 然后再右键云函数目录,点击“创建并部署:所有文件” 在云开发控制台–云函数–云函数列表查看云函数是否部署成功。 login、openapi、echo、callback这些云函数在后面都会用到的哦,一定要确定自己部署上传成功,不然后面会报错的哦。 npm 包管理器与依赖模块 为什么要在云函数目录执行 npm install,而不是其他地方?这是因为 npm install 会下载云函数目录下的配置文件 package.json 里的 dependencies,它表示的是当前云函数需要依赖的模块。package.json 在哪里,就在哪里执行 npm install,没有 package.json,没有 dependencies,就没法下载啊。 执行 npm install 命令下载的依赖模块会放在 node_modules 文件夹里,大家可以在执行了 npm install 命令之后,在电脑里打开查看一下 node_modules 文件夹里下载了哪些模块。 既然 npm install 是下载模块,那它是从哪里下载的呢?就以 wx-server-sdk 为例,我们可以在以下链接看到 wx-server-sdk 的情况: https://www.npmjs.com/package/wx-server-sdk 为什么 package.json 里依赖的是一个模块 wx-server-sdk,但是 node_modules 文件夹里却下载了那么多模块?这是因为 wx-server-sdk 也依赖三个包 tcb-admin-node、protobuf、jstslib,而这三个包又会依赖其他包,子子孙孙的,于是就有了很多模块。 node_modules 文件夹这么大(几十 M~几百 M 都可能),会不会影响小程序的大小?小程序的大小只与 miniprogram 文件夹有关,当你把云函数都部署上传到服务器之后,你把整个 cloudfuntions 文件夹删掉都没有关系。相同的依赖(比如都依赖 wx-server-sdk)一旦部署到云函数之后,你可以选择不上传 node_modules 时,因为已经上传过了。 获取 openid 与云函数 login 当我们把云函数 login 部署上传成功后,就可以在模拟器以及手机(需要重新点击预览图标并扫描二维码)里点击获取 openid 了。 点击获取 openid openid 是小程序用户的唯一标识,也就是每一个小程序用户都有一个唯一的 openid。点击“点击获取 openid”,在用户管理指引页面如果显示“用户 id 获取成功”以及一串字母+数字,那么表示你 login 云函数部署并上传成功啦。如果获取 openid 失败,你则需要解决 login 云函数的部署上传,才能进行下面的步骤哦。 调用云函数的解读 小程序的首页是”pages/index/index”,我们可以从 app.json 的配置项或者模拟器左下角的页面路径可以看出来。在 index.wxml 里有这段代码: <button class="userinfo-nickname" bindtap="onGetOpenid">点击获取 openid</button> 也就是当点击“点击获取 openid”按钮时,会触发 bindtap 绑定的事件处理函数 onGetOpenid,在 index.js 里可以看到 onGetOpenid 事件处理函数(在 index.js 里找到事件处理函数 onGetOpenid 对比理解)调用了 wx.cloud.callFunction()接口(打开技术文档对比理解) 技术文档:调用云函数 wx.cloud.callFunction 调用云函数的方法很简单,只需要填写云函数的名称 name(这里为 login),以及需要传递的参数(这里并没有上传参数),就可以进行调用。在 success 回调函数里添加以下代码打印 res 对象: console.log('调用login云函数返回的res',res) 添加完成之后记得保存代码哦,文件修改没有保存会在标签页有一个小的绿点。可以使用快捷键(同时按)Ctrl和S来保存(Mac电脑为Command和S)。 编译之后,再点击“点击获取 openid”按钮,就能看到完整的 res 对象,res 对象有三个参数: requestID:云函数执行 ID,可用于在云开发控制台查找日志,打开云开发控制台–云函数–日志,可以在这里根据云函数函数名以及 requestID 来筛选查看云函数的调用日志(含返回结果);result:云函数返回的结果,login 云函数返回的结果里包含 appid、event 对象,我们可以通过 res.result.appid 以及 res.result.event 访问它们;errMsg:显示云函数是否调用成功事件处理函数 onGetOpenid 调用云函数成功之后,干了三件事情: 使用 console.log 打印 openid,可以在点击按钮触发云函数在控制台看到该打印结果;把获取到的 appid 赋值给 app.js 文件里的 globalData 全局对象;跳转到 userConsole 页面;而 userConsole 页面就只是从 globalData 里将 openid 取出来通过 setData 渲染到页面。 小任务:你明白为啥wx.cloud.callFunction()是小程序端的API了么?思考一下为啥云开发会有小程序端的API和服务端API的区别?能理解多少是多少,不清楚也没有关系,后面会有更多内容助你理解。 云函数 login 解读 为什么调用云函数 login 返回的 res 的 result 对象里会包含 event 对象、appid、userInfo 这些结果?这就取决于云函数是怎么写的了。使用开发者工具打开 login 云函数(在 cloudfuntions 文件夹里)的 index.js。 exports.main = (event, context) => {} 这是一个箭头函数的写法,其中 event 和 context 是参数。我们将两个打印日志修改为以下代码,相当于备注一下到底打印到哪里去了: console.log('服务端打印的event',event) console.log('服务端打印的context',context) 保存之后,右键点击 index.js 文件,选择云函数增量上传:(更新文件),更新 login 云函数,我们再来点击“点击获取 openid”按钮,打印的结果在哪里呢?在云开发控制台的云函数日志里面(注意不是开发者工具的控制台)。打开云开发控制台–云函数–日志,按函数名筛选,选择 login 云函数,可以看到云函数被调用的日志记录,我们可以在日志里发现: event 对象包含程序用户的 openid 和小程序的 appid,而 openid 就相当于用户的身份证,我们可以根据 openid 获取到用户的昵称、头像等信息(后面会说明);而 context 对象则是云函数的调用信息和运行状态。在返回结果里我们可以看到 return 返回的数据小任务:比较一下云开发控制台的云函数日志打印的结果和开发者工具控制台打印的结果,深入了解 event 对象、context 对象、result 对象与返回结果,这是云函数的比较重要的知识点。云函数的打印日志会显示在云开发控制台的日志里面,这一点非常重要,要多加利用。只要是打印日志,无论是显示在开发者工具控制台还是显示在云开发控制台的就没有不重要的。 getWXContext() getWXContext()API 是云开发服务端的工具类 API,会返回小程序用户的 openid、小程序 appid、小程序用户的 unionid 等。说这么多不如直接打印,在下面添加一行打印信息: const wxContext = cloud.getWXContext() console.log('getWXContext返回的结果',wxContext) 保存之后,右键点击 index.js 文件,选择云函数增量上传:(更新文件),更新 login 云函数,我们再来点击“点击获取 openid”按钮,然后去云开发控制台的云函数日志里看到底返回了什么结果。 技术文档:getWXContext() 对照技术文档来理解返回的结果。 注意小程序用户 unionid只有在开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用才能获得。 return return 语句是终止函数的执行,并返回一个指定的值给函数调用者。这里返回了 4 个值,而前面我们就调用过 login 云函数,就是函数的调用者,所以我们打印的事件处理函数 onGetOpenid 的回调函数的 res 对象正是这个 return 返回的结果。那既然如此,我们在 return 多加一些内容看看,比如我们之前的一些数据结构案例,将 return 函数改为如下代码: let lesson = "云开发技术训练营"; let enname = "CloudBase Camp"; let x = 3, y = 4, z = 5.001, a = -3, b = -4, c = -5; let now = new Date(); return { movie: { name: "霸王别姬", img: "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1910813120.webp", desc: "风华绝代。" }, movielist:["肖申克的救赎", "霸王别姬", "这个杀手不太冷", "阿甘正传", "美丽人生"], charat: lesson.charAt(4), concat: enname.concat(lesson), uppercase: enname.toUpperCase(), abs: Math.abs(b), pow: Math.pow(x, y), sign: Math.sign(a), now: now.toString(), fullyear: now.getFullYear(), date: now.getDate(), day: now.getDay(), hours: now.getHours(), minutes: now.getMinutes(), seconds: now.getSeconds(), time: now.getTime(), event, openid: wxContext.OPENID, appid: wxContext.APPID, unionid: wxContext.UNIONID, } 保存之后,右键点击 index.js 文件,选择云函数增量上传:(更新文件),更新 login 云函数,我们再来点击“点击获取 openid”按钮,然后去云开发控制台的云函数日志里看到底返回了什么结果。 这里我们多次反复提及更新了index.js文件之后就要选择云函数增量上传:(更新文件),更新login云函数,希望大家平时的时候注意,这也是小程序云开发服务端和小程序端一个非常大的区别。 新建云函数 鼠标右键 cloudfunctions 云函数根目录,在弹出的窗口选择新建 Node.js 云函数,比如输入 sum,按 Enter 确认后,微信开发者工具会在本地(你的电脑)创建出 sum 云函数目录,同时也会在线上环境中创建出对应的云函数(也就是自动部署好了,可以到云开发控制台云函数列表里看到) 打开 sum 云函数目录下的 index.js,添加 sum:event.a+event.b,到 return 函数里(把多余的内容可以删掉了),然后记得选择云函数增量上传:(更新文件),更新 sum 云函数。 return { sum:event.a+event.b, } 这个 a 和 b 是变量,但是和前面不一样的是,在服务端我们并没有声明 a 和 b 啊,这是因为我们可以在小程序端声明变量。 点击开发者工具模拟器的“快速新建云函数”,会跳转到 addFunction 页面,打开 addFunction.wxml,我们看到测试云函数绑定的是 testFunction 事件处理函数。 <view class="list-item" bindtap="testFunction"> <text>测试云函数</text> </view> 我们去看 addFunction.js 里的 testFunction,看变量 a 和 b 这两个小程序端的变量是怎么和服务端的变量关联起来的,而又是如何把结果渲染到页面的。testFunction 调用云函数 sum 同样是通过 wx.cloud.callFunction,不同的是在 data 里有 a 和 b: data: { a: 1, b: 2 }, data 里填写的是传递给云函数的参数,也就是先把小程序端的参数传递给云函数,然后云函数处理之后再返回 res 对象,我们可以在 success 回调函数里打印 res 对象: console.log("sum云函数返回的对象",res) 编译之后,我们再点击测试云函数,在控制台就能看到打印的结果,res.result.sum 就是 3。直接把 res.result.sum 通过 setData 赋值到 result 就能渲染出数字,那这个 res.result 是什么?JSON.stringify()又是什么? result: JSON.stringify(res.result) 我们可以打印一下 res.result,以及 JSON.stringify(res.result) console.log("res.result是啥", res.result) console.log("JSON.stringify(res.result)是啥", JSON.stringify(res.result)) res.result 是对象,而 JSON.stringify(res.result)是 json 格式, JSON.stringify() 方法是将一个 JavaScript 值(对象或者数组)转换为一个 JSON 字符串,因为对象如果直接渲染到页面是会显示 [object Object]的。 小任务:将小程序的参数传递给云端,有没有一点wx.request的感觉?相当于我们通过云函数写好了一个数据API,然后在小程序端调用。新建一个云函数,把各种数学运算都部署到云端,然后通过传递参数,调用这些算法,并将结果渲染到页面。 体验上传图片 上传图片到云存储 使用模拟器以及手机端点击云开发 QuickStart 小程序的上传图片按钮,选择一张图片并打开,如果在文件存储指引页面显示上传成功和文件的路径以及图片的缩略图,说明你的图片就上传到云开发服务器里啦。 点击云开发控制台的存储图标,就可以进入到存储管理页查看到你之前上传的图片啦,点击该图片名称可以看到这张图片的一些信息,如:文件大小、格式、上传者的 OpenID 以及存储位置、下载地址和 File ID。复制下载地址链接,在浏览器就能查看到这张图片啦。 值得注意的是由于QuickStart小程序将“上传图片”这个按钮上传的所有图片都命名为my-image,所以上传同一格式的图片就会被覆盖掉,也就是无论你上传多少张相同格式的图片,只会在后台里看到最后更新的那张图片。以后我们会教大家怎么修改代码,让图片不会被覆盖。 组件支持 我们可以把下载地址作为图床来使用的,也就是你可以把图片的下载地址放到其他网页图片是可以显示的。云存储的图片还有一个 FileID(既云文件 ID,以 cloud://开头)则只能用于小程序的特定场景,也只有部分组件的部分属性支持,把链接粘贴到浏览器也是打不开的。 技术文档:组件支持 比如我们在 index 页面的 index.wxml 里输入以下代码,在 image 组件的 src 属性里输入你的云存储图片的 FileID,它是可以显示出来的。 <image src="你的图片的FileID"></image> 但是如果你退出登录开发者工具,图片就不会显示,而且还会报错,所以不要把图片的 FileID 当做图床用,FileID 另有它用。 体验云调用之服务端调用 重新点击开发者工具的预览图标,然后用手机扫描二维码,在手机端点击云开发 QuickStart 的云调用里的服务端调用,就可以发送模板消息和获取小程序码。 点击获取小程序码,如果显示调用失败,说明你的 openapi 云函数没有部署成功,需要你先部署成功才行哦。调用成功,就能获取到你的小程序码啦,这个小程序码也会保存到云开发的存储里。 发送模板消息,只能在手机微信里预览测试哦,使用微信开发者工具是发送不了模板消息,而且控制台还会报错 点击发送模板消息,你的微信就会收到一则服务通知,该通知是由你的小程序发出的购买成功通知。这就是微信的模板消息啦,很多微信公众号、小程序都会有这样的功能,使用小程序云开发,我们也可以轻松定制自己的服务通知(后面会教大家如何定制)。 体验前端操作数据库 点击微信开发者工具的云开发图标,打开云开发控制台,点击数据库图标进入到数据库管理页,点击集合名称右侧的+号图标,就可以创建一个数据集合了,这里我们只需要添加一个 counters 的集合(不需添加数据)即可。 在开发者工具的编辑器里展开 miniprogram 文件夹,打开 pages 文件下 databaseGuide 里的 databaseGuide.js 文件,在这里找到 onAdd: function (){}、 onQuery: function (){}、 onCounterInc: function (){}、 onCounterDec: function (){}、 onRemove: function (){}分别选中绿色的代码块,然后同时按快捷键 Ctrl 和/(Mac 电脑的快捷键为 Command 和/),就可以批量取消代码的注释。 //是前端编程语言JavaScript的单行注释,位于 // 这一行的代码都不会执行,我们使用快捷键就是批量取消这些代码的注释,让整段代码生效。之所以显示为绿色,是微信开发者工具为了让我们看得更清晰而做的语法高亮。 前端操作数据库的页面逻辑 以上的函数是在小程序的前端页面来操作数据库,点击开发者工具模拟器云开发 QuickStart 里的前端操作数据库, 在第1步(数据库指引有标注),我们会获取到用户的openid,也就是说你没有获取到openid是没法通过小程序的前端来操作数据库的哦 第2步,需要我们在云开发控制台里的数据库管理页创建一个counters的集合(不需添加数据); 第3步,点击按钮页面的按钮“新增记录”(按钮就在这个页面的第4条与第5条之间,看起来不是那么明显),这时会调用 onAdd方法,往counters集合新增一个记录(之前手动添加有木有很辛苦?),我们可以去云开发控制台的数据库管理页查看一下counters集合是不是有了一条记录;大家可以多点击几下新增记录按钮,然后去云开发控制台看数据库又有什么变化。也就是小程序前端页面通过 onAdd方法,在数据库新增了记录。 第4步,点击按钮查询记录,这时调用的是 onQuery方法就能在小程序里获取到第3步我们存储到数据库里的数据啦 第5步,点击计数器按钮+号和-号,可以更新count的值,点击+号按钮会调用 onCounterInc方法,而点击-号 onCounterDec方法,比如我们点击加号到7,再去数据库管理页查看最新的一条记录(也就是最后一条),它的count由原来的1更新到了7(先点刷新按钮),我们再点击-号按钮到5,再来数据库管理页查看有什么变化变化(先点刷新按钮) 第6步,点击删除记录按钮,会调用 onRemove方法,这时会删掉数据库里最新的记录(也就是第5步里的那一条记录)。 通过实战我们了解到,databaseGuide.js 文件里的 onAdd、 onQuery、 onCounterInc、 onCounterDec、 onRemove 可以实现小程序的前端页面来操作数据库。 这些函数大家可以结合 databaseGuide.js 文件和云开发技术文档关于数据库的内容来理解。(关于前端是如何操作数据库的,我们之后还会深入讲解,这里只需要了解大致的逻辑即可) 在前面JavaScript的章节里我们了解到数据以及数据的存储是非常重要的,而有了数据库,用函数生成的数据能够比缓存存储的更加持久,而且在上面我们实现了对数据进行增(添加)、删(删除)、改(修改、更新)、查(查询并渲染到页面),不仅如此,缓存的容量也比较有限,最多不过10M,而数据库可以存几百G以上,可见它的重要性。 开始一个新的云开发项目 基于云开发 QuickStart 模板小程序 云开发 QuickStart 模板小程序有很多多余的页面,这个我们只需要把 miniprogram 文件夹下的 pages、images、components、style 文件夹里的文件清空,以及 app.json 的 pages 配置项里的页面删除,把 app.wxss 里的样式代码都删掉就是一个全新的开始啦。这是方法之一,也可以使用下面的方法(推荐学习时使用下面的方法)。 基于没有使用云开发的项目改造 当然我们也可以把前面章节没有使用云开发的项目改造成使用云服务,首先在小程序的根目录下新建一个文件夹,比如 cloudfunctions,然后在 project.config.json 添加云函数文件夹的路径配置即可, "cloudfunctionRoot": "cloudfunctions/", 然后新建一个 miniprogram 文件夹,把小程序除了 project.config.json 以外的其他文件,比如 pages、utils、images、app.js、app.json 等文件都放到 miniprogram 文件夹里,再在 project.config.json 添加 miniprogramRoot 配置: "cloudfunctionRoot": "cloudfunctions/", "miniprogramRoot":"miniprogram/", 值得一提的是,云函数部署上传成功,我们就可以一直调用,只要你的小程序的appid以及环境ID没有变,你创建再多的小程序项目,都可以直接调用部署好的云函数,比如前面的login、echo、callback、sum等云函数。也就是说云函数一旦部署成功,它就一直在云端服务器里,哪怕你把小程序本地的云函数都删掉也没有关系。 当新建了并配置了云函数根目录为 cloudfunctions 文件夹之后,云函数根目录里并没有云函数,我们可以右键点击云函数根目录 cloudfunctions 文件夹选择同步云函数列表,可以把所有云端的云函数列表都列举出来(这只是列举了列表),而要修改云函数里面的内容,我们可以右键点击其中的一个云函数目录选择下载云函数即可。 除此之外,我们需要小程序的 app.js 的生命周期函数 onLaunch 里使用 wx.cloud.init()来初始化云开发能力: onLaunch: function () { if (!wx.cloud) { console.error('请使用 2.2.3 或以上的基础库以使用云能力') } else { wx.cloud.init({ env: '你的环境ID', traceUser: true, }) } }, 云开发能力全局只需要初始化一次即可,这里的 traceUser 属性设置为 true,会将用户访问记录到用户管理中,在云开发控制台的运营分析—用户访问里可以看到访问记录。 基础库与 wx.cloud 在小程序端初始化云开发能力的代码里,涉及到 wx.cloud 以及基础库版本的知识。关于 wx.cloud,我们可以和之前在控制台了解 wx 对象一样,直接在开发者工具的控制台里输入: wx.cloud 来了解对象有哪些属性与方法。我们可以看到有如下方法: CloudID: ƒ () //用于云调用获取开放数据 callFunction: ƒ () //调用云函数 database: ƒ () //获取数据库的引用 deleteFile: ƒ () //从云存储空间删除文件 downloadFile: ƒ () //从云存储空间下载文件 getTempFileURL: ƒ () //用云文件 ID 换取真实链接 init: ƒ () //初始化云开发能力 uploadFile: ƒ () //上传文件至云存储空间 而关于基础库,有三个地方需要注意它的存在,平时开发的时候需要留意开发者工具的project.config.json里有这样一个属性libVersion,这个也可以在开发者工具工具栏右上角的详情里的本地设置里的调试基础库,建议切换到最新,切换后libVersion的值也会修改到切换的版本; 官方文档基础库的更新日志,小程序更新非常频繁,而更新的核心就是基础库:所以基础库更新日志要经常留意每个API,技术文档都会标明它的基础库支持的最低版本,而小程序·云开发 SDK是2.2.3以上的基础库才开始支持的。
2021-09-10 - 为什么在IOS环境下request请求一直处于Pending状态?
小程序request请求数据,在安卓真机设备下一切正常,但是换到IOS真机设备中,所有的请求都是一直处于pending状态,并不返回canceled或fail。 域名已经备案,安装了阿里云提供的免费证书。 小程序的合法request域名已经设置。 BUG复现环境: IPhone7,IOS13.1.2,WeChat7.0.8。 而且并不是一直这样,之前并没有问题,过了几天同事使用时发现所有请求都不正常了。 [图片] [图片]
2019-10-12 - onShareAppMessage 和 onShareTimeline 返回对象是一样的吗?
onShareAppMessage 是分享给好友,onShareTimeline 是分享到朋友圈。 https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareAppMessage-Object-object https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareTimeline 如果 path 需要携带参数,二者的写法是不是不一样? 比如: // 分享给好友 onShareAppMessage(){ return { path: '/pages/index/index?name=123' }; }, // 分享到朋友圈 onShareTimeline(){ return { path: '/pages/index/index', query: 'name=123' }; } 官方文档说的含糊其词,也没找到示例!
2021-12-05 - 微信小程序分享朋友圈功能,为什么只能开发者自己分享?别人打开小程序后不能再分享吗?
如上题,谢谢各位。 例如:我做了一个微信小程序,我分享到我自己朋友圈没有问题。但是当别人打开我的小程序,想分享到他的朋友圈的时候,分享不了。 请问是根本没有办法,还是需要增加代码?谢谢
2022-03-28 - 微信小程序转发朋友圈详解
概述点击右上角分享朋友圈[图片] 分享到朋友圈样式[图片] 朋友圈打开样式[图片] 这个功能目前只支持Android(在IOS高版本微信支持朋友圈打开小程序能力,但不能分享)。 用户打开朋友圈分享的小程序,看到不是真正的小程序,而是原本页面的“单页模式”。 什么是“单页模式”?以下是微信官方对于“单页模式”的描述: “单页模式”下,页面顶部固定有导航栏,标题显示为当前页面 JSON 配置的标题。底部固定有操作栏,点击操作栏的“前往小程序”可打开小程序的当前页面。顶部导航栏与底部操作栏均不支持自定义样式。“单页模式”默认运行的是小程序页面内容,但由于页面固定有顶部导航栏与底部操作栏,很可能会影响小程序页面的布局。因此,请开发者特别注意适配“单页模式”的页面交互,以实现流畅完整的交互体验。限制另外,“单页模式”存在着很多限制。以下是官方给出的禁用能力列表: [图片] 限制主要包括以下几点: 页面无登录态,与登录相关的接口,如 [代码]wx.login[代码] 均不可用不允许跳转到其它页面,包括任何跳小程序页面、跳其它小程序、跳微信原生页面若页面包含 tabBar,tabBar 不会渲染,包括自定义 tabBar本地存储与小程序普通模式不共用这些限制,让“单页模式”只适用于内容展示,不适用于有较多交互。 配置针对“单页模式”,新增了单页模式相关配置。目前这个配置里只有一个navigationBarFit属性: [图片] navigationBarFit属性主要是针对原页面设置了自定义导航栏的情况。也就是原页面的json文件中配置了这个属性: { // ... "navigationStyle":"custom" // ... } 给大家看一下普通导航栏和自定义导航栏的区别,下图是普通导航栏页面: [图片] 下图是自定义导航栏页面,我们在原本的导航栏位置使用了banner: [图片] [代码]"navigationStyle":"custom"[代码]这个设置在“单页模式”下也会生效。前文微信官方对“单页模式”的描述有说到“顶部导航栏与底部操作栏均不支持自定义样式”。如果我们在原页面设置了自定义导航栏。那么“单页模式”样式就会变成这样: [图片] 通过设置navigationBarFit为 [代码]squeezed[代码]就可以解决这个问题: { // ... "singlePage": { "navigationBarFit": "squeezed" } // ... } 设置后的样式: [图片] 开发 接下来介绍如何在小程序中实现这个功能。 第一步在需要转发朋友圈的页面中注册用户点击右上角转发功能,这是实现转发朋友圈功能的必要满足条件。 onShareAppMessage: function () { return { title: '转发标题', path: '/pages/home/index', imageUrl: '自定义图片路径' } } 第二步注册分享朋友圈功能(从基础库 [代码]2.11.3[代码] 开始支持): onShareTimeline: function () { return { title: '转发标题', query: 'from=pyq', imageUrl: '自定义图片路径' } } 注意,这里有个问题,分享朋友圈功能不支持自定义页面路径,意味着只能转发当前页面。如果当前页面存在较多“单页模式”限制功能,就可能让我们的页面不能按预期展示。 当页面存在限制功能时,我们存在两个方案,第一个方案,针对“单页模式”做改动,不调用那些限制的功能。第二个方案,另外写一个针对“单页模式”的页面。 这两种方案都需要能判断当前是否正处在小程序“单页模式”。 我们通过判断场景值(场景值用来描述用户进入小程序的路径)是否等于 1154 来判断当前是否正处在小程序“单页模式”。场景值可以在 [代码]App[代码] 的 [代码]onLaunch[代码] 获取。 // app.js App({ // ... onLaunch(options) { const { scene } = options; this.isSinglePage = scene === 1154; } // ... }) 我们将是否正处在“单页模式”的Boolean值放入App实例,方便全局拿到值。 接下来说说两种方案。 第一种方案,在“单页模式”不调用那些限制功能(这是一种不推荐的方案,代码耦合性太强)。举个例子: const app = getApp(); Page({ // ... onLoad() { if (!app.isSinglePage) { wx.login({ // ... }) } } // ... }) 第二种方案,针对“单页模式”另写一个页面。因为分享朋友圈功能并不支持自定义页面路径,我们只能另外写一个组件来作为“单页模式”的内容承载。 将isSinglePage放入页面的初始数据,方便在wxml中拿到: // pages/home/index.js const app = getApp(); Page({ data: { isSinglePage: app.isSinglePage, } // ... }) home-single-page就是分享到朋友圈的内容承载组件: // pages/home/index.json { // ... "usingComponents": { "home-single-page": "components/home-single-page/index" }, } 当“单页模式”时,我们展示 [代码]home-single-page[代码]组件,否则就展示普通页面内容: // pages/home/index.wxml 样式上虽然搞定了,但是在原本的生命周期中可能会调用一些限制功能,或者跑一些其它“单页模式”用不上的内容。我们得停止原本生命周期函数调用。 建议对传入Page的对象进行统一处理,当“单页模式”时,不调用原本的生命周期: // pages/home/index.js import ExtendPage from 'common/extend-page/index' const app = getApp(); ExtendPage({ data: { isSinglePage: app.isSinglePage, } // ... }) ExtendPage函数针对“单页模式”进行统一处理: // common/extend-page/index.js const app = getApp(); const PAGE_LIFE = [ 'onLoad', 'onReady', 'onShow', 'onHide', 'onError', 'onUnload', 'onResize', 'onPullDownRefresh', 'onReachBottom', 'onPageScroll' ]; export default function(option) { let newOption = {}; if(app.isSinglePage) { newOption = PAGE_LIFE.reduce((res, lifeKey) => { if (option[lifeKey]) { res[lifeKey] = undefined; } return res; }, {}) } return Page({ ...option, ...newOption, }); } 在“单页模式”下,我们将原本的生命周期都停止了调用。这样就能很好的将“单页模式”下的页面和普通页面进行解耦。 如果”单页模式“页面比较复杂,需要使用生命周期。我们也可以添加 [代码]singlePageLife[代码]属性,当处在“单页模式”下,就调用 [代码]singlePageLife[代码]内的生命周期: // pages/home/index.js import ExtendPage from 'common/extend-page/index' const app = getApp(); ExtendPage({ data: { isSinglePage: app.isSinglePage, }, singlePageLife: { onLoad() { // ... }, } // ... }) // common/extend-page/index.js const app = getApp(); const PAGE_LIFE = [ 'onLoad', 'onReady', 'onShow', 'onHide', 'onError', 'onUnload', 'onResize', 'onPullDownRefresh', 'onReachBottom', 'onPageScroll' ]; export default function(option) { let newOption = {}; if(app.isSinglePage) { const { singlePageLife } = option; newOption = PAGE_LIFE.reduce((res, lifeKey) => { if (singlePageLife[lifeKey]) { res[lifeKey] = singlePageLife[lifeKey]; } else if(option[lifeKey]) { res[lifeKey] = undefined; } return res; }, {}) } return Page({ ...option, ...newOption, }); } 文章如有疏漏、错误欢迎批评指正。
2020-10-21 - 微信JSSDK弹框显示config:invalid signature,realAuthURL?
错误如图: [图片] 场景描述: h5页面中引入微信JSSDK使用分享朋友圈和分享朋友功能。弹框提示上述错误,请问问题出在什么地方? 使用微信JSSDK版本号:jweixin-1.6.0.js 按照https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#1附录5验证排除错误。 1、微信js接口签名校验工具结果: [图片] 认证接口返回结果signature一致。 [图片] 2、检查wx.config配置: [图片] 根据上图接口返回结果,不存在不一致情况; 3、微信工作平台配置JS接口安全域名 [图片]
2022-03-02 - H5页面分享不显示自定义标题和图片?
原因是H5用旧的方式申请JSAPI分享权限,后台返回无权限,因此分享的时候不能自定义,建议开发者接入新的分享方式:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html ,使用新的wx.updateAppMessageShareData和wx.updateTimelineShareData接口来设置分享数据。
2020-04-23 - 报错Unknown custom element: <wx-open-launch-weapp>?
在uniapp中使用h5跳转小程序,组件引用报错,说没有注册组件,我都jssdk都可以使用,有没有官方的小哥哥小姐姐解答一下????
2020-08-11 - h5页面打开app,微信开放标签的使用教程。
<wx-open-launch-app id=“launch-btn-2” appid=“您的appid”> <template> <style>.btn { padding: 12px }</style> <button class=“btn”>App内查看</button> </template> </wx-open-launch-app> [代码]<script> let url = window.location.href; if(url.indexOf("#")>0){ url = url.split('#')[0]; } $.ajax({ method: "get", url: '获取tocken等url,是后台人员提供的', data: { }, contentType: false, // 告诉jQuery不要去设置Content-Type请求头 processData: false, // 告诉jQuery不要去处理发送的数据 }) .done(function( res ) { console.log(res); if(res.code==1){ var res_data = res.data; console.log(res_data); wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: res_data.appId, // 必填,公众号的唯一标识 timestamp: res_data.timestamp, // 必填,生成签名的时间戳 nonceStr: res_data.nonceStr, // 必填,生成签名的随机串 signature: res_data.signature,// 必填,签名 jsApiList: [ "menuItem:share:facebook" ], // 必填,需要使用的JS接口列表 openTagList: ['wx-open-launch-app'] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app'] }); }else{ // _this.$toast("请用在微信中打开"); alert(res+"123"); } }); wx.ready(function () { wx.checkJsApi({ jsApiList: ['wx-open-launch-app'], // 需要检测的JS接口列表,所有JS接口列表见附录2, success: function (res) { console.log('可用') }, fail: (err) => { console.log(err, '不可用') } }); var btn = document.getElementById('launch-btn-2'); btn.addEventListener('ready', function (e) { console.log('ready'); }); //点击立即使用按钮 btn.addEventListener('launch', (e)=> { console.log('launch'); }); btn.addEventListener('error', function (e) { console.log('error'); }); // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中 }); //如果是vue,上面的标签部分,则可以用这个: <wx-open-launch-app id="launch-btn" appid="您的appid"> <script type="text/wxtag-template"> <style> .bottom-btn{ -webkit-user-select:none; font-weight:bold; } .bottom-btn:link,.bottom-btn:visited{color:#fff;} .bottom-btn:active{color:#fff; background:linear-gradient(90deg,rgba(255,82,59,1) 0%,rgba(255,176,69,1) 100%);} </style> <a class="bottom-btn">立即使用</a> </script> </wx-open-launch-app> 如果有问题,可联系我:13241108634,加微信即可。[代码]
2021-03-01 - H5如何跳转微信小程序?
之前遇到一个需求,就是要从H5跳转到小程序里,但是微信之前一直没有提供接口做跳转,我们只能做降级方案,在要跳转小程序的地方做了一个弹窗,弹窗里面放小程序码,引导用户长按识别小程序码,然后跳转到小程序内,整个流程非常之长,转化率可想而知也是很低的。 今天刚好看到有人技术群里面问了这个问题,于是我就去看了下微信的文档,发现微信偷偷的更新的这个接口,可以让微信浏览器下的H5跳转到小程序内。 相关文档在这边: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html 用的是JS-SDK的接口,需要使用到js-sdk-1.6.0的版本才有支持,https://res.wx.qq.com/open/js/jweixin-1.6.0.js wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: [], // 必填,需要使用的JS接口列表 openTagList: [] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app'] }); 在wx.config下面多了一项openTagList,开放标签列表,目前支持配置wx-open-launch-weapp,wx-open-launch-app wx-open-launch-weapp 指H5跳转小程序 wx-open-launch-app 指H5跳转app 我们主要介绍的是wx-open-launch-weapp H5跳转小程序 先上才艺: [图片][图片][图片] html代码如下: var btn = document.getElementById('launch-btn'); btn.addEventListener('launch', function (e) { console.log('success'); }); btn.addEventListener('error', function (e) { console.log('fail', e.detail); }); username为小程序的原始id,path对应的是小程序的链接地址。之前有写过微信H5的应该会知道怎么把这段代码嵌入到之前的代码里面。 目前此功能仅开放给已认证的服务号,网页的域名要在服务号的“JS接口安全域名”下。 亲测<wx-open-launch-weapp>可以跳转到任意合法合规的小程序,是任意的小程序都能跳转!!!!这个接口真开放(不怕人干坏事?) PS: 有个坑,官方文件说的path是/a/b/c?d=1&e=2#fg,类似的这样的链接格式,但是我自己亲测如果直接使用/a/b/c?d=1&e=2#fg这样格式的链接会报页面不存在,然后我想到了小程序那边复制链接的时候会在链接后面加上.html,于是挖槽的事情发生了,把path链接格式换成/a/b/c.html?d=1&e=2#fg这样就能正常访问,不知道是微信故意这样设计的还是bug,有待考证。 然后这个接口真的可以干好多坏事,希望大家能用正确的价值观来正确使用此接口。 微信开放标签有最低的微信版本要求,以及最低的系统版本要求。 如果开发过程中出现以下情况的,要确认一下,微信版本要求为:7.0.12及以上。 系统版本要求为:iOS 10.3及以上、Android 5.0及以上。 [图片]
2020-07-09 - canvas绘制出现空白问题?
在进行小程序提审时,验证体验版是ok的,可正常打开首页展示条形码信息,发现在公开小程序后,条码出现如图空白现象,现象持续了许久,后续进行回退版本操作,发现还是有此问题,10多分钟后,发现此现象没有再次发生,此现象出现在iOS手机上。不知是否有什么发布或升级操作? [图片]
2020-11-05 - [填坑手册]小程序Canvas生成海报(一)--完整流程
[图片] 海报生成示例 最近智酷君在做[小程序]canvas生成海报的项目中遇到一些棘手的问题,在网上查阅了各种资料,也踩扁了各种坑,智酷君希望把这些“填坑”经验整理一下分享出来,避免后来的兄弟重复“掉坑”。 [图片] 原型图 这是一个大致的原型图,下面来看下如何制作这个海报,以及整体的思路。 [图片] 海报生成流程 [代码片段]Canvas生成海报实战demo demo的微信路径:https://developers.weixin.qq.com/s/Q74OU3m57c9x demo的ID:Q74OU3m57c9x 如果你装了IDE工具,可以直接访问上面的demo路径 通过代码片段将demo的ID输入进去也可添加: [图片] [图片] 下面分享下主要的代码内容和“填坑现场”: 一、添加字体 https://developers.weixin.qq.com/miniprogram/dev/api/canvas/font.html [代码]canvasContext.font = value //示例 ctx.font = `normal bold 20px sans-serif`//设置字体大小,默认10 ctx.setTextAlign('left'); ctx.setTextBaseline("top"); ctx.fillText("《智酷方程式》专注研究和分享前端技术", 50, 15, 250)//绘制文本 [代码] 符合 CSS font 语法的 DOMString 字符串,至少需要提供字体大小和字体族名。默认值为 10px sans-serif 文字过长在canvas下换行问题处理(最多两行,超过“…”代替) [代码]ctx.setTextAlign('left'); ctx.setFillStyle('#000');//文字颜色:默认黑色 ctx.font = `normal bold 18px sans-serif`//设置字体大小,默认10 let canvasTitleArray = canvasTitle.split(""); let firstTitle = ""; //第一行字 let secondTitle = ""; //第二行字 for (let i = 0; i < canvasTitleArray.length; i++) { let element = canvasTitleArray[i]; let firstWidth = ctx.measureText(firstTitle).width; //console.log(ctx.measureText(firstTitle).width); if (firstWidth > 260) { let secondWidth = ctx.measureText(secondTitle).width; //第二行字数超过,变为... if (secondWidth > 260) { secondTitle += "..."; break; } else { secondTitle += element; } } else { firstTitle += element; } } //第一行文字 ctx.fillText(firstTitle, 20, 278, 280)//绘制文本 //第二行问题 if (secondTitle) { ctx.fillText(secondTitle, 20, 300, 280)//绘制文本 } [代码] 通过 ctx.measureText 这个方法可以判断文字的宽度,然后进行切割。 (一行字允许宽度为280时,判断需要写小点,比如260) 二、获取临时地址并设置图片 [代码]let mainImg = "https://demo.com/url.jpg"; wx.getImageInfo({ src: mainImg,//服务器返回的图片地址 success: function (res) { //处理图片纵横比例过大或者过小的问题!!! let h = res.height; let w = res.width; let setHeight = 280, //默认源图截取的区域 setWidth = 220; //默认源图截取的区域 if (w / h > 1.5) { setHeight = h; setWidth = parseInt(280 / 220 * h); } else if (w / h < 1) { setWidth = w; setHeight = parseInt(220 / 280 * w); } else { setHeight = h; setWidth = w; }; console.log(setWidth, setHeight) ctx.drawImage(res.path, 0, 0, setWidth, setHeight, 20, 50, 280, 220); ctx.draw(true); }, fail: function (res) { //失败回调 } }); [代码] 在开发过程中如果封面图无法按照约定的比例(280x220)给到: 那么我们就需要处理默认封面图过大或者过小的问题,大致思路是:代码中通过比较纵横比(280/220=1.27)正比例放大或者缩小原图,然后从左上切割,竟可能保证过高的图是宽度100%,过宽的图是高度100%。 在canvas中draw图片,必须是一个(相对)本地路径,我们可以通过将图片保存在本地后生成的临时路径。 微信官方提供两个API: wx.downloadFile(OBJECT)和wx.getImageInfo(OBJECT)。都需先配置download域名才能生效。 三、裁切“圆形”头像画图 [代码]ctx.save(); //保存画图板 ctx.beginPath()//开始创建一个路径 ctx.arc(35, 25, 15, 0, 2 * Math.PI, false)//画一个圆形裁剪区域 ctx.clip()//裁剪 ctx.closePath(); ctx.drawImage(headImageLocal, 20, 10, 30, 30); ctx.draw(true); ctx.restore()//恢复之前保存的绘图上下文 [代码] 使用图形上下文的不带参数的clip()方法来实现Canvas的图像裁剪功能。该方法使用路径来对Canvas话不设置一个裁剪区域。因此,必须先创建好路径。创建完整后,调用clip()方法来设置裁剪区域。 需要注意的是裁剪是对画布进行的,裁切后的画布不能恢复到原来的大小,也就是说画布是越切越小的,要想保证最后仍然能在canvas最初定义的大小下绘图需要注意save()和restore()。画布是先裁切完了再进行绘图。并不一定非要是图片,路径也可以放进去~ 小程序 canvas 裁切BUG [代码]ctx.setFillStyle("#fff"); ctx.fillRect(0, 0, 320, 500); //第一个填充矩形 wx.downloadFile({ url: headUri, success(res) { ctx.beginPath() ctx.arc(50, 50, 25, 0, 2 * Math.PI) ctx.clip() ctx.drawImage(res.tempFilePath, 25, 25); //第二个填充图片 ctx.draw() ctx.restore() ctx.setFillStyle("#fff"); ctx.fillRect(0, 0, 320, 500); ctx.draw(true) ctx.restore() } }) [代码] clip裁切这个功能,如果有超过一张图片/背景叠加,则裁切效果失效。 错误参考:http://html51.com/info-38753-1/ 四、将canvas导出成虚拟地址 [代码]wx.canvasToTempFilePath({ fileType: 'jpg', canvasId: 'customCanvas', success: (res) => { console.log(res.tempFilePath) //为canvas的虚拟地址 } }) res: { errMsg: "canvasToTempFilePath:ok", tempFilePath: "http://tmp/wx02935bb29080a7b4.o6zAJswFAuZuKQ5NZfPr….cGnD1a02PlVC0b3284be3a41d08986c2477579a5fd8e.jpg" } [代码] 这里需要把canvas里面的内容,导出成一个临时地址才能保存在相册,比如: http://tmp/wx02935bb29080a7b4.o6zAJswFAuZuKQ5NZfPr5UfJVR4k.cGnD1a02PlVC0b3284be3a41d08986c2477579a5fd8e.jpg 五、询问并获取访问手机本地相册权限 [代码]wx.getSetting({ success(res) { console.log(res) if (!res.authSetting['scope.writePhotosAlbum']) { //判断权限 wx.authorize({ //获取权限 scope: 'scope.writePhotosAlbum', success() { console.log('授权成功') //转化路径 self.saveImg(); } }) } else { self.saveImg(); } } }) [代码] 判断是否有访问相册的权限,如果没有,则请求权限。 六、保存到用户手机本地相册 [代码]wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: function (data) { wx.showToast({ title: '保存到系统相册成功', icon: 'success', duration: 2000 }) }, fail: function (err) { console.log(err); if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") { console.log("当初用户拒绝,再次发起授权") wx.openSetting({ success(settingdata) { console.log(settingdata) if (settingdata.authSetting['scope.writePhotosAlbum']) { console.log('获取权限成功,给出再次点击图片保存到相册的提示。') } else { console.log('获取权限失败,给出不给权限就无法正常使用的提示') } } }) } else { wx.showToast({ title: '保存失败', icon: 'none' }); } }, complete(res) { console.log(res); } }) [代码] 保存到本地需要一定的时间,需要加一个loading的状态。 七、关于组件中引用canvas [代码]let ctx = wx.createCanvasContext('posterCanvas',this); //需要加this [代码] 在components中canvas无法选中的问题: 在components自定义组件下,当前组件实例的this,表示在这个自定义组件下查找拥有 canvas-id 的 <canvas> ,如果省略则不在任何自定义组件内查找。
2021-09-13 - ctx.draw(true,function(){}) 回调未执行,安卓机不支持回调?
ctx.draw(false, () => { 可进入 }) ctx.draw(true, () => { 未进入 }) 安卓机(如: vivo x27 微信版本最新版本),当reserve为true时,未进入回调函数内,这个问题官方的解决方式是?
2020-01-08 - ctx.draw()
- 当前 Bug 的表现(可附上截图) [图片] 但是像下面这种写的话线上版本就会报错,出现率特别高 canvasToTempFilePath :fail no image[图片] - 预期表现 - 复现路径 - 提供一个最简复现 Demo
2019-07-12 - 小程序上传和下载的方法,能用于处理zip压缩包吗?
目前有个需求想通过小程序,用户可以上传一个压缩包,其他用户可以下载别人上传的压缩包。请问上传接口触发后,用户如何选择自己要上传的文件。是调用手机的文件目录还是微信自带的,能否解释一下。同时用户下载了压缩包,文件存储在哪个位置,用户能如何转发给其他人? 官方大佬们求助下!!!!
2019-11-21 - H5跳转微信小程序成功案例
本人使用的VUE框架。 代码提示: 1、vue代码; 2、点击事件代码; 3、php代码; 遇到的大坑重要提示: 3、必须是认证服务号; 4、必须是服务号绑定的微信小程序 5、https接口获取服务号的access_token 6、如果你的https接口没有问题,但是你的wx-open-launch-weapp标签没有显示或者点击无反应。有以下原因: 1》、vue代码样式问题,可以根据我的代码写样式,最好写成一样的。 2》、在微信开发者工具没有反应的话,最好在微信客户端试试。 3》、JSSDK版本是1.6.0。 4》、如果框架写上还不行,可以试试在文件main.js中,写上: Vue.config.ignoredElements = [‘wx-open-launch-app’, ‘wx-open-launch-weapp’]; 新增项: 5》、在小程序后台配置上业务域名,域名必须有证书。代码放到服务器上,用业务域名访问。 官方链接参考: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html 还是不行的话,下方留言或者私信我。 1、<template> <div class=“cnt”> <div> <button @click=“onClickOpens”>新开页面跳转</button> </div> <div class=“test-position”> <wx-open-launch-weapp id="launch-btn" username="gh_xxxxxxxxxx" path=“pages/index/index.html?user=123&action=abc” > <script type=“text/wxtag-template”> <style>.btn {width: 200px; height: 100px;}</style> <button class=“btn”>打开测试小程序</button> </script> </wx-open-launch-weapp> </div> </div> </template> 2、 onClickOpens() { this.$axios({ method: “POST”, url: “https://接口”, data: { url: window.location.href, }, }).then(function (res) { console.log(res); if (res.status == 200) { console.log(res.data.appid); wx.config({ debug: true, appId: res.data.appid, timestamp: res.data.timestamp, nonceStr: res.data.nonce_str, signature: res.data.sign, jsApiList: [“scanQRCode”], openTagList: [“wx-open-launch-weapp”], // 可选,需要使用的开放标签列表,例如[‘wx-open-launch-weapp’] }); wx.error(function (res) { console.log(res); // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 }); } }); }, 3、 [图片]
2022-12-25 - 微信公众号H5页面缓存无法更新?
vue项目编译部署之后,部分手机无法更新到最新的版本,访问的还是之前的版本,试过多种方法都无法清除缓存,请问要怎样才能清除缓存呢
2021-03-05 - 如何清除公众号H5页面缓存?
最近发现公众号H5页面缓存特别严重,该怎么处理
2019-10-11 - 微信里打开h5页面,经常无缘无故白屏,请问是什么原因,微信是否对链接有限制
最近在做的h5页面,只要用户一访问多了,就容易出现无缘无故的白屏问题,苹果经过重启手机,安卓退出登录,又可以正常打开,问一下微信是否有对链接做访问限制,访问多了就做屏蔽,然后本地缓存呢?
2017-08-30 - 微信公众号的域名重新解析后,公众号跳转的网页缓存无法清除的问题?
背景:域名进行一一次新的解析,解析后,新关注的用户可以正常的使用公众号功能,原来已经关注的用户,访问仍然是重新解析之前的地址https://mp.weixin.qq.com/s/c4HPSJMm8dTYhjozgeUpdQ?poprequest=1&dm=shyfybjy.cn&acc=c6cbb05b-e8b1-8662-a12a-18244e0e6f89 [图片] 已经试过的办法: 清除微信设置中--》通用--》清除缓存手机应用管理--》清除应用缓存重启手机退出重新登录取消关注,重新关注公众号直接访问公众号菜单的连接未使用: http://debugx5.qq.com/ x5调试工具,不适用原因,微信公众号的用户为普通的用户,不太会使用,再者在x5的调试工具中点击渲染的显示信息面板后,会造成整个微信所有的链接打不开,整个webview崩溃,未找到解决办法[图片] 怀疑是:微信内置浏览器的DNS缓存的问题 但是用以上已经用过的这些方式无法清除掉,大家有好的办法没,(公众号的用户使用的场景是普通人)?
2021-05-07 - 求求搞搞安卓端微信网页清除不了缓存的问题吧找了一天问题卸载微信重装才解决这怎么玩?
发现在微信网页的路径里最后面存在“ :: ” 会提示下载QQ浏览器的问题 后来找到了问题但是依旧有部分原先测试的安卓手机依旧下载QQ浏览器 经过加班不断测试依旧找不到问题,然后因为新加了一些东西发现安卓死活也出不来才明白不是兼容的问题是安卓部分手机清不掉缓存,然后我们把微信卸载了重新安装才显示了最新代码 真的是炸了(^o^)
2021-05-31 - 微信 打开H5 vue 出现白屏
线上版本更新 不管是ios 或者是安卓 会有部分手机 打开页面 白屏 微信重登就可以显示,有时重登也是白屏 而且部分手机首次白屏,手动刷新后,就可以显示 我想问下是微信浏览器的有时候打开没面 不刷新页面 还是 其他的问题
2019-05-01 - 微信h5 vue 部分手机白屏?
我们是使用vue单页面开发的,之前也有过这样的问题,最近我们提交更新了版本之后,有部分之前可以使用的用户现在打开我们的公众号出现白屏现象。有试过es6转es5,有试过静态页面不缓存,但是都不行
2020-09-27 - 华为Mate20、华为P40点击H5开发页面,无法授权登录一直白屏
华为Mate20、系统EMUI11.0.0、微信版本8.0.1 华为P20、系统EMUI10.1.0、微信版本7.0.22 这两个机型在打开H5后一直跳转不了进入程序,展示白屏。后台数据授权均判断为成功的状态。更换其他手机或设备,使用同一个微信可以正常登录。 [图片]
2021-03-03 - webview跳转小程序的另一种实现
起因 因为公司业务原因,小程序嵌套了大量的h5页面供; 但涉及到支付类的操作必须在小程序原生页面完成; 这就牵扯了webview跳转原生小程序问题; 我们在线上经常遇到用户投诉;在webview页面点去支付没有反应; 代码逻辑上,这个按钮点击应该跳转原生页面才对的; 我们也在相关页面添加了日志,显示已经触发jssdk成功跳转回掉 但是并没有跳转成功 就在前几天我们又接到用户关于跳转失败投诉; 这种收到反馈,搜集微信日志,联系官方的操作过于被动; 每次都要被公司质量管控部门吐槽,有苦难言; 社区也有不少开发者反馈相关问题;但是偶现bug,官方也不易排查 所以除了等待官方解决我们就没有别的办法了么? 突破 就在我辗转反侧,彻夜难眠的时候,官方文档的一句话吸引了我 [图片] 每次网页加载都能触发bindload事件获取到url 那么我们能不能指定一个url,获取url上的指定的参数,利用小程序原生能力进行跳转呢 实现 wxml 页面添加bindload事件监听 [代码]<web-view src="{{url}}" bindload="load"></web-view> [代码] js 监听url中的变化,检测到指定值执行跳转逻辑 [代码]load: function (e) { // 获取url const src = e.detail.src; const query = src.split('?')[1] || ''; // 检测url参数中是否有指定的参数 const isJump = query.indexOf('word=jump'); // 检测到指定值执行跳转逻辑 if(isJump >= 0){ wx.navigateTo({ url: '/index/index' }) } } [代码] demo 这里写了一个简单的demo https://developers.weixin.qq.com/s/HCPpEzmU7DkV 嵌入了触屏的baidu 当监听到搜索关键词为jump时,会执行原生的跳转 [图片] 兼容性的问题 因为公司小程序基础库是2.9.2,大于等于这个版本的可靠性是经过我们线上验证的 低于2.9.2的基础库版本有待考证,可能需要使用者自测 这里给大家提供一种思路,可以结合场景使用 安卓微信8.0.1,出现webview bindload没有执行的情况,这个api在新版本微信上可能有兼容性问题(20210322)
2021-08-13 - 部分手机打开webView空白?
客户反映部分手机打开同域名的h5,部分webview的页面空白,部分是可以了,然后过了两三天突然都能打开了,打不开的h5在浏览器中直接访问是没任何问题的,是微信最近做了什么操作吗
2021-04-25 - 偶现webview页面显示空白,怎么解决?
1、webview是偶现的现象,发生率比较低,ios、安卓都会出现 2、webview嵌入的url地址没有问题。在浏览器中可以正常打开 3、体验版环境打开调试模式,bindload 会正常回调 4、清除微信缓存后,可以正常打开
2021-09-02 - 如何解决<web-view >标签每次更新内容会出现空白页面现象?
因项目需要在企业版小程序中,仅加<web-view src='https://XXXXX.com'></web-view>进行跳转到H5页面。且服务域名已配置,每次投产上线后(H5)都会出现小程序进入后空白现象。链接没有改变只改变了H5的内容。请问如何解决?这次已空白了两天。新客户可以正常访问,老客户则不可以。
2021-03-19 - webview页面总是空白!?
webview页面总是空白!!! [图片] <web-view src="http://www.baidu.com"></web-view>
2019-11-22 - web-view 页面显示空白
webview地址如图,浏览器里可以正常打开,也在后台配置了。但是小程序里显示空白,之前还是好的,也没发版本,突然不行了。求解答。 [图片]
2021-03-01 - [填坑手册]小程序web-view组件实战与踩坑
[图片] 首先,根据官网文档可以知道 只有非个人 的小程序才可以使用web-view组件,如果你的个人开发者,可以跳过这篇文章。 [图片] 一、使用web-view以及它的好处 1、己方账号(第三方)与小程序openId/UnionId的关联绑定,实现免登陆 比如你是某门户网站S,你要识别自己小程序上的用户与网站用户的关系,你可以通过三种方法绑定关系,公众号,小程序源生,小程序web-view内嵌跳转三种方法 2、内嵌H5的富文本,减少重复开发 比如你是门户网站,社区,以往有大量的新闻和帖子,里面带了各种css样式的富文本,小程序源生是无法直接读取的,需要大量转化,这时候直接内嵌这些H5新闻,大大降低开发成本 3、热更新,减少发布审核 某些需要经常更新的内容、公告、活动页,内嵌H5可以减少频繁提交小程序审核 二、小程序功能赋权 为H5提供各种小程序才有的功能,比如录音,扫一扫等。 注意事项 多场景判断,建议使用官方API: wx.miniProgram.getEnv H5唤醒一些小程序API有一定的延时,0.3~1秒 请调用小程序专用的JSSDK,同一个jssdk,但是webview的功能收到限制,和之前微信打开H5有所不同 小程序自动获取加载H5的title H5中iframe的url必须也是业务域名 web-view一定是撑满全屏的,自定义顶部菜单,悬浮的都没用 三、小程序和H5之前的互相通讯 1、 从小程序 ==>> h5 小程序控制H5,可以直接用src路径传参的形式,比如 [代码]<!-- 小程序端 HTML --> <web-view src="//URL?a=param1&b=param2"></web-view> [代码] 避免在链接中带有中文字符,在 iOS 中会有打开白屏的问题,建议加一下 encodeURIComponent。 2、 从 H5 ==>> 小程序 [图片] 这里我们知道bindmessage是小程序用来监听H5的推送的内容,但是这里不大不小的坑!就是它的三个出发场景: 小程序后退:使用接口名 wx.miniProgram.navigateTo,wx.miniProgram.navigateBack,wx.miniProgram.switchTab 等切换小程序页面/场景的API时候都会出发 分享:这个就是当你点分享小程序的时候,会接受到H5之前发送的postMessage 组件销毁,web-view组件销毁,类似 wx.miniProgram.redirectTo 都会触发。 [代码]<!-- 小程序端 HTML --> <web-view bindmessage="handleGetMessage" src="{{openUrl}}"></web-view> [代码] [代码]// 小程序端 JS --> Page({ /** * 页面的初始数据 */ data: { openUrl: "", }, /** * 获取请求数据 */ handleGetMessage: function (e) { console.log(e.detail.data); } }, }) [代码] [代码]<!-- h5端 HTML和JS --> <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> <script> wx.miniProgram.postMessage({ data: { link: "//test.com", title: "一起学习,一起进步" } }); //wx.miniProgram.redirectTo({ // url:"/pages/inner/index?source=123" //}) wx.miniProgram.navigateBack({delta: 1}) </script> [代码] 注意事项 那些H5控制小程序的跳转路径必须是“/”开头,如 “/pages/xxx/xxx”,且路径必须在app.json里有,地址错误的话,有时不报错。 postMessage的json必须是data开始,不然接收不到数据。 [图片] 四、bindmessage接收到消息有3个重要特性(重点) 接收可以是H5之前几分钟前发送postMessage,不一定是即刻发出的。 之前发出的 postMessage的DATA信息会累加,当触发bindmessage接收的时候是一个数组。 [图片] 当bindmessage 再次 接收到数据,之前发送的数据不会被清空,将累加一起返回,获取时要判断好数组的角标 [图片] 五、Tips 1、在IDE工具中如何调试H5 [图片] 可以在 web-view 组件上通过右键 - 调试,打开 web-view 组件的调试。 2、内嵌H5缓存问题 web-view加载的H5具有很重的缓存,如果需要调试,可以通过在url后面加时间戳的方式解决。 3、小程序关闭,H5背景音乐仍然在播放问题 小程序已经关闭,但是H5自带的背景音乐仍然在手机后台播放的问题。这里可以利用一个属性: visibilitychange:页面可见性状态 简单的说,浏览器标签页被隐藏或显示的时候会触发visibilitychange事件。 [代码]var statusBeforeHide = true; //初始化页面的状态 var music = document.getElementById("xxx"); // 更改音乐播放状态 function setChangeMusic() { if (document[hiddenProperty]) { // 页面隐藏 if (statusBeforeHide) { music.pause(); // 暂停 } } else { // 页面显示 if (statusBeforeHide) { music.play() //如果statusBeforeHide是true, 继续播放 } } } let hiddenProperty = ('hidden' in document) ? 'hidden' : ('webkitHidden' in document) ? 'webkitHidden' : ('mozHidden' in document) ? 'mozHidden' : null; if (hiddenProperty) { let visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange'); let onVisibilityChange = () => { //console.log('visibilityChange'); setChangeMusic(); }; document.addEventListener(visibilityChangeEvent, onVisibilityChange); } else { console.log("不支持这个api"); } [代码] 总结,web-view还是非常实用的组件,且用且珍惜~ 往期回顾: 小程序自定义头部导航栏“完美”解决方案 小程序Canvas生成海报(一) 小程序新版订阅消息+云开发实战与跳坑
2021-09-13 - 小程序 webview 内嵌 h5 支付、路由跳转
一.介绍允许通过特定方式在小程序内通过 webview 内嵌 h5 页面,跳转以及支付等流程。 大致流程如下: 小程序创建 webview 加载 h5 url(https://3400.retail.../shop/index),后续跳转通过 url 后拼接的参数判断是否要跳转新的 webview 页面(参数符合规则并且此跳转点击使用了 CommonRouter(见在H5页面中集成的小程序跳转路由),否则只是普通的页面跳转),支付环节需要小程序创建一个原生页面用于支付中转; 二.集成1.创建 webview 容器用于承载 h5 页面(webview 组件用法参考官方组件) 创建一个 webview page,用于加载 h5 url,路径没有要求,只需在 步骤2>参数拼接 时带上路径即可。 2.参数拼接在 webview 加载 url 之前,需要在 url 后拼接上必要的参数,否则无法在新的 webview 打开下一次页面和在H5生成支付参数,在H5页面生成支付参数,请求后端生成支付参数接口要用小程序的appid,openid。webview 完整示例如下: Page({ data: { weburl:'' //加载的 url }, onLoad: function (options) { let url = decodeURIComponent(options.url) // url 拼接参数 this.dealUrl(url) }, dealUrl(url) { /** * miniProgramWebviewPath webview 的路径, 必传 解决采用小程序路由跳转H5嵌在多个小程序webview,跳回小程序webview * miniProgramPayPath 支付中转页路径,必传 * pageStackLength 页面路由栈个数,必传 解决小程序跳转10级问题,改用redirectTo跳转, * ec_appid、ec_openid 两个参数为支付所需参数,必传 */ let miniProgramWebviewPath = encodeURIComponent(`${this.route}?weburl=`) let miniProgramPayPath = "pages/h5payment/payMiddle/index" let pageStackLength = getCurrentPages().length let ec_appid = "wxb956c83845b9c0" let ec_openid = "oOVgY4xSj-LyuFifcaF_YDcRLU" const urlParams = {} urlParams.ec_openid = ec_openid urlParams.ec_appid = ec_appid urlParams.miniProgramWebviewPath = miniProgramWebviewPath urlParams.pageStackLength = pageStackLength urlParams.miniProgramPayPath = miniProgramPayPath let weburl = this.onInsterParamsInUrl(url, urlParams) this.setData({ weburl }) }, /** * 解析 url param */ onInsterParamsInUrl(url, params) { let tempUrl = '' let hasParams = url.indexOf('?') !== -1; tempUrl = Object.keys(params).reduce(function (before, after) { return before + after + '=' + params[after] + '&' }, tempUrl) tempUrl = tempUrl.substring(0, tempUrl.length - 1) return hasParams ? (url + '&' + tempUrl) : (url + '?' + tempUrl) } }) 3.支付中转页小程序内嵌 h5 的支付无法直接使用微信环境 sdk 支付,需要借助小程序的支付能力,所以小程序需要提供一个支付页面,接收在h5 生成的小程序支付参数,支付成功失败的回调url,发起小程序支付。小程序支付完成,需要跳转到结果回调页面,此页面需要由 webview 打开,所以在下面代码 PayDoneCallback 方法里的跳转路径对应 webview 的路径。 Page({ onLoad: function(options) { /** * 解析 options, options为H5传过来的参数(支付参数,回跳H5的URL) */ this.successUrl = options.successUrl this.failUrl = options.failUrl options.package = decodeURIComponent(options.package); options.paySign = decodeURIComponent(options.paySign); delete options.successUrl delete options.failUrl const { success, fail, cancel } = this.PayDoneCallback(this.successUrl, this.failUrl) this.payment({options, success, fail, cancel}) }, payment(opts) { const data = opts.options let hasComplete = false; wx.requestPayment({ ...data, success: function(res){ typeof opts.success =='function'&&opts.success() }, fail: function(res) { if (res.errMsg == 'requestPayment:fail cancel') { typeof opts.cancel =='function'&&opts.cancel(); hasComplete = true; return; } typeof opts.fail =='function'&&opts.fail() }, complete:function(res){ console.log(res) if (hasComplete) { hasComplete = false; }else if(res.errMsg =='requestPayment:fail cancel'||res.errMsg=="requestPayment:cancel") { typeof opts.cancel =='function'&&opts.cancel() } typeof opts.complete =='function' && opts.complete(res) } }) }, PayDoneCallback(successUrl, failUrl) { return { success(){ wx.redirectTo({ url: `/pages/h5payment/webview/webview?weburl=${successUrl}` }); }, fail(){ wx.redirectTo({ url: `/pages/h5payment/webview/webview?weburl=${failUrl}` }); }, cancel(){ wx.redirectTo({ url: `/pages/h5payment/webview/webview?weburl=${failUrl}` }); } } } })
2021-08-20 - 微信小程序内嵌 web-view 页面改动 iOS 正常显示,Android 依旧是改动前的样子(缓存页面)
微信小程序内嵌 web-view 页面改动 iOS 正常显示,Android 依旧是改动前的样子(缓存页面) 前言 小程序里webview打开的H5页面怎么清除缓存? [图片] 如图,在 iOS 系统的手机上(开发者工具上)已经能正常显示新页面了,而 Android 系统的手机上却还是左侧的老页面 不管是退出重进小程序还是删掉小程序重新搜索进入、亦或是清除微信缓存、关掉微信重进、清除手机缓存依旧不能生效,等到了第二天再试一遍这种方法依旧不能生效… 在微信开发者社区也可以看出,大家怨念极重,哈哈哈哈… 解决方法 给 web-view src 对应的 url 换成动态的(加个随机参数),时间戳作为这个参数,页面也不会频繁去改动,所以取前几位就行了 [代码]// <web-view src="{{webviewurl}}"></web-view> Page({ /** * 页面的初始数据 */ data: { webviewurl: 'https://www.coveycity.com/zsdt?t=' + (""+new Date().getTime()).slice(0, -5), // 页面缓存时间为一分钟左右(具体没去换算) }, // ... }) [代码] 如果还是不行,可以参考网友的建议: 所有资源全部加上版本号,可以解决,是所有资源! 不只是页面路径,页面里的样式,js , 图片等都加 [图片]
2021-09-01 - 小程序webview组件,小程序和webview交互,小程序内联h5页面,小程序webview内网页实现微信支付
小程序支持webview以后,我们开发的好多h5页面,就可以直接在小程序里使用了,比如我们开发的微信商城,文章详情页,商品详情页,就可以开发一套,多处使用了。我们今天来讲一讲。在小程序的webview里实现微信支付功能。因为微信不允许在小程序的webview里直接调起微信支付。所以我们这节课就要涉及到小程序和webview的交互了。 老规矩先看效果。 因为这里涉及的东西比较多,录gif太多,没法上传,我就录制了一段视频出来。 https://v.qq.com/x/page/t0913iprnay.html 原理 先说下实现原理吧,实现原理就是我们在webview的h5页面里实现下单功能,然后点击支付按钮,我们点击支付按钮的时候会跳转到小程序页面,把订单号,订单总金额,传递到小程序里,然后小程序里使用订单号和订单金额去调起微信支付,实现付款,付款成功或者失败时都会有回调。我们再把对应的回调传递给webview,刷新webview里的订单和支付状态。 一,定义webview显示h5页面 关于webview的使用,我就不做讲解了,官方文档里写的很清楚,用起来也很简单。https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html [图片] webview很简单,就是用一个webview组件,显示我们的网页。 二,定义h5页面 我这里启动一个本地服务器,用来展示一个简单的h5页面。 [图片] 上图是我在浏览器里显示的效果。 接下来我们在小程序的webview里显示这个页面,也很简单,只需要把我们的src定义为我们的本地网页链接就可以了。 [图片] 这里有一点需要注意 因为我们是本地链接,我们需要到开发者工具里把这一项给勾选。 [图片] 三,来看下h5页面代码 [代码]<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>小程序内嵌webview</title> <style> .btn { font-size: 70px; color: red; } </style> </head> <body> <h1>我是webview里的h5页面</h1> <a id="desc" class="btn" onclick="jumpPay()">点击支付</a> <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> <script> console.log(location.href); let payOk = getQueryVariable("payOk"); console.log("payOk", payOk) if(payOk){//支付成功 document.getElementById('desc').innerText="支持成功" document.getElementById('desc').style.color="green" }else{ document.getElementById('desc').innerText="点击支付" } //获取url里携带的参数 function getQueryVariable(variable) { var query = window.location.search.substring(1); var vars = query.split("&"); for (var i = 0; i < vars.length; i++) { var pair = vars[i].split("="); if (pair[0] == variable) { return pair[1]; } } return (false); } function jumpPay() { let orderId = Date.now();//这里用当前时间戳做订单号(后面使用你自己真实的订单号) let money = 1;//订单总金额(单位分) let payData = {orderId: orderId, money: money}; let payDataStr = JSON.stringify(payData);//因为要吧参数传递给小程序,所以这里需要转为字符串 const url = `../wePay/wePay?payDataStr=${payDataStr}`; wx.miniProgram.navigateTo({ url: url }); // console.log("点击了去支付", url) console.log("点击了去支付") } </script> </body> </html> [代码] h5代码这里不做具体讲解,只简单说下。我们就是在点击支付按钮时,用当前时间戳做为订单号(因为订单号要保证唯一),然后传一个订单金额(单位分),这里节约起见,就传1分钱吧,花的是自己的钱,心疼。。。。 关键点说一下 1, 必须引入jweixin,才可以实现h5跳转小程序。 <script type=“text/javascript” src=“https://res.wx.qq.com/open/js/jweixin-1.3.2.js”></script> 2,跳转到小程序页面的方法 [代码]const url = `../wePay/wePay?payDataStr=${payDataStr}`; wx.miniProgram.navigateTo({ url: url }); [代码] 这里要和你小程序的页面保持一致。payDataStr是我们携带的参数 [图片] 四,小程序支付页 来看下我们的小程序支付页 [图片] 小程序支付页功能很简单,就是来接收我们h5传过订单号和订单金额。然后去调起微信支付,实现支付。支付成功和支付失败都有对应的回调。 [图片] 支付我们这里实用的小程序云开发来实现的支付,核心代码只有10行。由于支付不是本节的重点,所以这里不做具体讲解。感兴趣的同学可以去看我写的文章和我录的视频 小程序支付文章:https://www.jianshu.com/p/2b391df055a9 小程序支付视频:https://edu.csdn.net/course/play/25701/310742 下面把小程序接收参数和支付的完整代码贴出来给大家 [代码]Page({ //h5传过来的参数 onLoad: function(options) { console.log("webview传过来的参数", options) //字符串转对象 let payData = JSON.parse(options.payDataStr) console.log("orderId", payData.orderId) let that = this; wx.cloud.callFunction({ name: "pay", data: { orderId: payData.orderId, money: payData.money }, success(res) { console.log("获取成功", res) that.goPay(res.result); }, fail(err) { console.log("获取失败", err) } }) }, //微信支付 goPay(payData) { wx.requestPayment({ timeStamp: payData.timeStamp, nonceStr: payData.nonceStr, package: payData.package, signType: 'MD5', paySign: payData.paySign, success(res) { console.log("支付成功", res) //你可以在这里支付成功以后,再跳会webview页,并把支付成功状态传回去 wx.navigateTo({ url: '../webview/webview?payOk=true', }) }, fail(res) { console.log("支付失败", res) } }) } }) [代码] 代码里注释很清楚,这里有一点,就是我们支付成功后,需要告诉h5我们支付成功了,通知h5去刷新订单或者支付状态。 到这里我们就完整的实现了小程序webview展示h5页面,并且做到了h5和小程序的交互,实现了小程序webview的支付功能。 是不是很简单呢。 源码地址 1,关注“编程小石头”公号,回复“webview”即可获取源码 2,也可以到我github下载源码 https://github.com/qiushi123/xiaochengxu_demos [图片]
2019-08-15 - 如何解决小程序订阅消息page页面传参数的问题,无法跳转指定的页面?
小程序订阅消息中page 怎么写? 后端php环境 $page ='pages/dt/index?id=5&uid=6&cid=7'; 发送没问题,也能 收到,但就是页面打开是空白,不能跳转指定的小程序页面。 地址没问题,为什么都打不开,是空白的
2021-04-01 - 订阅消息 page 跳转问题
如题 使用:page: "pages/index/index" 使用其他的页面时,报页面不存在
2019-11-27 - 小程序引入外部字体怎么实现呢?
小程序引入外部字体,用https://transfonter.org/转成了base64,然后把.css改成.wxss,但是报错 something must be wrong ,我想是因为包太大了,该怎么办呢
2019-10-10 - [有点炫]自定义navigate+分包+自定义tabbar
自定义navigate+分包+自定义tabbar,有需要的可以拿去用用,可能会存在一些问题,根据自己的业务改改吧 大家也可以多多交流 代码片段:在这里 {"version":"1.1.5","update":[{"title":"修复 [复制代码片段提示] 无法使用的问题","date":"2020-06-15 09:20","imgs":[]}]} 更新日志: 2019-11-25 自定义navigate 也可以调用wx.showNavigationBarLoading 和 wx.hideNavigationBarLoading 2019-11-25 页面滚动条显示在自定义navigate 和 自定义tabbar上面的问题(点击“体验custom Tabbar” [图片] [图片] 其他demo: 云开发之微信支付:代码片段
2020-06-15 - 小程序分包相关问题,有哪位大神帮忙解答下?急急急~
1.小程序分包时候,可以只把首页放在主包,剩余三个tab页放在不同的分包中吗? 2.主包和分包之间可以共享数据吗? 3.主包和分包之间可以页面跳转吗? 4.分包的规则是什么?怎样分包,才能使小程序的结构清晰,且性能比较优?
2020-09-17 - 小程序分包没有超过2M,但是上传却提示分包超过2M?
小程序分包没有超过2M,但是上传却提示分包超过2M?
2020-04-18 - getUserProfile 调用失败
https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserProfile.html 期望行为: 当用户授权,调用 success 回调成功 目前行为: 不弹出授权框,{errMsg: "getUserProfile:fail can only be invoked by user TAP gesture."} Note: 如果此方法必须要绑定某个事件使用,请在文档中明确注明「此方法必须在 X 事件的响应函数中使用,否则报错」。请不要浪费开发者的时间
2021-03-31 - 关于 wx.loadFontFace 加载字体在真机环境下不能正常显示的实验结果分享及正确解决方案
wx.loadFontFace 必须满足的条件: 跨域 / CORS 下载的字体文件的响应头中必须包含:Access-Control-Allow-Origin: * 这里指出一下,官方文档注意事项描述中的第3点这里有个问题(也可能是我理解错了,望指正): 官方写的是:“字体链接必须是同源下的,或开启了cors支持,小程序的域名是servicewechat.com”; 经过测试后发现如果将 Access-Control-Allow-Origin 设置为:“servicewechat.com” 的话在iOS设备中可以正确下载字体,但在安卓中不能下载,显示的是:“loadFontFace:fail”, 反复测试了一下如果将 Access-Control-Allow-Origin 设置为 * 在安卓真机环境下就可以下载成功并显示了。 响应文件类型 Content-Type 必须设置为正确的字体类型,例如 *.ttf 对应的类型是 “font/ttf” 总结 正确显示字体的必要条件就是: Access-Control-Allow-Origin: * Content-Type: font/ttf | font/woff | font/woff2 | ... *上面这两条配置需要后端在字体文件保存的服务器或者CDN设置 为了让字体快速的加载,尽可能压缩字体文件大小或者精简字体,1mb内的字体大小基本可以在正常4G网络下实时加载出来;wx.loadFontFace需要设置 global 属性,才能全局生效;下载字体文件的域名必须配置到小程序的 downloadFile 合法域名中;下载的字体文件域名需要使用HTTPS协议;以上是个人实验下来的结果和一些经验,如果有不正确的地方可以评论指出。 参考 常见文件类型列表跨域/CORS(跨域资源共享)
2021-02-18 - 微信小程序加载自定义字体包会出现渲染层网络层错误
https://developers.weixin.qq.com/miniprogram/dev/api/ui/font/wx.loadFontFace.html 我用了两种方式 wx.loadFontFace api或者 直接在wxss中引入自定义字体包 都会出现这个错误 [图片]
2020-09-15 - 微信 JS SDK 扫码二维码 api scanQRCode, 不会回调 suc
[图片]
2019-09-02 - canvas clip 裁剪圆形图像有黑边?
canvas绘制圆形图像会生成黑边, 设置fillStyle也不生效, 代码如下: ``` /** * 绘制用户头像 * @param ctx */ drawAvatar(ctx, canvas, screenWidth) { const _this = this; // 绘制头像圆圈 ctx.save(); const w = 94 * screenWidth / 750; const h = 94 * screenWidth / 750; const r = 47 * screenWidth / 750; const x = 36 * screenWidth / 750; const y = 1130 * screenWidth / 750; ctx.beginPath(); ctx.fillStyle="white"; ctx.arc(x+r, y+r, r, 0, 2 * Math.PI); // ctx.stroke(); ctx.clip(); // 绘制头像 const posterImg = canvas.createImage(); posterImg.onload = () => { ctx.drawImage(posterImg, x, y, w, h); ctx.restore(); console.log('绘制头像完成>>'); _this.drawCodeImage(ctx, canvas, screenWidth); }; posterImg.src = this.data.userInfo && this.data.userInfo.avatarUrl || '../../../assets/default-head.svg'; }, ```
2020-12-10 - 如何实现一个自定义导航栏
自定义导航栏在刚出的时候已经有很多实现方案了,但是还有大哥在问,那这里再贴下代码及原理: 首先在App.js的 onLaunch中获取当前手机机型头部状态栏的高度,单位为px,存在内存中,操作如下: [代码]onLaunch() { wx.getSystemInfo({ success: (res) => { this.globalData.statusBarHeight = res.statusBarHeight this.globalData.titleBarHeight = wx.getMenuButtonBoundingClientRect().bottom + wx.getMenuButtonBoundingClientRect().top - (res.statusBarHeight * 2) }, failure() { this.globalData.statusBarHeight = 0 this.globalData.titleBarHeight = 0 } }) } [代码] 然后需要在目录下新建个components文件夹,里面存放此次需要演示的文件 navigateTitle WXML 文件如下: [代码]<view class="navigate-container"> <view style="height:{{statusBarHeight}}px"></view> <view class="navigate-bar" style="height:{{titleBarHeight}}px"> <view class="navigate-icon"> <navigator class="navigator-back" open-type="navigateBack" wx:if="{{!isShowHome}}" /> <navigator class="navigator-home" open-type="switchTab" url="/pages/index/index" wx:else /> </view> <view class="navigate-title">{{title}}</view> <view class="navigate-icon"></view> </view> </view> <view class="navigate-line" style="height: {{statusBarHeight + titleBarHeight}}px; width: 100%;"></view> [代码] WXSS文件如下: [代码].navigate-container { position: fixed; top: 0; width: 100%; z-index: 9999; background: #FFF; } .navigate-bar { width: 100%; display: flex; justify-content: space-around; } .navigate-icon { width: 100rpx; height: 100rpx; display: flex; justify-content: space-around; } .navigate-title { width: 550rpx; text-align: center; line-height: 100rpx; font-size: 34rpx; color: #3c3c3c; font-weight: bold; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } /*箭头部分*/ .navigator-back { width: 36rpx; height: 36rpx; align-self: center; } .navigator-back:after { content: ''; display: block; width: 22rpx; height: 22rpx; border-right: 4rpx solid #000; border-top: 4rpx solid #000; transform: rotate(225deg); } .navigator-home { width: 56rpx; height: 56rpx; background: url(https://qiniu-image.qtshe.com/20190301home.png) no-repeat center center; background-size: 100% 100%; align-self: center; } [代码] JS如下: [代码]var app = getApp() Component({ data: { statusBarHeight: '', titleBarHeight: '', isShowHome: false }, properties: { //属性值可以在组件使用时指定 title: { type: String, value: '青团公益' } }, pageLifetimes: { // 组件所在页面的生命周期函数 show() { let pageContext = getCurrentPages() if (pageContext.length > 1) { this.setData({ isShowHome: false }) } else { this.setData({ isShowHome: true }) } } }, attached() { this.setData({ statusBarHeight: app.globalData.statusBarHeight, titleBarHeight: app.globalData.titleBarHeight }) }, methods: {} }) [代码] JSON如下: [代码]{ "component": true } [代码] 如何引用? 需要引用的页面JSON里配置: [代码]"navigationStyle": "custom", "usingComponents": { "navigate-title": "/pages/components/navigateTitle/index" } [代码] WXML [代码]<navigate-title title="青团社" /> [代码] 按上面步骤操作即可实现一个自定义的导航栏。 如何实现通栏的效果默认透明以及滚动更换title为白色背景,如下图所示: [图片] [图片] [图片] [图片] 最后代码片段如下: https://developers.weixin.qq.com/s/wi6Pglmv7s8P。 以下为收集到的社区老哥们的分享: @Yunior: 小程序顶部自定义导航组件实现原理及坑分享 @志军: 微信小程序自定义导航栏组件(完美适配所有手机),可自定义实现任何你想要的功能 @✨o0o有脾气的酸奶💤 [有点炫]自定义navigate+分包+自定义tabbar @安晓苏 分享一个自适应的自定义导航栏组件
2020-03-10 - wx.chooseImage 选图片后会跳到首页(pages.json中第一个路由)的问题
非首页 使用wx.chooseImage做以下操作: 1 选择图片 2 图片列表取消选择 3 拍照确定 然后,页面会出现自动跳转到首页的问题
2020-03-22 - chooseImage拍照闪退,拍照后失败,自动跳转到小程序首页
小米手机note3出现的上诉问题,偶尔发生,我可以提供微信号,上传操作日志
2020-04-20 - 微信公众号H5端无法缓存,重复登陆
已经有第7个用户反馈经常登陆,都是iphone X级别以上的新款机器。身边的手机都太低档了。全都没有问题。终于等到一个同事反馈说他也要每天登陆或间接性登陆了。跳到测试的专用隐藏页面,发现localstorage全都没有了。好奇怪。同事说了没有清过缓存(永远不要相信用户的操作,这次除外)。一切正常使用。官方可以真机自测一下localstorage的存储看看。而且论坛也有相关的反馈了。这确实是真的。手机型号:国行 iphone Xs Max 13.0 微信版本:7.0.11 [图片] 直接加上cookies了。现在localstorage和cookies也没有用。普通浏览器没有问题。就是微信客户端会出现这种情况。但还是没有用。上面图片是最新的一个用户的登陆情况。然后同事这边也是重复登陆了。
2020-04-13 - 微信jssdk遇到问题 config:fail,Error:invalid signature?
{errMsg: "config:fail,Error: 系统错误,错误码:63002,invalid signature [20200310 16:50:42][]", jsApiList: Array(0)}errMsg: "config:fail,Error: 系统错误,错误码:63002,invalid signature [20200310 16:50:42][]"jsApiList: []__proto__: Object[图片] 代码如下 ,真的头大 不知为啥一直出现这个问题? [图片]
2020-03-10 - 同一页面存在多个video时,video无法正常播放一直在加载转圈
不建议同个页面使用多个video组件,建议不超过3个video,如果要实现video列表功能,请进行优化(image列表,选中时将image替换成video)
2019-08-29 - video组件安卓端可以正常播放,开发者工具可以播放,iOS端转圈圈播放不出来?
video组件,苹果微信版本号:7.0.5,微信开发者工具基础库版本号:1.02.1907301
2019-08-07 - 如何同时只能播放一个视频?
列表中有多个video(点击时把image替换成video形式实现),怎么样保证同一页面同时只能播放一个视频?求教!
2019-12-30 - (15)真机定位问题技巧
开发者在开发小程序的时候可能会碰到一些这样的问题: 问题1 开发者工具上看效果没问题,但是在真机上测试不行? 问题2 有用户遇到小程序功能无法使用的问题,但无法快速定位解决? 今天我们的小故事与大家分享一些真机定位的技巧,可以解决上面两个问题。 1 vConsole开发利器和远程调试功能 针对问题1,我们提供了 vConsole 开发利器和远程调试功能,可以协助开发者在定位真机上的问题。 vConsole 的有四个Tab面板,可以先看下 Log 面板,看是否有异常信息,异常类型 thirdScriptError 是框架捕捉到的开发者的代码执行的异常,可以优先处理异常信息看是否可以解决问题。Log 面板可以看到异常出现的文件和行数。 [图片] 除了异常日志,开发者还可以通过 console.log 接口在一些关键执行路径上打日志来定位问题,这些日志会呈现在 Log 面板上。 vConsole 默认是不开启的,可以通过下面2个方法来开启: 1 开发版和体验版可以点击小程序页面右上角的...按钮打开的菜单项“打开调试”来开启 vConsole。 2 正式版没有“打开调试”的菜单项,可以先通过开发版和体验版来开启 vConsole,然后再打开正式版。或者可以预埋一个隐藏操作,比如连续点击某个 Button 多次,然后调用 API 接口 wx.setEnableDebug 来打开。 vConsole 虽然强大,但在手机上查看大量的日志信息不方便,此外,vConsole 没有断点调试、无法修改样式,定位复杂问题需要花费比较多的时间。 小程序的业务逻辑运行在 AppService 层,页面渲染在 WebView 运行,并通过微信客户端通信,因此,我们想到了可以让 AppService 运行在开发者工具,页面渲染还是在手机 WebView,两者通过网络来通信,这样借助开发者工具的调试能力,就可以实现远程调试功能。 远程调试窗口通过手机客户端扫描开发者工具上生成的二维码来打开,无需像普通手机 H5 页面调试一样,需要在手机端进行一些设置。 [图片] 打开的远程调试界面和开发者工具的模拟器的调试界面很像,需要注意的是,要在 Console 里对小程序进行调试,需要将调试的上下文切换到 VM Context 1 。 [图片] 更多的远程调试的使用方法请参考使用文档。 2 意见反馈能力 对于问题2,小程序的使用反馈来自用户投诉,这种情况用户无法联系到开发者。我们遇见过有小程序功能出现问题,用户无法使用,但投诉无门的情况,而这些问题,开发者也没有途径去收集以及处理,这就导致了小程序服务质量下降,用户流失。 为此,我们开发了“意见反馈”功能,当出现问题时,开发者可以引导用户使用“意见反馈”进行反馈,并上传日志来辅助开发者定位问题。操作过程如下: 引导用户进入小程序帐号详情页面,具体可以在小程序界面点击右上角...按钮,选择关于菜单。接着在帐号详情页面点击右上角...按钮,选择意见反馈菜单进入页面。页面可以上传图片和日志,建议用户上传异常情况的截图,以及勾选允许开发者使用小程序日志选项上传日志,反馈信息越详细,越有助于定位问题。 [图片] [图片] 如果觉得上面的操作步骤太麻烦,开发者可以通过在页面 WXML 添加下面的按钮,用户点击按钮可以直接打开“意见反馈”页面。 [图片] 开发者需要定时处理用户的反馈,这样才能保证小程序的质量。开发者可以登录小程序管理后台,进入左侧菜单客服反馈,就可以看到用户的反馈内容以及下载日志来辅助定位问题。 [图片] 为了保证日志信息足够详细,开发者需要用下面的接口在代码的关键执行路径上写日志。 [图片] wx.getLogManager 接口的更详细使用请参考文档。 希望通过这些小技巧,可以帮助大家顺畅地开发小程序。
2019-04-29 - 如何打开线上版本小程序的调试模式
生产版本的小程序如果出现问题,可以调试一下正式版看看,调试方式如下: 方式1、https://developers.weixin.qq.com/miniprogram/dev/api/base/debug/wx.setEnableDebug.html [代码]wx.setEnableDebug(Object object) 基础库 1.4.0 开始支持,低版本需做兼容处理。 设置是否打开调试开关。此开关对正式版也能生效。 参数 Object object 属性 类型 默认值 必填 说明 enableDebug boolean 是 是否打开调试 success function 否 接口调用成功的回调函数 fail function 否 接口调用失败的回调函数 complete function 否 接口调用结束的回调函数(调用成功、失败都会执行) 示例代码 // 打开调试 wx.setEnableDebug({ enableDebug: true }) // 关闭调试 wx.setEnableDebug({ enableDebug: false }) Tips [代码] 方式2、先在开发版或体验版打开调试,再切到正式版就能看到vConsole
2019-11-29 - 云函数获取openid
代码如下: app.js: //如果担心openid的安全,就用这个函数 getCloudOpenid: async function () { return this.openid = this.openid || (await wx.cloud.callFunction({name: 'login'})).result.OPENID }, //最佳方案。 getOpenid: async function () { (this.openid = this.openid || wx.getStorageSync('openid')) || wx.setStorageSync('openid', await this.getCloudOpenid()) return this.openid }, 任何page: onLoad: async function () { console.log(this.openid = await getApp().getOpenid()) }, //在本page的其他函数里获得openid。 yourFunc: function(){ console.log(this.openid) } 云函数login: const cloud = require('wx-server-sdk') cloud.init() exports.main=async()=>{return cloud.getWXContext()}
2020-10-18