- tdesign-miniprogram太大了,.wechatide.ib如何不打到包里面?
tdesign-miniprogram太大了,.wechatide.ib如何不打到包里面
2023-02-22 - 主包太大了,可以将组件components设为分包吗?
主包太大了,可以将组件components设为分包吗?我是uniapp的项目 [图片] 这样加上马上就会报错 [图片] 各位大佬帮忙看下
06-04 - 分包小程序,如何让npm独立依赖?
npm依赖的第三方库,是不是都会被打在主包里面。 我的分包会单独依赖一些第三方库,我应该怎么做? 还是构建的时候会动态根据使用的情况自动分包?
2019-10-08 - 小程序项目里通过npm方式引入了 Tdesign组件库 导致项目主包过大怎么办?
[图片]
07-06 - 我引入了tdesign导致总包过大,怎么办?
我在开发时引入了vant weapp,但因为部分功能简单所以我引入了一下腾讯的tdesign,导致主包现在有2m多,tdesign800kb,vant400kb。有没有办法把这两个放到分包里?或者有什么别的解决方案?
2023-02-13 - TDesign框架开发miniprogram_npm主包太大如何处理?
在使用TDesign开发小程序,miniprogram_npm目录下很多组件,感觉很多组件我都没引用,为什么都在主包来,导致主包很大。如何优化? [图片] [图片]
05-04 - 小程序使用npm包,构建完成后使用,在上传是提示包太大,构建的npm包比较大,怎么处理啊?
小程序使用npm包,构建完成后使用,在上传是提示包太大,构建的npm包比较大。下载的包在构建后生成较多的包文件,导致小程序的包体积过大,这个npm的包也是算作小程序的包体积吗?如果安装过多的包肯定会导致很大的,怎么解决想安装很多npm包而体积又不超过限制呢?
2020-06-04 - 微信OCR识别,一个正常的https图片地址无法识别,报错: decode image failed
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/img-ocr/ocr/idCardOCR.html 示例图片地址: https://domain.cn:4343/2037/123.jpg 图片地址域名后添加了端口,OCR就无法识别了 decode image failed hint: [4PdDeA06506405] rid: 66b5c1c2-407e8ca3-644765d8
08-09 - 小程序开发工具中怎样编辑多行呢?
我想选中多行进行编辑,怎样才能做到呢? 我用alt+shift+左键,但是编辑的时候,会修改光标后面的内容。我不想修改原来内容,只是想在光标后面添加内容,怎样做到呢? [图片]
2020-05-12 - 如何解决淘宝链接生成二维码无法打开通过点击链接是可以正常访问的?
1、淘宝链接生成二维码无法打开,但通过链接打开就可以。是否需要做相关的公众号配置才行? 如果以上无法通过淘宝链接生成二维码直接打开,是否可以通过在自己的项目里面重定向到淘宝(该功能通过链接打开可以正常进行,但是通过二维码生成链接) 目前可以在在页面中嵌入iframe,可以获取到微信授权信息吗?
2023-10-25 - 微信小程序如何访问淘宝联盟转链?
听说腾讯和阿里互通了,微信小程序是否可以跳转淘宝联盟商品转链?
2023-11-21 - 小程序接淘宝联盟
小程序,微信小程序跳转淘宝联盟链接,我需要怎么操作呢
2019-07-07 - 用 HTM 实现小程序 SVG
写在前面 今天你可以在小程序中使用 Cax 引擎高性能渲染 SVG! SVG 是可缩放矢量图形(Scalable Vector Graphics),基于可扩展标记语言,用于描述二维矢量图形的一种图形格式。它由万维网联盟制定,是一个开放标准。SVG 的优势有很多: SVG 使用 XML 格式定义图形,可通过文本编辑器来创建和修改 SVG 图像可被搜索、索引、脚本化或压缩 SVG 是可伸缩的,且放大图片质量不下降 SVG 图像可在任何的分辨率下被高质量地打印 SVG 可被非常多的工具读取和修改(比如记事本) SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性、可编程星更强 SVG 完全支持 DOM 编程,具有交互性和动态性 而支持上面这些优秀特性的前提是 - 需要支持 SVG 标签。比如在小程序中直接写: [代码]<svg width="300" height="150"> <rect bindtap="tapHandler" height="100" width="100" style="stroke:#ff0000; fill: #0000ff"> </rect> </svg> [代码] 上面定义了 SVG 的结构、样式和点击行为。但是小程序目前不支持 SVG 标签,仅仅支持加载 SVG 之后 作为 background-image 进行展示,如 [代码]background-image: url("data:image/svg+xml.......)[代码],或者 base64 后作为 background-image 的 url。 直接看在小程序种使用案例: [代码]import { html, renderSVG } from '../../cax/cax' Page({ onLoad: function () { renderSVG(html` <svg width="300" height="220"> <rect bindtap="tapHandler" height="110" width="110" style="stroke:#ff0000; fill: #ccccff" transform="translate(100 50) rotate(45 50 50)"> </rect> </svg>`, 'svg-a', this) }, tapHandler: function () { console.log('你点击了 rect') } }) [代码] 其中的 svg-a 对应着 wxml 里 cax-element 的 id: [代码]<view class="container"> <cax-element id="svg-c"></cax-element> </view> [代码] 声明组件依赖 [代码]{ "usingComponents": { "cax-element":"../../cax/index" } } [代码] 小程序中显示效果: [图片] 可以使用 [代码]width[代码],[代码]height[代码],[代码]bounds-x[代码] 和 [代码]bounds-y[代码] 设置绑定事件的范围,比如: [代码]<path width="100" height="100" bounds-x="50" bounds-y="50" /> [代码] 需要注意的是,元素的事件触发的包围盒受自身或者父节点的 transform 影响,所以不是绝对坐标的 rect 触发区域。 再来一个复杂的例子,用 SVG 绘制 Omi 的 logo: [代码]renderSVG(html` <svg width="300" height="220"> <g transform="translate(50,10) scale(0.2 0.2)"> <circle fill="#07C160" cx="512" cy="512" r="512"/> <polygon fill="white" points="159.97,807.8 338.71,532.42 509.9,829.62 519.41,829.62 678.85,536.47 864.03,807.8 739.83,194.38 729.2,194.38 517.73,581.23 293.54,194.38 283.33,194.38 "/> <circle fill="white" cx="839.36" cy="242.47" r="50"/> </g> </svg>`, 'svg-a', this) [代码] 小程序种显示效果: [图片] 在 omip 和 mps 当中使用 cax 渲染 svg,你可以不用使用 htm。比如在 omip 中实现上面两个例子: [代码] renderSVG( <svg width="300" height="220"> <rect bindtap="tapHandler" height="110" width="110" style="stroke:#ff0000; fill: #ccccff" transform="translate(100 50) rotate(45 50 50)"> </rect> </svg>, 'svg-a', this.$scope) [代码] [代码]renderSVG( <svg width="300" height="220"> <g transform="translate(50,10) scale(0.2 0.2)"> <circle fill="#07C160" cx="512" cy="512" r="512"/> <polygon fill="white" points="159.97,807.8 338.71,532.42 509.9,829.62 519.41,829.62 678.85,536.47 864.03,807.8 739.83,194.38 729.2,194.38 517.73,581.23 293.54,194.38 283.33,194.38 "/> <circle fill="white" cx="839.36" cy="242.47" r="50"/> </g> </svg>, 'svg-a', this.$scope) [代码] 需要注意的是在 omip 中传递的最后一个参数不是 [代码]this[代码],而是 [代码]this.$scope[代码]。 在 mps 中,更加彻底,你可以单独创建 svg 文件,通过 import 导入。 [代码]//注意这里不能写 test.svg,因为 mps 会把 test.svg 编译成 test.js import testSVG from '../../svg/test' import { renderSVG } from '../../cax/cax' Page({ tapHandler: function(){ this.pause = !this.pause }, onLoad: function () { renderSVG(testSVG, 'svg-a', this) } }) [代码] 比如 test.svg : [代码]<svg width="300" height="300"> <rect bindtap="tapHandler" x="0" y="0" height="110" width="110" style="stroke:#ff0000; fill: #0000ff" /> </svg> [代码] 会被 mps 编译成: [代码]const h = (type, props, ...children) => ({ type, props, children }); export default h( "svg", { width: "300", height: "300" }, h("rect", { bindtap: "tapHandler", x: "0", y: "0", height: "110", width: "110", style: "stroke:#ff0000; fill: #0000ff" }) ); [代码] 所以总结一下: 你可以在 mps 中直接使用 import 的 SVG 文件的方式使用 SVG 你可以直接在 omip 中使用 JSX 的使用 SVG 你可以直接在原生小程序当中使用 htm 的方式使用 SVG 这就完了?远没有,看 cax 在小程序中的这个例子: [图片] 详细代码: [代码]renderSVG(html` <svg width="300" height="200"> <path d="M 256,213 C 245,181 206,187 234,262 147,181 169,71.2 233,18 220,56 235,81 283,88 285,78.7 286,69.3 288,60 289,61.3 290,62.7 291,64 291,64 297,63 300,63 303,63 309,64 309,64 310,62.7 311,61.3 312,60 314,69.3 315,78.7 317,88 365,82 380,56 367,18 431,71 453,181 366,262 394,187 356,181 344,213 328,185 309,184 300,284 291,184 272,185 256,213 Z" style="stroke:#ff0000; fill: black"> <animate dur="32s" repeatCount="indefinite" attributeName="d" values="......太长,这里省略 paths........" /> </path> </svg>`, 'svg-c', this) [代码] 再试试著名的 SVG 老虎: [图片] path 太长,就不贴代码了,可以点击这里查看 pasiton 标签 [代码]import { html, renderSVG } from '../../cax/cax' Page({ onLoad: function () { const svg = renderSVG(html` <svg width="200" height="200"> <pasition duration="200" bindtap=${this.changePath} width="100" height="100" from="M28.228,23.986L47.092,5.122c1.172-1.171,1.172-3.071,0-4.242c-1.172-1.172-3.07-1.172-4.242,0L23.986,19.744L5.121,0.88 c-1.172-1.172-3.07-1.172-4.242,0c-1.172,1.171-1.172,3.071,0,4.242l18.865,18.864L0.879,42.85c-1.172,1.171-1.172,3.071,0,4.242 C1.465,47.677,2.233,47.97,3,47.97s1.535-0.293,2.121-0.879l18.865-18.864L42.85,47.091c0.586,0.586,1.354,0.879,2.121,0.879 s1.535-0.293,2.121-0.879c1.172-1.171,1.172-3.071,0-4.242L28.228,23.986z" to="M49.1 23.5H2.1C0.9 23.5 0 24.5 0 25.6s0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1C51.2 24.5 50.3 23.5 49.1 23.5zM49.1 7.8H2.1C0.9 7.8 0 8.8 0 9.9c0 1.1 0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1C51.2 8.8 50.3 7.8 49.1 7.8zM49.1 39.2H2.1C0.9 39.2 0 40.1 0 41.3s0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1S50.3 39.2 49.1 39.2z" from-stroke="red" to-stroke="green" from-fill="blue" to-fill="red" stroke-width="2" /> </svg>`, 'svg-c', this) this.pasitionElement = svg.children[0] }, changePath: function () { this.pasitionElement.toggle() } }) [代码] pasiton 提供了两个 path 和 颜色 相互切换的能力,最常见的场景比如 menu 按钮和 close 按钮点击后 path 的变形。 举个例子,看颜色和 path 同时变化: [图片] 线性运动 这里举一个在 mps 中使用 SVG 的案例: [代码]import { renderSVG, To } from '../../cax/cax' Page({ tapHandler: function(){ this.pause = !this.pause }, onLoad: function () { const svg = renderSVG(html` <svg width="300" height="300"> <rect bindtap="tapHandler" x="0" y="0" height="110" width="110" style="stroke:#ff0000; fill: #0000ff" /> </svg>` , 'svg-a', this) const rect = svg.children[0] rect.originX = rect.width/2 rect.originY = rect.height/2 rect.x = svg.stage.width/2 rect.y = svg.stage.height/2 this.pause = false this.interval = setInterval(()=>{ if(!this.pause){ rect.rotation++ svg.stage.update() } },15) }) [代码] 效果如下: [图片] 组合运动 [代码]import { renderSVG, To } from '../../cax/cax' Page({ onLoad: function () { const svg = renderSVG(html` <svg width="300" height="300"> <rect bindtap="tapHandler" x="0" y="0" height="110" width="110" style="stroke:#ff0000; fill: #0000ff" /> </svg>` ,'svg-a', this) const rect = svg.children[0] rect.originX = rect.width/2 rect.originY = rect.height rect.x = svg.stage.width/2 rect.y = svg.stage.height/2 var sineInOut = To.easing.sinusoidalInOut To.get(rect) .to().scaleY(0.8, 450, sineInOut).skewX(20, 900, sineInOut) .wait(900) .cycle().start() To.get(rect) .wait(450) .to().scaleY(1, 450, sineInOut) .wait(900) .cycle().start() To.get(rect) .wait(900) .to().scaleY(0.8, 450, sineInOut).skewX(-20, 900, sineInOut) .cycle() .start() To.get(rect) .wait(1350) .to().scaleY(1, 450, sineInOut) .cycle() .start() setInterval(() => { rect.stage.update() }, 16) } }) [代码] 效果如下: [图片] 其他 vscode 安装 lit-html 插件使 htm 的 html[代码]内容[代码] 高亮 还希望小程序 SVG 提供什么功能可以开 issues告诉我们,评估后通过,我们去实现! Cax Github 参考文档
01-04 - 【优化】利用函数防抖和函数节流提高小程序性能
大家好,上次给大家分享了swiper仿tab的小技巧: https://developers.weixin.qq.com/community/develop/article/doc/000040a5dc4518005d2842fdf51c13 [代码]今天给大家分享两个有用的函数,《函数防抖和函数节流》 函数防抖和函数节流是都优化高频率执行js代码的一种手段,因为是js实现的,所以在小程序里也是适用的。 [代码] 首先先来理解一下两者的概念和区别: [代码] 函数防抖(debounce)是指事件在一定时间内事件只执行一次,如果在这段时间又触发了事件,则重新开始计时,打个很简单的比喻,比如在打王者荣耀时,一定要连续干掉五个人才能触发hetai kill '五连绝世'效果,如果中途被打断就得重新开始连续干五个人了。 函数节流(throttle)是指限制某段时间内事件只能执行一次,比如说我要求自己一天只能打一局王者荣耀。 这里也有个可视化工具可以让大家看一下三者的区别,分别是正常情况下,用了函数防抖和函数节流的情况下:http://demo.nimius.net/debounce_throttle/ [代码] 适用场景 函数防抖 搜索框搜索联想。只需用户最后一次输入完,再发送请求 手机号、邮箱验证输入检测 窗口resize。只需窗口调整完成后,计算窗口大小。防止重复渲染 高频点击提交,表单重复提交 函数节流 滚动加载,加载更多或滚到底部监听 搜索联想功能 实现原理 [代码] 函数防抖 [代码] [代码]const _.debounce = (func, wait) => { let timer; return () => { clearTimeout(timer); timer = setTimeout(func, wait); }; }; [代码] [代码] 函数节流 [代码] [代码]const throttle = (func, wait) => { let last = 0; return () => { const current_time = +new Date(); if (current_time - last > wait) { func.apply(this, arguments); last = +new Date(); } }; }; [代码] [代码] 上面两个方法都是比较常见的,算是简化版的函数 [代码] lodash中的 Debounce 、Throttle [代码] lodash中已经帮我们封装好了这两个函数了,我们可以把它引入到小程序项目了,不用全部引入,只需要引入debounce.js和throttle.js就行了,链接:https://github.com/lodash/lodash 使用方法可以看这个代码片段,具体的用法可以看上面github的文档,有很详细的介绍:https://developers.weixin.qq.com/s/vjutZpmL7A51[代码]
2019-02-22 - 地图瓦片/ Leaflet/自定义图层WMSLayer,小程序都不能用?来试试这个方法
需求 最近项目甲方想把PC端的地图线路绘制在手机上,并且还要在小程序上,听得我心里一惊,那么多线,那么多点符号,我该如何画啊,小程序最大setData也有1M的限制。但是需求来了就得想办法解决。 寻找方法 1、小程序方法[代码]polyline[代码]+[代码]marker[代码](适用普通的点位渲染) 小程序文档翻了翻,发现map组件文档有个 “聚合能力” 我似乎看见了新大陆,觉得肯定可以满足,经过一番研究,还是不能满足,因为这种方法只能用[代码]polyline[代码]来画线,而点或符号用[代码]marker[代码]来画,这种方法数据要处理大多了,因为我的项目线多,符号也多还不同形状的符号,PC端的显示是使用瓦片来渲染,没有分那么多符号和点位,这个方法以失败告终。有兴趣可以看下这个博客写的内容和我这里讲的差不多:微信小程序添加外部地图服务数据 2、自定义图层WMSLayer 上面方法不行,于是我找了gis,跟他讨论了我这个需求,看看有没有办法可以满足我的需求,他们就给我推荐了自定义图层WMSLayer,他说PC端就是用这种方式实现,导入一份数据就可以了。我就说好的,我自己回去研究了一番,发现是需要引入GL的包,但是小程序不支持dom操作,和普通web页面还是有区别,于是我就放弃了该方法。 3、Leaflet插件 这个方法也是gis那边介绍的一个插件库,我寻找了很多遍,发现没有支持小程序的插件库,只是支持web网页开发,还是无法使用到小程序中。传送门leaflet地址 4、小程序个性化图层 这个方法我研究过,就是可以直接导入图层瓦片,最终腾讯生成一个个性化地图id,然后小程序调用个性化图层id。该方法好像还行,但是我没有具体操作,因为我的数据不是固定的,随时会改变,如果每次改变又去改个性化地图就惨了,这种方法适用于景区景点类型。 腾讯地图个性化图层 看见社区有人发的web效果图地址 个性化地图使用指南 我使用的方法 思来索去既然瓦片是图,那能不能让gis那边直接返回一张图片呢?我这边就贴图就行?因为小程序刚好有个[代码]自定义图片图层[代码]可以跟着地图变大变小[图片] 感觉这个方法挺好的,联想了加入是一张张瓦片我也可以对准位置贴上去,连在一起就是我想要的效果了。于是找了gis那边的同事,发现他们有这种方法可以获取图片。addGroundOverlay文档地址 思路 先看下addGroundOverlay的参数 [图片] 单独一个参数抽出来 [图片] 由图可见,有一个很重要的参数[代码]bounds[代码]这个参数,这个参数就是获取地图的对角点,用来确定当前地图视野范围,有了这个参数,我们就叫gis那边生成一张图片,然后粘贴到我们小程序的地图上面就完成了渲染。这里需要注意几点: gis那边生成的图片需要几个参数, a、需要对角点即[代码]bounds[代码]一样的参数,可以通过小程序提供的MapContext.getRegion获取当前地图的视野范围 b、需要获取你当前手机全屏屏幕宽高(windowWidth这个),用这个宽高传给gis那边生成图片的宽高 c、使用地图map组件提供的方法[代码]bindregionchange[代码]来监听,当前缩放或者中心点移动,然后去请求最新视野的图片粘贴上去 d、这里有个不好的问题就是用[代码]MapContext.updateGroundOverlay[代码]方法,更新上一张的贴图会出现闪动问题(即更新最新的图片会发生显示原来图片位置、然后隐藏才显示最新的图片位置),为了解决这个问题,我使用了每次变动位置请求最新图片,都用增加方法[代码]MapContext.addGroundOverlay[代码]去添加贴图到地图,然后把旧的贴图全部删除,为了效果看起来像懒加载,等加载完最新的图片在去删除旧的图片,这样就不会出现闪动的问题 核心代码如下: [代码]onReady: function (options) { this.MapContext = wx.createMapContext('mapId', this) this.getSystemInfo = wx.getSystemInfo().then(res => { this.getSystemInfo = res }) this.indexId = 1 }, bindregionchange: function (e) { if (e.type === 'end') { const northeast = e.detail.region.northeast const southwest = e.detail.region.southwest if (mapTimer) clearTimeout(mapTimer) mapTimer = setTimeout(()=> { this.updataMap(southwest, northeast) }, 100) } }, updataMap(southwest, northeast) { const northeast1 = { longitude: CoordTransformUtil.GCJ02ToWGS84(northeast.longitude, northeast.latitude)[0], latitude: CoordTransformUtil.GCJ02ToWGS84(northeast.longitude, northeast.latitude)[1] } const southwest1 = { longitude: CoordTransformUtil.GCJ02ToWGS84(southwest.longitude, southwest.latitude)[0], latitude: CoordTransformUtil.GCJ02ToWGS84(southwest.longitude, southwest.latitude)[1] } overlayId.push(this.indexId) this.indexId = this.indexId + 1 this.MapContext.addGroundOverlay({ id: this.indexId, src: `https://xxx/export?bbox=${northeast1.longitude},${northeast1.latitude},${southwest1.longitude},${southwest1.latitude}&bboxSR=4490&layers=&layerDefs=&size=${this.getSystemInfo.windowWidth},${this.getSystemInfo.windowHeight}`, bounds: { southwest: southwest, northeast: northeast }, success: async (res) => { // 由于使用updata图层会出现每次闪图渲染问题,所以每次获取图层都是新增的,故这里需要把每次渲染的图层删除,只留最后一次 if (mapTimer2) clearTimeout(mapTimer2) mapTimer2 = setTimeout(async() => { await Promise.all(overlayId.map(async (item) => { await this.MapContext.removeGroundOverlay({ id: item }); overlayId = overlayId.filter(fil => fil != item) })); }, 500) }, fail: (err) => { console.error(err, 'fail...addGroundOverlay') } }) } [代码] 总结 抱歉了,其实我这是不讲武德,把技术点给gis那边处理了,我这边只需要把他们处理好的图片粘贴上去就好了,经过验证该方法确实可行的哦 解决问题才是王道 代码片段:https://developers.weixin.qq.com/s/taAR41mz7GHT
2023-03-27 - 小程序A能引导跳转至小程序B吗?(主体不一致,举例京东跳淘宝)
小程序A能引导跳转至小程序B吗?(主体不一致,举例京东跳淘宝)
09-04 - 开源leaflet地图组件小程序版——leafletwx
leafletwx开源地址:https://gitee.com/zz2022com/leafletwx leaflet库的微信小程序版(使用小程序原生组件view+image显示瓦片,并非web-view方式) leafletwx在leaflet的基础上开发,是leaflet的微信小程序版本。 目前,leafletwx支持地图加载、缩放、移动、POI显示、线、面显示。 本项目中,有QQ地图、百度地图、高德地图以及天地图的加载方式。 由于微信小程序不支持dom操作,leaflet的部分插件无法直接用在leafletwx上,后续会陆续适配。 加载QQ地图 [图片] 加载百度地图 [图片] 加载高德地图 [图片] 加载天地图 [图片]
2023-04-19 - 最近激励视频广告收益断崖式下跌,为什么?
[图片][图片] 请教一下,这个数据是正常的吗?大家最近的收益都是怎样的呢
2023-04-27 - 小程序激励广告的视屏广告秒数 6-15秒和6-30秒的广告收益有区别吗,还是收益是一样的?
最近发现小程序激励广告的视屏秒数是可以设置的,有6-15秒,6-30秒和6-60秒三钟选择,请问这三类的千次曝光收益是一样的吗,还是有不同计费区别的? [图片] [图片]
2022-07-25 - 小程序激励广告被指出利诱其他用户参与,转发,下载,或委托刷单平台等方式行为,被永久封禁?
小程序经营推广运营快1年了,积累了不少用户。从来没有违规过。最近被人举报了,就收到了直接永久封禁,不给整改机会吗?这个违规确实没有利诱其他用户参与、转发、下载或者委托刷单平台等方式行为,只是放了一个激励广告,不是很能理解这个封禁的理由。 如果说官方给了警告拒不修改的。给永久封禁就不说了,但是第一次莫名的就被永久封禁。小程序经营推广不易,希望官方再给一次机会? appId:wx9f355e03b038be66 [图片]
06-04 - 云开发 如何批量修改云数据库中集合的某一个字段的类型?
如题,使用了云开发,集合里的一个字段类型目前是String,想改成Number,不然聚合操作时sum()函数无法使用... 所以现在想修改下这个集合中这个字段的类型,但是因为已经有很多数据了,一个个修改不显示,大佬们有什么办法能够批量修改的啊,求贴一份代码Orz...
2021-03-06 - 云开发数据库VS传统数据库丨云开发101
云开发数据库与传统数据库的不同 在小程序·云开发中,最核心的便是三大组件:数据库、云存储和云函数,从今天开始,我们将开始隔日更的专栏文章,云开发101,在第一周,我们将从最最核心的数据库开始说起。 云开发数据库简介 首先,我们先来了解一下云开发的数据库,云开发数据库是由云开发团队提供给云开发用户的数据库服务,开发者可以在小程序、云函数等环境中,通过简洁易懂的函数调用,来获取到对应的数据,方便开发者快速完成业务逻辑中关于数据库的部分。 在开发过程中,你可以使用诸如 [代码]wx.cloud.database().collection('data').where({"age":10}).get()[代码] 这样的方法获取到数据库中的信息,而无需再通过服务端提供的 API 完成数据库请求,将数据查询的权力下放到小程序端,加快应用的迭代效率。 云开发数据库底层技术简介 云开发数据库所使用的是 NoSQL (Not Only SQL)数据库方案中的 MongoDB 数据库。MongoDB 数据库是目前业界发展的最好的 NoSQL 数据库,可以让开发者以 SQL 和 NoSQL 两种方式完成数据库结构的建设,快速完成应用的开发。 NoSQL 与 SQL 我们在传统的 Web 应用开发过程中,大多使用的是 SQL 数据库,如 Oracle、SQLite、MySQL、MSSQL 等,但云开发所使用的 MongoDB 则是完全不同的数据库方案,因此,在进行数据库结构设计时,也有所不同。错误的思考模型,会使得你在后续的应用开发过程中,给自己带来无尽的麻烦。因此,也就有了我们这篇文章,向你介绍 NoSQL 世界的魅力。 Schemaless 带来的特性 在我们使用 SQL 数据库开发时我们需要先行设计好数据库的结构、数据表的结构等,而 NoSQL 型数据库,因此,让我们在开发的时候,也会有了不同的开发模式。我们无需在进行应用开发时,先行添加表结构,我们只需要根据我们自己的使用情况,随时增加、删除新的字段,完成自己的业务需求,也正是这种自由,使得云开发有了快速开发、快速迭代的特性。 云开发数据库结构设计思路 由于云开发所使用的数据库类型与我们所熟悉的数据库类型不同,因此,在开发的时候,我们也要相应的修改我们的数据库结构,以适配 NoSQL 数据库的各项特性,从而降低编程时的复杂度,又好又快的满足自己的业务需求。 和 SQL 数据库不同, MongoDB 数据库由于其存储结构从设计之初便是考虑分布式、多节点存储,其 Best Practice 是「以空间换时间」,因此,在设计应用数据结构时,不要考虑应用的数据存储空间,而是更多思考,如何以更快的速度将数据查询出来。 但是,数据库的设计不能完全追求时间,也要思考编程的复杂程度,平衡时间、空间与编程复杂度,以一个更好的方式完成自己的数据库设计。 举个例子,因为极度追求数据的空间换时间,整个数据系统的多种数据仅设计一个集合,所有的数据都挂在一个集合中,显然是不合理的,这种存储会导致应用后续的迭代造成麻烦。 同样的,极度的不追求空间换时间,也是一种错误的选择,如果你将所有的数据都放在各自的独立集合中,则会造成没有很好的利用 NoSQL 数据库的特性,也会使得你的后续编程变得麻烦。 因此,在使用云开发数据库时,我们需要思考我们的业务发展方向,将可能会用到的场景进行割离,思考应用的数据库结构,从而确保自己的应用在后续开发的时候不出问题。 云开发数据库使用常见问题 在实际的应用中,我们也看到,不少人因为不熟悉 NoSQL 的数据库设计理念,在实际开发过程中,出现了不少的问题,这里我们一一讨论一下。 自建主键属性 在 MongoDB 数据库中,数据存储使用的是 ObjectID,因此,其数据的 ID 并非 1 ,2 ,3 ,4 ,而是一个类似于 a718a0f318d76 hash 值,不少人在开发时,因为认为没有自增的数据,无法完成数据排序,就自行实现了一个自增的 ID,每次新增的时候,都重新查询一遍,获取最新的值以后, 再重新新增数据。 但实际上,我们可以有一种更加优雅和方便的工具来完成这种需求,那就是新增一个字段 created_at,这个字段的值设置为当前时间的时间戳 Timestamp。当你后续需要进行数据按新增的数据进行排序时,可以使用这个字段进行逆序排序,同时,因为这个数据使用的是当前的时间数据,你还可以将其用于数据的「创建于XX年XX月XX日」的功能,完成自己的业务需求。这个数据除了能进行直接的排序,还可以用于后续按日期导出数据,比如筛选出某一个特定时间段的数据。 相比于一个自增的 ID,created_at 更加的简单易用,同时,因为不需要提前获取上一条记录中这个字段的值,可以有效的降低数据的查询次数。 时间存储问题 在我们进行业务逻辑开发时,时间数据的获取是不可或缺的,不少人习惯于使用一个可视化的日期数据,便会将数据库中的日期字段设置为 2019-09-09,以便于在使用时直接输出到数据库中,但实际上在开发过程中,建议大家存储时间戳 Timestamp 来作为具体的时间。 这是因为 2019-09-09 的数据并非一个可以用于排序的字段,在后续开发的过程中,因为你使用的是字符串作为时间,如果你需要将数据进行排序,将会无法排序或出现排序错误的情况;此外,因为你存储的是字符串类型的时间,那么后续如果你的业务需求发生了展示形式的变化,会导致你花费大量的时间去修改所有数据的时间,或者在数据的读取和存储时进行多次格式转换,徒增麻烦。 因此,对于时间存储有需求的,我们一贯建议大家使用时间戳来存储,因为时间戳是一个数字类型的数据,因此可以直接进行大小的比对,同时,因为时间戳的数据是全球统一的,如果你的应用后续有全球化的需求,也可以很好的支持。 无法区分是否要拆分为独立的数据集合存储 在进行云开发的数据应用开发的时候,我们发现,不少开发者的疑问是,我所使用的数据,是否有必要进行独立拆分出一个 Collection 来进行数据存储。 这个问题我们可以以一些简单的问题来判断: 你所使用的数据是否有排序的需求? 你所使用的数据是否有修改的需求? 你所使用的数据除了在此处使用,是否还在其他地方使用? 这里我们举几个例子来说明一下,比如说,我们有一个需求,是为一个内容发布系统的文章新增评论功能,那么我们应该如何完成这部分呢? 如果你的评论数据没有排序、修改,也仅在此处使用,你可以考虑将评论数据放在文章数据中的一个子属性中,这样可以有效的完成数据查询,你在文章进行查询的时候,直接将评论数据查询出来,并进行显示,十分的方便。 如果你的评论数据有排序、修改以及其他地方使用的需求,那么就建议你将评论数据单独存放在一个集合中,以便在后续完成排序、更新和调用,如果此时你将其放在文章数据中,在后续查询时就会有很多问题,操作起来极为不便,给自己徒增烦恼。 当然,具体情况具体分析,如果你在分析完成后,依然没有答案,可以在公众号后台提出你的问题,我们将尽快给您回复。 总结 在本次的文章中,我们分享了云开发所使用的 NoSQL 数据库与传统的 SQL 数据库的区别,以及因为这种区别所带来的开发体验上的不同,理解这些基础内容,将会帮助你更好的应用云开发数据库开发你自己的产品。 如果你对于云开发有任何问题,都欢迎你在文章留言出留下你的疑问,我们将一一解答。 更多云开发使用技巧及 Serverless 行业动态,扫码关注我们~ [图片]
2019-09-17 - 最佳实践丨从 MySQL/MongoDB 迁移数据至 CloudBase 云数据库
迁移说明本篇文章从 MySQL、MongoDB 迁移到云开发数据库,其他数据库迁移也都大同小异。 迁移大致分为以下几步: 从 MySQL、MongoDB 将数据库导出为 JSON 或 CSV 格式创建一个云开发环境到云开发数据库新建一个集合在集合内导入 JSON 或 CSV 格式文件导出一、导出 MySQL 数据下面的流程中,我们使用 Navicat for MySQL 进行导出。您也可以使用其它 MySQL 导出工具。 1、导出为 CSV 格式 选中表后进行导出: [图片] 类型中选择 csv 格式: [图片] 注:在第 4 步时,我们需要勾选包含列的标题 [图片] 导出后的 csv 文件内容 第一行为所有键名,余下的每一行则是与首行键名相对应的键值记录。类似这样: [图片] 2、导出为 JSON 格式 同样的我们将选中的表进行导出为 json 格式: [图片] 剩余步骤全部选择默认即可。 导出后的样子: [图片] 我们将数组去除,最后是这样: [图片] 二、导出 MongoDB 数据首先我们先启动 mongod 服务: [图片] 启动后此终端不要关闭。 1、导出为 CSV 格式 新打开一个终端,输入以下命令: mongoexport -db <数据库> --collection <集合名称> --type csv -f <字段名1[,字段名2]> -o <输出的文件路径> 更详细的参数说明,请参考 MongoDB 文档。 注:导出 csv 格式时需要指定导出的列,否则会出现如下的报错信息:⚠️ csv mode requires a field list 导出后的样子: [图片] 2、导出为 JSON 格式 新打开一个终端,输入以下命令: mongoexport -db <数据库> --collection <集合名称> -o <输出的文件路径> 更详细的参数说明,请参考 MongoDB 文档。 导出后的样子: [图片] 导入1、新建云环境如果已有云环境,可直接跳过这一步打开云开发控制台新建云环境: [图片] 新建环境后耐心等待 2 分钟环境初始化过程。 2、数据库导入点击添加集合来创建一个集合: [图片] 新建之后我们点进去,并进行导入操作: [图片] 选择我们之前导出的 CSV 或 JSON 格式文件。 注意:这里有两种冲突处理模式:Insert 和 Upsert Insert 模式会在导入时总是插入新记录,同一文件不能存在重复的 _id 字段,或与数据库已有记录相同的 _id 字段。如果希望已经存在的数据不被覆盖掉,应该 Insert 模式。Upsert 模式会判断有无该条记录,如果有则更新该条记录,否则就插入一条新记录。如果不希望产生冗余重复的数据,应该使用 Upsert 模式。这里我们选择 Upsert 模式: [图片] 导入过程完毕后,数据库内可以看到导入的数据: [图片] 产品介绍云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为开发者提供高可用、自动弹性扩缩的后端云服务,包含计算、存储、托管等serverless化能力,可用于云端一体化开发多种端应用(小程序,公众号,Web 应用,Flutter 客户端等),帮助开发者统一构建和管理后端服务和云资源,避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。 开通云开发:https://console.cloud.tencent.com/tcb?tdl_anchor=techsite 产品文档:https://cloud.tencent.com/product/tcb?from=12763 技术文档:https://cloudbase.net?from=10004 【技术交流群】添加小助手微信号 Tcloudedu1,回复:技术交流 最新资讯关注微信公众号【腾讯云云开发】
2021-04-15 - 为什么云函数连接MongoDB时显示没有mongodb模块?
已经有npm install mongodb过了,还是显示没有mongodb 模块? [图片]
2021-12-07 - 米大师支付的方式可以用来在小程序内购买虚拟商品么?
因为微信和苹果的关系,之前的运营规范里,wx.requestPayment 是不允许在 IOS 里购买虚拟物品的(例如会员、道具等),最近关注到小程序支持了米大师支付的方式 wx.requestVirtualPayment,想咨询一下,通过这种方式购买虚拟物品的(例如会员、道具等)是否符合微信小程序的运营规范?
2023-11-16 - 视频号小店现在可以售卖虚拟商品(例如:会员、兑换券、兑换码等)吗?
关于视频号小店现在是否支持售卖虚拟商品(例如:会员、兑换券、兑换码等),在社区搜索到如下也没有找到答案,其他的相关问题都N年前了,特来咨询,感谢感谢 [图片]
06-03 - 虚拟业务指南请收好。
在小程序生态中,基于苹果运营规范,小程序内暂不支持iOS端虚拟支付业务。为此小编为大家整理了一份虚拟支付业务指南,希望大家在做虚拟业务时有所帮助: [视频] 那么,到底什么是虚拟支付业务呢? 虚拟支付业务是指购买非实物商品。比如:VIP会员、充值、录制课程、录制音频视频等虚拟产品。目前iOS端暂不支持虚拟支付业务。 我们常见iOS虚拟支付的不合规示例有哪些呢? 示例一 :小程序内存在付费购买虚拟内容或道具。商品多体现为提前编辑好的、录制好的虚拟商品。如录制视频课程、游戏道具。 整改建议 :建议去除小程序内所有付费购买虚拟服务,并根据提示修改相关内容及文案,文案可参照“由于相关规范,iOS功能暂不可用”。 [图片] 示例二 :付费解锁优质服务。多体现为提供虚拟商品的小程序可通过支付购买、开通虚拟会员等形式,体验小程序付费服务。比如:支付阅读章节小说、同城生活服务平台付费发帖/付费置顶等。 整改建议 :建议可以关闭iOS端虚拟支付通道,并将【马上充值】更改为【由于相关规范,iOS功能暂不可用】,并不再提供iOS端会员服务。 [图片] 示例三 :关闭iOS端虚拟支付功能后,虚拟商品页面仍然保留货架价格标签展示、购买/付费/订阅等功能或按钮。 整改建议 :建议去除小程序中的虚拟商品的价格展示,并更改为【免费】;并将【订阅 ¥128】更改为【由于相关规范,iOS功能暂不可用】,并不再提供iOS端虚拟商品购买服务。 [图片] 示例四 :关闭iOS端虚拟支付功能后,提供引导用户前往其他支付的路径/文案,完成虚拟支付闭环。 整 改建议 :建议去除iOS端小程序内引导用户前往其他支付路径/文案,并不再提供iOS端虚拟商品购买服务。 [图片] 示例五 :小程序含需要付费的虚拟商品,并设置限时免费的服务,限时免费结束后需付费才能继续提供服务。 整改建议 :建议将iOS端小程序中所有虚拟付费内容更改为免费,并不再提供iOS端虚拟商品购买服务。 [图片] 示例六 :关闭iOS端虚拟支付功能后,小程序中虚拟产品页面不可以含有付费性质的关键字(如:购买、已购、付费、支付等),包括但不限于功能按钮、功能页面、支付提示及任何商品介绍等。 整改建议 :建议将小程序iOS端虚拟产品页面中的文案/按钮/功能tab含有限制的关键字更改为【免费】或删除。并不再提供iOS端虚拟商品购买服务。 [图片] 如小程序内存在以上不合规的虚拟支付内容,请开发者重视并及时整改。对于首次违规的小程序,平台将下发站内信整改通知,并给予三天整改时间,请开发者按照提示在限期内完成整改。平台将会对到期未完成整改的小程序进行搜索策略调整,并在小程序功能使用上进行一定的限制,直到小程序完成内容整改。
2020-04-23 - 举报群报数小程序通过赠送用户会员的方式刷好评?
appid:wxfc4ef6d539d03373 小程序名称:群报数丨接龙报名预约统计 该小程序通过引导用户给小程序刷五星好评,然后给予用户会员奖励,严重影响了小程序的生态,请求微信官方对该小程序予以封禁处理 以下是该小程序发的活动截图 [图片][图片]
06-19 - 更新云数据库中 某一条记录 满足条件的数组 中的值?
[图片] 官方示例看懂了,但是 如果要更新 该记录中 符合 条件的数组中的某一条记录的 某一个值 如 条件是math数组中的 examid=3 ,更新它的 score为 50 该如何写更新语句呢?请大神们指导下,万分感谢
05-07 - 允许第三方应用运行权限,关闭后再次开启,却无法在QQ上运行?
如题,请问大家怎么解决的?
06-18 - 用户没几个,为什么调用次数这么多?
每天没几个用户,openid只在首页调用云函数获取过一次,其他页面跳转都是传参,为什么“调用次数”还这么多? [图片]
04-20 - 省钱有道之 减少云函数调用次数
由于云函数有一项计费规则是按调用次数计费,在小程序访问量比较小的情况下还比较无所谓,但当体量上来之后不得不考虑控制一下对公共接口的调用次数从而减少一些不必要的开销。比如获取用户信息接口、获取配置信息接口 这里分享一个我自己几个小程序用到的方法,公共接口的调用都放在app.js,然后提供函数供其他页面调用。同时由于异步问题,有可能页面加载完接口还未返回,因此还需能够注册回调函数,在接口返回数据后回调给调用页面 代码示例: app.js App({ onLaunch: async function (options) { //判断是否需要更新小程序 updateCheck.check(); await api.wxCloudInit(); //获取用户信息 this._getUserInfo().catch(res => { console.warn("获取用户信息失败,准备重试"); this._getUserInfo().then(); }); }, /** * 获取用户信息 * @param callback * @param refresh 等于true时表示重新查询用户信息,同时也会更新会员状态 */ getUserInfo: function (callback, refresh) { if (!refresh) { const userInfo = this.globalData.userInfo; if (!userInfo.ready) { if (typeof callback == 'function') { this.callbackFunctions.userInfoReadyCallback.push(callback); } if (!this.userInfoReadyCallback) { this.userInfoReadyCallback = res => { console.log("获取用户信息完毕,开始回调", res); const callbacks = this.callbackFunctions.userInfoReadyCallback; while (callbacks.length) { const callback = callbacks.pop(); typeof callback == 'function' && callback(res); } /*callbacks.forEach(callback => { typeof callback == 'function' && callback(res); })*/ } console.log("注册userInfoReadyCallback成功"); } else { console.log("已经注册了userInfoReadyCallback,不再重复注册"); } } else { typeof callback == 'function' && callback(userInfo); } } else { console.log("准备更新用户信息") this._getUserInfo().then(userInfo => { typeof callback == 'function' && callback(userInfo); }); } }, /** * 执行云函数,获取用户信息 * @returns {Promise<unknown>} * @private */ _getUserInfo: function () { return new Promise((resolve, reject) => { api.callCloudUserCenterFunction("UserInfoHandler/getUserInfo", {}, res => { console.log("获取用户数据完毕:", res.result); const result = res.result; if (result.success) { const data = result.data; this.globalData.userInfo = data; // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(data); } resolve(data); } else { console.error("没有获取到用户信息"); reject("没有获取到用户信息"); } }, e => { console.error("获取用户信息失败", e); reject("获取用户信息失败"); }); }); }, /** * 异步事件回调函数列表 * 增加这个列表是为了避免不同地方同时调用,互相覆盖回调函数 */ callbackFunctions: { //用户信息异步回调 userInfoReadyCallback: [], }, globalData: { userInfo: { confirm: false//用来标记用户信息查询动作是否已经结束,等于true时,userInfo才可信 }, } }) 某page.js app.getUserInfo(res => { const isVip = res.isVip; if (isVip) { console.log("已开通会员", res); } });
02-07 - wx.navigateTo() 出现警告[Deprecation] ?
[Deprecation] SharedArrayBuffer will require cross-origin isolation as of M92, around July 2021. See https://developer.chrome.com/blog/enabling-shared-array-buffer/ for more details. e.onmessage @ worker.js?libName=WAAccelerateWorker.js:1 [worker] reportRealtimeAction:fail not support e.workerInvokeJsApi @ worker.js?libName=WAAccelerateWorker.js:1 (anonymous) @ WAWorker.js:2 k @ WAWorker.js:2 invoke @ WAWorker.js:2 f @ WAWorker.js:2 (anonymous) @ WAWorker.js:2 re @ WAWorker.js:2 y @ WAWorker.js:2 l @ WAWorker.js:2 (anonymous) @ WAWorker.js:2 (anonymous) @ WAWorker.js:2 setTimeout (async) globalThis.setTimeout @ WAWorker.js:2 (anonymous) @ WAWorker.js:2 Q @ WAWorker.js:2 (anonymous) @ WAWorker.js:2 (anonymous) @ WAWorker.js:2 S @ WAWorker.js:2 eval @ VM10:1 e.onmessage @ worker.js?libName=WAAccelerateWorker.js:1
2022-06-21 - 小程序云开发如何修改node.js版本?
worker_threads 在node.js 10.50后才提供,小程序云函数环境无法自主升级,也无法加试验性前缀,这个有解决办法吗?
2021-03-29 - 云函数报错Error: Cannot find module 'node:stream'?是什么原因
云函数执行报错:Error: Cannot find module 'node:stream' Require stack: 是缺少模块stream吗?[图片]
08-14 - 请教一下如果修改云函数的nodejs版本
我更新了一个最新的云函数,它的node.js的版本变成了16.13,一直报错,当我把同样的代码复制进之前旧的云函数,nodejs的版本还是12.16的云函数运行时,它就是正确的,我反复看了代码,没得问题,你们这个太不稳定了啊,最关键的是我还不能选node.js的版本,最新提交的全是16.13.这怎么也敢用于生产环境啊, 我实在受不了,这么多BUG.代码里好多兼容你们的BUG的代码.这么大的公司,为什么会这么多错误 [图片] 云函数代码如下: const cloud = require('wx-server-sdk'); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); const db = cloud.database(); const _ = db.command; async function cleanUnusedImages(info) { try { // 查询 fileIds 表,最多查询10条数据 const { data: list } = await db.collection(info[0]) .where({ updateTime: _.lt(new Date(Date.now() - 1000 * 60 * 60 * 12)) // 图片记录超过12小时 }) .limit(10) .orderBy("updateTime", "asc") .get(); console.log("查询结果:", list); for (const item of list) { const { data: resList } = await db.collection(info[1]) .where({ fileIds: item.fileId }) .limit(1) .get(); if (resList.length === 0) { await cloud.deleteFile({ fileList: [item.fileId], }); // 文件删除成功,删除当前记录 await db.collection(info[0]).doc(item._id).remove(); } else { // 当前文件仍在使用中,修改当前记录的修改时间 await db.collection(info[0]).doc(item._id).update({ data: { "updateTime": db.serverDate() } }); } } console.log("定时清理未被使用的图片执行成功!" + info.toString()); } catch (error) { console.error("执行出错:", error); throw error; } } exports.main = async (event, context) => { // 随机获取要执行的表 const FileIdsTables = [ ["houseFileIds", "houseResources"], ["roomFileIds", "houseRoom"], ["contractFileIds", "contract"], ]; const index = Math.floor(Math.random() * 3); const info = FileIdsTables[index]; await cleanUnusedImages(info); console.log("删除未被使用的图片执行成功!") };
2023-09-18 - 小程序推荐图表库uchart
话说这三个图表库,我都有用过,echart,wx-chart,ucharts, wx-chart由于个人目前没有维护了,echart,总的来说,还是更倾向于pc,而ucharts就不一样了,他的诞生,就是为小程序而生的,他是伴随小程序跨端框架uni-app而来的,所以uchart更小程序更具有一种天然的属性。 ----- 高性能跨平台图表库,支持H5图表、APP图表、小程序图表(微信小程序、支付宝小程序、百度小程序、头条小程序、QQ小程序、360小程序),支持饼图、圆环图、线图、柱状图、区域图、雷达图、圆弧进度图、仪表盘、K线图、条状图、混合图、玫瑰图、漏斗图、词云图、地图。 首页 https://www.ucharts.cn 码云主页 https://gitee.com/uCharts/uCharts 扫码体验地址 [图片] - - - - - - - - - - - - - - - - H5端流行的echart报表因为涉及大量dom操作,无法跨端使用,而wx-chart在跨端和更新方面都不足,如果要做小程序,推荐使用全端可用的[uChart](https://ext.dcloud.net.cn/plugin?id=271)。 - 如只考虑H5端,也可以继续使用echart、f2等常规web图表。 - 如不考虑小程序,那么App端和H5,还可以通过renderjs技术来使用echart、f2等web图表,功能性能比uchart更好。[什么是renderjs](https://uniapp.dcloud.io/frame?id=renderjs)、[基于renderjs使用echart的示例](https://ext.dcloud.net.cn/plugin?id=1207)
2020-04-12 - 微信小程序引导关注公众号?
我想在我的小程序中引导用户去关注一个不同主体的公众号,我已经在微信开放平台中放入了小程序和公众号,但是在小程序后台引导关注公众里搜索不到公众号信息,让在开放平台绑定
05-09 - 开发者工具 无法格式化文档
开发者工具中右键点击格式化文档无效,没有任何反应 换一个项目就没有问题
2023-02-02 - 云开发聚合查询Aggregate时match中无法比较Date?
已经试过传入new Date()或者db.serverDate(),均不行。 看文档里聚合操作match的时候不支持聚合操作符,我也把$改为_试过,直接报错 [图片] 最后是下面的代码,可以看后面的查询结果,我特地和collection().get()进行了比较,后者是能正常返回数据的,而前者返回空集,请问大家一般这样是怎么处理的 return { code: 200, list: await db.collection('task').aggregate().match({ available: true, begin_time:$.lte(db.serverDate()) }).end(), list1:await db.collection('task').where({ available: true, begin_time:_.lte(db.serverDate()) }).get() } [图片]
2020-04-18 - 云开发数据库按条件抽取聚合aggregate().match()的问题?
不知道有没有更好一点的按条件抽取的方法 这个聚合方便是方便,但是由于代码有点复杂, 耗费的时间有点长 望有经验的各位给予一点建议
04-23 - 记录云开发lookup多表嵌套查询优化
最近在优化一个云开发用lookup实现的多表嵌套查询SQL,发现测试环境最大的表数据量还不到2W,但是整体查询耗时竟然要2,3s,这让我觉得有些意外,能加的索引也都加了,有点头大。。。 主要是以下几个表: user-card-list(清单表,大概1.9W条)user-comment(评论表,大概500条)user-info(用户信息表,大概9000条)black-list(黑名单表,12条)具体的业务是分页查询出清单,并关联出发布清单的用户信息、清单评论信息、评论者的用户信息,同时过滤掉黑名单用户。在测试SQL的过程中发现在pipeline中用到的父表字段其实不会使用索引,如果是用localField/foreignField关联表时索引可以生效,但是遗憾的是这种方式不可用嵌套查询... 写惯了关系型数据库SQL,通常是会把分页以及过滤条件写在SQL最后的位置。但是在非关系型数据库,如果尽量把过滤条件或者分页的SQL前置,可能会有意想不到的效果。 下面的这个SQL我把match跟limit前置后查询速度从2,3s降到了3,400ms,有点苦笑不得[捂脸]。。 在这里蛮记录一下。或许对看到的小伙伴可以有一点点小启发。 db.collection('user-card-list').aggregate() .lookup({ from: 'black-list', let: { openid: '$openid'//将变量openid的值等于user-card-list表的openid,在pipeline可以使用,let需要和pipeline一起使用 }, pipeline: $.pipeline() .match(_.expr($.and([ $.eq(['$openid', '$$openid']), ]))) .done(), as: 'blackList', }) .addFields({ inBlackList: $.gt([$.size('$blackList'), 0]), //排序字段,由公开时间+ID组成 cursor: $.concat(['$lightAt', '', '$_id']), }) .match(_.expr($.and( $.eq(['$light', 'Y']), //$.gt(['$cursor', '2023-05-20 23:58:23ozzW05Gch7jMMhsn1r_SWLGdGtF0_add_1563634289607']) $.or([ //当前清单的发布用户不在黑名单中,直接展示 $.eq(['$inBlackList', false]), //当前清单的发布用户在黑名单中,且是本人浏览时,直接展示 $.and([ $.eq(['$inBlackList', true]), $.eq(['$openid', 'ozzW05Gch7jMMhsn1r_SWLGdGtF0']), ]) ]) ))) //按cursor降序排序 .sort({cursor: -1}) //分页前置,提升查询速度 .limit(30) .lookup({ from: 'user-comment', let: { id: '$_id'//将变量id的值等于user-card-list表的_id,在pipeline可以使用,let需要和pipeline一起使用 }, pipeline: $.pipeline() .match(_.expr($.eq(['$belongTo', '$$id']))) //按createAt降序 .sort({createAt: -1}) .lookup({ from: 'user-info', let: { replyOpenid: '$replyOpenid'//将变量replyOpenid的值等于user-comment表的replyOpenid,在pipeline可以使用,let需要和pipeline一起使用 }, pipeline: $.pipeline() .match(_.expr($.eq(['$openid', '$$replyOpenid']))) .done(), as: 'replyUserInfoList', }) .done(), as: 'userCommentList', }) .project({ momentContent: 1, author: 1, cursor: 1, lightAt: 1, comments: $.reverseArray('$commentsReverse'), userCommentList: 1, likes: 1, wishes: 1, time: '$lightAt', }) .end();
2023-05-26 - 关于云开发数据库日期比较条件返回错误结果的问题?
现在是北京时间2024年3月14日早上10:39,微信小程序数据库的以下这条语句: db.collection('waihuhaoma') .where( {start_date:_.gt(new Date())} ) .get() 搜索出: [ { "_id": "63cb1eba65f254e90313d8c14c8bc627", "end_date": "2024-03-20T08:00:00.000Z", "start_date": "2024-03-14T08:00:00.000Z", } ] , db.collection('waihuhaoma') .where( {start_date:_.lt(new Date())} ) .get() 搜索不出结果 。
03-14 - video组件的custom-cache属性有什么效果。
ios中视频组件会卡loading加载不出来,加了custom-cache="{{false}}"就好了。有没有大神知道custom-cache属性有什么效果?
2018-11-22 - 两个云开发的微信小程序是否可以共用数据?
同一个主体,用云开发方法开发两个小程序,是否可以共用数据?一个小程序专注产品开发设计,另一个专注产品的用户体验,有一部分数据要在两个小程序之间传递。
2022-08-24 - 同一页面存在多个video时,video无法正常播放一直在加载转圈
不建议同个页面使用多个video组件,建议不超过3个video,如果要实现video列表功能,请进行优化(image列表,选中时将image替换成video)
2019-08-29 - 为什么这两个域名downloadFile很多失败?wxs.qq.com
这几个调用失败的接口,是广告组件里的吗,为什么调用失败这么多? [图片]
05-13 - we分析出现大量downloadFile请求错误的统计?
如下图,we分析再现大量downloadFile错误,错误代码600007(超过最大请求数量)。业务代码里没有频繁downloadFile。 [图片]
2023-11-14 - channel-video同主体,如何点击播放而不跳转到视频号的?
如题,同主体,不设置自动播放,如何点击播放而不跳转?
05-27 - 小程序video组件如何加载 使用第三方上传的带有referer防盗链的视频
目前video组件暂不支持设置referer防盗链,计划支持中。
2020-04-20 - 隐私弹窗拒绝,后还可以再调起地理位置确认弹窗吗?
拒绝隐私授权后直接提示我authorize:fail privacy permission is not authorized,或"getLocation:fail privacy permission is not authorized;
2023-12-13 - 服务号今年付费300认证通过后,为什么小程序还得二次年审?缴费?
服务号今年付费300认证通过后,为什么小程序还得二次年审?缴费?,我记得往年只需要付费主体公众号就行,小程序直接服用主体公众号就行,不用二次付费,我今年付费主体公众号后,小程序还是提示付费?有啥办法不?
02-07 - webview无法打开关联公众号的专辑链接
暂不支持
2020-09-01 - 希望云开发数据库支持 distinct 去重
- 需求的场景描述(希望解决的问题) 现在只能自己取出所有数据,一条条循环比对才能去重,太过消耗资源浪费时间 - 希望提供的能力 希望云开发数据库支持 distinct 去重
2019-07-07 - 现在微信小程序还能做SEO吗?
逛了一圈开放社区,了解到 页面内容提交下架, SEO内容接入页面API接入下架,API文档关闭了 自定义关键词下架, 发现、下拉搜索小程序,不展示内容结果 模糊搜索,也不一定能搜到,精准搜索,也不是都排在第一 SEO优化指南3年未更新 还有什么方向能去做SEO吗?
2023-02-03 - 微信云开发计费调整调用次数怎么算?
这四个统一归到调用次数了吗?每天多支出100+。。。。。 https://developers.weixin.qq.com/community/minihome/doc/0000a680588d3891fa2ec250c51401?page=1 [图片]
2022-07-13 - 视频号扩展链接提示该文章链接包含小程序无法添加?
如题,之前是OK的,今天突然就不让添加了,这是为什么呢?
2022-09-06 - 小程序no such file or directory, access问题?
error occurs:ENOENT: no such file or directory, access '/storage/emulated/0/ 一直报错,求教如何解决,谢谢!
2022-04-18 - 企业微信群二维码获取接口
希望能够有一个群二维码获取的接口,我们的场景是会定期,比如故障拉群处理,并且将二维码分享出来,可以让想了解故障处理进度的人,自行扫码进来。希望能够有 API 支持获取当前群二维码的功能
2020-03-19 - 微信云开发计费调整公告
各位微信云开发用户: 感谢大家一直以来对微信云开发的支持。由于云计算成本整体上升,为了继续为各位用户提供稳定可靠的服务,微信云开发将于 2022 年 08 月 18 日,对计费方式进行如下变更,部分指标价格将有所上浮。 新计费模式下,新用户免费使用 1 个月后,统一使用 “基础套餐+按量付费” 模式:购买带有一定配额的基础套餐后,超出套餐配额部分再按照实际使用量付费。 基础套餐 [图片] *新用户首月免费配额:与基础套餐一致,可满足大部分情况下的开发体验需求 *5 折折扣有效期至少延续至 2022 年底,后续折扣如有变化将另行通知 按量付费 [图片] 【指标说明】 1、调用次数:合并原多项指标统一计价,具体为 “云存储上传操作”、“云存储下载操作”;“数据库读操作”、“数据库写操作” 及新增指标 “云函数调用操作”; 2、容量:合并原多项指标统一计价,具体为 “存储空间" 及 "数据库容量"; 3、云函数日志服务:本次新增计费指标,建议通过优化日志存储策略降低该指标费用。 新用户手动触发确认开始使用后,将拥有 1 个月免费权益,体验期间的环境配额与基础套餐相同,可选择是否进行超额按量付费。 现有用户可以在「微信开发者工具-云开发控制台」或「微信云服务助手小程序」查询过往用量情况后,使用 价格计算器 预估新价格。 在计费方式升级生效之日(2022.08.08)起,对现有用户均提供至少 1 个月的操作缓冲期,期间会推送提醒及提供切换入口,用户可自由选择是否切换新的计费方式,超时未切换的云开发环境将会停服释放。缓冲期内切换成功的用户将会获得额外代金券。 对于当前月调用次数 >100 万次的帐号,本次调整将不直接生效,后续将由专业架构师联系或独立推送指引切换到合适配额的企业旗舰版本。 自本公告发布之日起,对于原已购预付费套餐、资源包的用户,仍然可正常使用原已购资源,直至原约定套餐到期或用完。现有旧预付费套餐不再支持续费超过一个月,现有旧资源包不再支持新购。 微信云开发将继续为各位用户提供简单易用安全的专业 Serverless 开发服务,感谢大家的支持。 Q&A 1、此次调整,意味着我的费用会增加吗? 是的,由于云计算整体成本的持续上升,为了能够长期给各位开发者提供低门槛的开发服务,我们对于部分计费指标进行了价格调整,在调整后大部分的开发者费用会一定程度的上浮。 2、我如何预估调整之后的费用是多少呢? 新计费生效后,在缓冲期内,开发者可查看新指标下的用量情况,或者根据过往用量,使用 价格计算器 估算调整之后的费用。 我们根据测算,为大部分开发者提供基础套餐配额以满足线上服务,如你的实际用量没有超过基础配额,也没有使用扩展功能,那么每月消费即为 19.9 元。 3、我需要在哪里操作切换新计费呢? [图片] 微信云服务助手小程序码 在计费方式升级生效之日(2022.08.08)起,开发者可前往「微信开发者工具-云开发控制台」或「微信云服务助手小程序」进行操作切换。按照过往的计费信息下发惯例,我们通过「微信公众平台公众号」向管理员推送计费变更信息与切换入口。 4、现在的环境是否可以继续使用呢? 新计费生效后,已购买的预付费套餐可正常使用至原到期时间,已购买资源包的按量付费环境可正常使用至原资源包到期时间,均不会存在直接失效或自动退费的情况。在切换到新计费方案后,原有环境即可持续正常使用。 5、如果超时切换会有什么影响呢? 若原环境到期且超出切换缓冲时间,则该环境将进入停服释放流程,数据不可找回,请开发者及时操作。 6、以上新计费方案生效后,我有多长时间可以决定是否继续使用云开发呢? 对于当前月调用次数 <100 万次的帐号,从公告发布日至新方案生效后的一个月,期间可进行是否继续使用的决策;计费方式升级生效之日(2022.08.08)起,我们也会通过上述 Q&A 3 说明的方式中提供切换入口与下发消息,此时你仍然有至少 1 个月的缓冲期做出决定。对于当前月调用次数 >100 万次的帐号,将有专业架构师联系指引切换到合适配额的企业旗舰版本,期间产生的消耗仍然按旧方案计费。我们会为大额消耗用户提供适当优惠,同时对于不希望继续使用云开发的此类帐号提供不低于 3 个月的缓冲时间。如有其他问题,可前往「微信开发者工具-云开发控制台-帮助-工单」主动联系我们。 7、我自行测算预估后觉得新方案有点贵,有什么好建议吗? 本次调整,价格上涨指标为 “调用次数”、“容量”和“CDN 流量”,建议相应进行技术优化,减少不必要的多次调用或存储内容,可有效控制费用;此外新增计费指标为日志服务,可在「微信开发者工具-云开发控制台-云函数-日志」中查看日志使用情况,并优化日志使用逻辑,避免上报大量冗余的日志信息导致不必要的费用支出。 若评估后认为新的费用方案已不适用于你的业务,可在上述充足的缓冲期内自行选择迁移业务至更合适的服务。 微信云开发团队 2022年7月4日
2022-08-08 - 小程序地理位置相关接口调整
为进一步规范开发者调用涉用户信息相关接口或功能,保障用户合法权益,平台将对如下地理位置相关接口调用实行准入开通: wx.getLocation、wx.onLocationChange、wx.chooseAddress、wx.chooseLocation、wx.choosePoi 自2022年4月18日开始,如使用以上接口,在代码审核环节将检测该接口是否已完成准入开通(申请路径:小程序管理后台 -「开发」-「开发管理」-「接口设置」),如未开通,将在代码提审环节进行拦截,请涉及相关接口的开发者尽快进行接口权限申请,第三方开发者申请方式:可通过 apply_privacy_interface 接口完成。 请广大涉及相关接口的开发者尽快进行相关接口准入申请,如未申请,后续将影响线上小程序相关接口的使用。
2023-09-26 - 数字文本中含有数字1的文本在ios上的表现和安卓不一致,数字未对齐,详见截图
- 当前 Bug 的表现(可附上截图) 设备:iPhone Xs 问题:数字文本中含有数字1的文本在ios上的表现和安卓不一致,数字未对齐。通过硬编码,对文本数字中含有数字1的文本添加类名,给其数字增加间距,也不行。 [图片] [图片] - 预期表现 以下为安卓机上表现: 安卓表现正常 [图片] - 复现路径 - 提供一个最简复现 Demo
2019-07-16 - 在云函数中可以调用fs.readFile和fs.writeFile来读写文件吗?
在云函数中可以调用fs.readFile和fs.writeFile来读写文件吗? 我试了一下,报错如下: 日志 START error when writing file: { "errno": -30, "code": "EROFS", "syscall": "open", "path": "/var/user/node_modules/ffprobe-static/bin/linux/x64/temp.mov" }
2021-11-23 - 添加到我的小程序引导组件
出发点 开发了一个小程序,经过一段时间的观察,发现访问人数和添加到我的小程序的数据差异比较大,我想可能存在2种可能: 用户不清楚有添加到我的小程序功能 本身产品做的不够好,不愿意添加 那为了验证可能性,我就做了这个引导添加的提示组件,组件开发非常简单,这里分享给大家。 代码实现 制作一张gif动图或者静态提示图片也行 [图片] wxml布局如下 [代码]<view wx:if="{{showTip}}" class="tip-wraper"> <image class="tip-gif" mode="widthFix" src="./images/add_tip.gif"></image> <image bindtap="closeTip" class="tip-close" src='./images/close.png'></image> </view> [代码] js代码如下 [代码]methods: { // 初始化关注提示 initTip() { let showTip = wx.getStorageSync('showTip') this.setData({ showTip: typeof showTip=='boolean'?showTip:true }) }, // 关闭提示 closeTip() { wx.setStorageSync('showTip', false) this.setData({ showTip: false }) } }, lifetimes:{ attached:function(){ this.initTip() } } [代码] [图片] 结果 上线2天后,发现添加人数相比之前是倍数增长,这也就验证了产品本身其实没有什么大问题,大多数用户是不知道这个功能,或者说用户的行为需要我们去小小的引导一下,就能产生意想不到的收获。 组件源码在minicode-debug项目的[代码]/add-tip[代码]目录下,可直接拿去复用或者参照修改。
2021-03-10 - 微信小程序中的多个空格怎么打?
微信小程序中的多个空格怎么打?  不行。
2017-02-04 - 哪个接口可以实时获取“今日活跃用户”?
云开发控制台中可以实时查看“今日活跃用户”,如下图。请问各位大师,调用哪个接口可以获取这个数据呢? [图片]
2021-09-29 - 你知道流量主的ECPM吗?扫盲篇
ECPM:千次曝光收益。他不是指单纯的曝光1000次的收益。具体是指1000次曝光里,有多少人点击产生的收益,才叫千次曝光收益。 也就是说ECPM和点击率有强关联性。(不单单指小程序流量主,是针对所有平台都是这么计算) 假设1:你的流量主曝光了1000次,一个人都没点击,你的收益是0,即ECPM=0 假设2:你的流量主曝光了1000次,只有一个人点击,再假设每个点击均为1元(具体数值取决于广告主投放的价格)。那么你这1000次曝光给你收益就是1元,即ECPM=1 假设3:你的流量主曝光了1000次,有100人点击,再假设每个点击均为1元(具体数值取决于广告主投放的价格)。那么你这1000次曝光给你收益就是100元,即ECPM=100 假设4:你的流量主曝光了1000次,只有一个人点击,这个用户实质性的转化为广告主的用户(比如购买商品、充值、关注公众号等),那么这个用户可能给你带来的收益是30,那么你这1000次曝光给你收益就是30元,即ECPM=30 假设5:你的流量主曝光了1000次,有100人点击,这100个用户实质性的转化为广告主的用户(比如购买商品、充值、关注公众号等),那么这100个用户可能给你带来的收益是3000,那么你这1000次曝光给你收益就是3000元,即ECPM=3000(这种情况几乎不会出现) 以上就是ECPM的扫盲。下面凑个原创文章多说一些,看破不说破,还能做朋友。 1、流量主的收益取决于广告主的广告内容、广告投放方式、受众群体、投放城市等有关。 2、正常1个人,1天从你这看5个广告,点击2次,那么这个是正常的,点击率在这个用户上是40%,你可以拿100%的流量主费用。但一个用户点击很多次,接近于100%点击必然会有问题,会在你最终收入中扣除一定比例。 3、你看到的流量主收益日报是基于昨天的单用户统计+总用户统计,微信做出最终的收益计算。 4、正常用户正常看广告,点击率大概在3%左右(常见数值),点击率高、超过大盘均值必然有问题(常见情况:流量主以不正当方式制造虚假或无效曝光量、点击量,轻则1-30天关闭广告展示,重则永久关闭) 5、如果有一天流量主点击特别高了,超出预期也别着急,可能投广告的人铺设的地域,和你的用户地域非常吻合。 6、针对一些互点群、刷广告等,不要做幻想靠广告发大财,这是硬生生从微信嘴里刨食啊,微信能坐视不管?正常运营流量主,你赚你的,广告主赚广告主的,微信赚微信的,这叫生态平衡,广告主和微信都不傻。 7、好好经营小程序,给身边的朋友多宣传宣传自己的小程序,指数自然增长,不出2年,肯定能日广告费赚百元以上稳稳的。 共建微信生态,造福你我他。
2021-04-08 - 为什么我的所有微信小程序的游戏都看不了广告?
我在玩微信小游戏时看不了广告,别人都可以看。 后来有一个朋友他也看不了,和我情况一样,他截图给了那个‘投诉与反馈’结果他第二天就可以看了,我也同样做了可是依旧看不了。
2019-08-01 - 自定义tabbar 【恋爱小清单开发总结】
看官方demo的小伙伴知道,自定义tabbar需要在小程序根目录底下建一个名叫custom-tab-bar的组件(我有试过,如果放在components目录里面小程序会识别不了),目前我自己实现的效果是:通过在配置可以切换tab,也可以点击tab后重定向到新页面,支持隐藏tabbar,同时也可以显示右上角文本和小红点。 官方demo里面用的是cover-view,我改成view,因为如果页面有弹窗的话我希望可以盖住tabbar 总结一下有以下注意点: 1、tabbar组件的目录命名需要是custom-tab-bar 2、app.json增加自定义tabbar配置 3、wx.navigateTo不允许跳转到tabb页面 4、进入tab页面时,需要调用tabbar.js手动切换tab 效果图: [图片] 可以扫码体验 [图片] 代码目录如下: [图片] 代码如下: app.json增加自定义tabbar配置 "tabBar": { "custom": true, "color": "#7A7E83", "selectedColor": "#3cc51f", "borderStyle": "black", "backgroundColor": "#ffffff", "list": [ { "pagePath": "pages/love/love", "text": "首页" }, { "pagePath": "pages/tabbar/empty", "text": "礼物说" }, { "pagePath": "pages/tabbar/empty", "text": "恋人圈" }, { "pagePath": "pages/me/me", "text": "我" } ] }, 自定义tabbar组件代码如下 index.js //api.js是我自己对微信接口的一些封装 const api = require('../utils/api.js'); //获取应用实例 const app = getApp(); Component({ data: { isPhoneX: false, selected: 0, hide: false, list: [{ showRedDot: false, showBadge: false, badgeText: "", pagePath: "/pages/love/love", iconPath: "/images/tabbar/home.png", selectedIconPath: "/images/tabbar/home-select.png", text: "首页" }, { showRedDot: false, showBadge: false, badgeText: "", pagePath: "/pages/tabbar/empty", navigatePath: "/pages/gifts/giftList", iconPath: "/images/tabbar/gift.png", selectedIconPath: "/images/tabbar/gift-select.png", text: "礼物说", hideTabBar: true }, { showRedDot: false, showBadge: false, badgeText: "", pagePath: "/pages/tabbar/empty", navigatePath: "/pages/moments/moments", iconPath: "/images/tabbar/lover-circle.png", selectedIconPath: "/images/tabbar/lover-circle-select.png", text: "恋人圈", hideTabBar: true }, { showRedDot: false, showBadge: false, badgeText: "", pagePath: "/pages/me/me", iconPath: "/images/tabbar/me.png", selectedIconPath: "/images/tabbar/me-select.png", text: "我" }] }, ready() { // console.error("custom-tab-bar ready"); this.setData({ isPhoneX: app.globalData.device.isPhoneX }) }, methods: { switchTab(e) { const data = e.currentTarget.dataset; console.log("tabBar参数:", data); api.vibrateShort(); if (data.hideTabBar) { api.navigateTo(data.navigatePath); } else { /*this.setData({ selected: data.index }, function () { wx.switchTab({url: data.path}); });*/ /** * 改为直接跳转页面, * 因为发现如果先设置selected的话, * 对应tab图标会先选中,然后页面再跳转, * 会出现图标变成未选中然后马上选中的过程 */ wx.switchTab({url: data.path}); } }, /** * 显示tabbar * @param e */ showTab(e){ this.setData({ hide: false }, function () { console.log("showTab执行完毕"); }); }, /** * 隐藏tabbar * @param e */ hideTab(e){ this.setData({ hide: true }, function () { console.log("hideTab执行完毕"); }); }, /** * 显示小红点 * @param index */ showRedDot(index, success, fail) { try { const list = this.data.list; list[index].showRedDot = true; this.setData({ list }, function () { typeof success == 'function' && success(); }) } catch (e) { typeof fail == 'function' && fail(); } }, /** * 隐藏小红点 * @param index */ hideRedDot(index, success, fail) { try { const list = this.data.list; list[index].showRedDot = false; this.setData({ list }, function () { typeof success == 'function' && success(); }) } catch (e) { typeof fail == 'function' && fail(); } }, /** * 显示tab右上角文本 * @param index * @param text */ showBadge(index, text, success, fail) { try { const list = this.data.list; Object.assign(list[index], {showBadge: true, badgeText: text}); this.setData({ list }, function () { typeof success == 'function' && success(); }) } catch (e) { typeof fail == 'function' && fail(); } }, /** * 隐藏tab右上角文本 * @param index */ hideBadge(index, success, fail) { try { const list = this.data.list; Object.assign(list[index], {showBadge: false, badgeText: ""}); this.setData({ list }, function () { typeof success == 'function' && success(); }) } catch (e) { typeof fail == 'function' && fail(); } } } }); index.html <view class="footer-tool-bar flex-center {{isPhoneX? 'phx_68':''}}" hidden="{{hide}}"> <view class="tab flex-full {{selected === index ? 'focus':''}}" wx:for="{{list}}" wx:key="index" data-path="{{item.pagePath}}" data-index="{{index}}" data-navigate-path="{{item.navigatePath}}" data-hide-tab-bar="{{item.hideTabBar}}" data-open-ext-mini-program="{{item.openExtMiniProgram}}" data-ext-mini-program-app-id="{{item.extMiniProgramAppId}}" bindtap="switchTab"> <view class="text"> <view class="dot" wx:if="{{item.showRedDot}}"></view> <view class="badge" wx:if="{{item.showBadge}}">{{item.badgeText}}</view> <image class="icon" src="{{item.selectedIconPath}}" hidden="{{selected !== index}}"></image> <image class="icon" src="{{item.iconPath}}" hidden="{{selected === index}}"></image> </view> </view> </view> index.json { "component": true, "usingComponents": {} } index.wxss @import "/app.wxss"; .footer-tool-bar{ background-color: #fff; height: 100rpx; width: 100%; position: fixed; bottom: 0; z-index: 100; text-align: center; font-size: 24rpx; transition: transform .3s; border-radius: 30rpx 30rpx 0 0; /*padding-bottom: env(safe-area-inset-bottom);*/ box-shadow:0rpx 0rpx 18rpx 8rpx rgba(212, 210, 211, 0.35); } .footer-tool-bar .tab{ color: #242424; height: 100%; line-height: 100rpx; } .footer-tool-bar .focus{ color: #f96e49; font-weight: 500; } .footer-tool-bar .icon{ width: 44rpx; height: 44rpx; margin: 18rpx auto; } .footer-tool-bar .text{ line-height: 80rpx; height: 80rpx; position: relative; display: inline-block; padding: 0rpx 40rpx; box-sizing: border-box; margin: 10rpx auto; } .footer-tool-bar .dot{ position: absolute; top: 16rpx; right: 16rpx; height: 16rpx; width: 16rpx; border-radius: 50%; background-color: #f45551; } .footer-tool-bar .badge{ position: absolute; top: 8rpx; right: 8rpx; height: 30rpx; width: 30rpx; line-height: 30rpx; border-radius: 50%; background-color: #f45551; color: #fff; text-align: center; font-size: 20rpx; font-weight: 450; } .hide{ transform: translateY(100%); } app.wxss(这里的样式文件是我用来存放一些公共样式) /**app.wxss**/ page { background-color: #f5f5f5; height: 100%; -webkit-overflow-scrolling: touch; } .container { height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: space-between; box-sizing: border-box; } .blur { filter: blur(80rpx); opacity: 0.65; } .flex-center { display: flex; align-items: center; justify-content: center; } .flex-column { display: flex; /*垂直居中*/ align-items: center; /*水平居中*/ justify-content: center; flex-direction: column; } .flex-start-horizontal{ display: flex; justify-content: flex-start; } .flex-end-horizontal{ display: flex; justify-content: flex-end; } .flex-start-vertical{ display: flex; align-items: flex-start; } .flex-end-vertical{ display: flex; align-items: flex-end; } .flex-wrap { display: flex; flex-wrap: wrap; } .flex-full { flex: 1; } .reset-btn:after { border: none; } .reset-btn { background-color: #ffffff; border-radius: 0; margin: 0; padding: 0; overflow: auto; } .loading{ opacity: 0; transition: opacity 1s; } .load-over{ opacity: 1; } .phx_68{ padding-bottom: 68rpx; } .phx_34{ padding-bottom: 34rpx; } 另外我还对tabbar的操作做了简单的封装: tabbar.js const api = require('/api.js'); /** * 切换tab * @param me * @param index */ const switchTab = function (me, index) { if (typeof me.getTabBar === 'function' && me.getTabBar()) { console.log("切换tab:", index); me.getTabBar().setData({ selected: index }) } }; /** * 显示 tabBar 某一项的右上角的红点 * @param me * @param index */ const showRedDot = function (me, index, success, fail) { if (typeof me.getTabBar === 'function' && me.getTabBar()) { me.getTabBar().showRedDot(index, success, fail); } }; /** * 隐藏 tabBar 某一项的右上角的红点 * @param me * @param index */ const hideRedDot = function (me, index, success, fail) { if (typeof me.getTabBar === 'function' && me.getTabBar()) { me.getTabBar().hideRedDot(index, success, fail); } }; /** * 显示tab右上角文本 * @param me * @param index * @param text */ const showBadge = function (me, index, text, success, fail) { if (typeof me.getTabBar === 'function' && me.getTabBar()) { me.getTabBar().showBadge(index, text, success, fail); } }; /** * 隐藏tab右上角文本 * @param me * @param index */ const hideBadge = function (me, index, success, fail) { if (typeof me.getTabBar === 'function' && me.getTabBar()) { me.getTabBar().hideBadge(index, success, fail); } }; /** * 显示tabbar * @param me * @param success */ const showTab = function(me, success){ if (typeof me.getTabBar === 'function' && me.getTabBar()) { me.getTabBar().showTab(success); } }; /** * 隐藏tabbar * @param me * @param success */ const hideTab = function(me, success){ if (typeof me.getTabBar === 'function' && me.getTabBar()) { me.getTabBar().hideTab(success); } }; module.exports = { switchTab, showRedDot, hideRedDot, showBadge, hideBadge, showTab, hideTab }; 最后,进入到tab对应页面的时候要手动调用一下swichTab接口,然tabbar聚焦到当前tab /** * 生命周期函数--监听页面显示 */ onShow: function () { tabbar.switchTab(this, this.data.tabIndex);//tabIndex是当前tab的索引 }
2021-11-09 - 小程序ad广告收入计算方式
[图片] 如图,为何4月17日收入这么低,只有0.05元,相近数量的曝光量与点击量,为何4月18、19日却有4元多? 小程序名: 找公厕 AppID:wx4513bda5456422ba
2019-04-22 - 有没有API可以获取小程序是否添加到【我的小程序】?
有没有API可以获取小程序是否添加到【我的小程序】,想要在小程序内检测当前小程序是否在【我的小程序】中
2020-12-03 - 小程序是否有“添加到我的小程序”这个功能的api
- 需求的场景描述(希望解决的问题) 微信的6.7.3版本新增了把小程序“添加到我的小程序”这个功能,那么这项功能是否可以由用户在小程序内点击实现,我在小程序的api文档那里没有看到有这个功能
2018-11-19 - 关于诱导分享的定义
小程序页面有一句提示语:您已经推荐X位用户,再推荐X位用户可领取XX礼品! 这句话算不算诱导分享? (页面中本身没有任何分享按钮,仅仅是一句提示!礼品也是真实有效的)
2017-11-18 - 关于微信小程序的诱导分享定义?
微信小程序如果做邀请活动,邀请的好友需要来到页面参与活动,邀请人才能获得奖励的,算不算“深度互动”?还算诱导分享吗?
2020-12-08 - 公众号诱导分享案例集锦
诱导分享,顾名思义即商家利用外链或公众号消息等形式,强制或利诱用户将指定内容分享至朋友圈,且其行为通常伴随着一定的利益、恐吓或道德绑架。 为了营造绿色和谐的网络阅读环境,公众平台根据相关运营规范对此进行了整理和分类,具体分为营销分享、恶意分享和外链分享。 1.营销分享 以获得红包、现金、实物奖励、虚拟奖品(积分、信息)等为诱饵,引导用户将信息转发到朋友圈,或分享到朋友圈集赞。 [图片] [图片] 2.恶意分享 ☛ 胁迫、煽动用户分享 以祝福诅咒、道德绑架等形式恶意要求用户在朋友圈分享指定内容。 [图片] [图片] ☛ 强制用户分享 分享后才能继续下一步操作。包括但不限于:分享后方可继续阅读,观看视频,浏览测试题答案等。 [图片] [图片] 3.外链分享 利用公众号的分享接口散布相关的活动内容。通常符合这两点特质: ☛用户提交一定的信息之后又要求强制转发到朋友圈才显示报名成功 ☛伴有一定的欺诈嫌疑 [图片]
2020-03-18 - 如何区分诱导分享类信息?
诱导分享类处罚规定: 根据《公众平台运营规范》第3.3.1 诱导分享 禁止通过外链或公众号消息等方式,强制或诱导用户将消息分享至朋友圈的行为。奖励的方式包括但不限于:实物奖品、虚拟奖品(积分、信息)等。 若违反相关协议,我司会根据公众帐号违规情况,对公众帐号限制或禁止使用全部或部分功能、帐号封禁/注销等相应处罚。 相关案例(以下信息仅供参考): 1)公众平台图文内包含诱导用户分享朋友圈活动 [图片] 2)公众平台图文或者图片包含诱导用户点赞活动 [图片] 3)通过公众平台图文、自动回复、自定义菜单跳转外链诱导用户分享朋友圈活动 [图片] 4)通过公众平台自动回复发布诱导用户分享朋友圈活动 [图片]
2020-03-18 - 一个小程序添加的直播间数量有限制吗?
一个小程序添加的直播间数量有限制吗?只看到同时五十场直播,举例:每天添加五十个直播间,第三天回放列表是不是150个直播间都能看?回放能看多久?
2020-06-11 - 如何突破一次只能获取20条记录的limit限制?只需要一行代码。
笔者刚遇到需要一次性拉取超过100条(云函数里超过1000条)记录的这种需求。 一般情况下,会有下面两种处理方式: 1、先获取总数,再for循环,每次拉取limit条记录;(可结合Promise.all并发) 2、递归拉取,每次拉取limit条记录,直到拉取的记录数量小于limit。 以上两种方式都比较麻烦,于是动了一脑筋,以最简单的方式实现上面的需求。 极简代码如下: db.collection('order').aggregate() .match({ status:'已付费' }) .addFields({ tempTag:1 //增加一个临时标签;也可以不要addFields这个阶段; }) .group({ _id:'$tempTag', orders:$.push('$$ROOT') //一次性拉取超过100条或者1000条记录 }) .end() .then(res=>{ let orders = res.list[0].orders console.log(orders) }) 一个临时标签,搞定。 小心数据量太大搞崩了,崩溃的极限是多少,需要各位自行摸索了。 需要注意的是,如果是云函数里执行以上代码(比如lookup),返回小程序端的数据量不要超过1M。
2021-03-15 - 小程序webview跨域问题如何解决?
在本地测试,后台已经设置允许跨域,浏览器和开发者工具微信公众号模式访问localhost不会存在跨域问题,但是在小程序webview中就会存在跨域问题,请问如何解决?
2019-10-17 - 网页授权出现跨域问题,域名已经在公众平台配置
XMLHttpRequest cannot load https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx1b63f19b557665ec&redirect_uri=https%3A%2F%2Factivitygray.motivape.cn%2F%23%2Ffriends_index%3Fopenid%3D%26channelType%3D0&response_type=code&scope=snsapi_userinfo&state=?openid=&channelType=0#wechat_redirect. Redirect from 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx1b63f19b557665ec&redirect_uri=https%3A%2F%2Factivitygray.motivape.cn%2F%23%2Ffriends_index%3Fopenid%3D%26channelType%3D0&response_type=code&scope=snsapi_userinfo&state=?openid=&channelType=0#wechat_redirect' to 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx1b63f19b557665ec&redirect_uri=https%3A%2F%2Factivitygray.motivape.cn%2F%23%2Ffriends_index%3Fopenid%3D%26channelType%3D0&response_type=code&scope=snsapi_userinfo&state=?openid=&channelType=0&connect_redirect=1#wechat_redirect' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://activitygray.motivape.cn' is therefore not allowed access. [图片]
2019-11-08 - 小程序web-view的缓存如何清除?
小程序web-view的缓存如何清除?
2021-08-06 - 小程序webView缓存如何处理?
小程序使用webView组件。访问url为 https://xxx.com/page?r=0.0907822272849359 携带随机数后,苹果手机真机查看依旧走的缓存页面。安卓手机却是可以的。请问下有什么好的处理方式吗?
2021-08-18 - webview 缓存解决办法
场景: 1.内嵌使用的是 vue + webpack 打包的单页面 2.更新内容后,webview里面的内容无法更新, 解决办法 1.在url后面加时间戳, 这个在苹果可以实时解决缓存,安卓有些机子不行 2.在安卓机子不行的时候,需要在webpack打包的时候加上 hash配置,不懂hash配置的,可以百度一下, 并且在index.html 里面meta标签加上http-equiv="cache-control" content="no-cache" 3.以上能解决新的打包项目在webview 缓存问题, 4.因为原先已经有缓存,进不到新打包的项目里面,走不到新的代码,所有还是会存在缓存问题,只需微信打开http://debugtbs.qq.com,然后根据里面提示,进入页面,里面有一个清除本地缓存选项,清除后,下次进去就可以了。 5.完美解决webview缓存问题
2020-12-01 - 云开发| -501001 resource system error 代表了什么?
编写了一个需要频繁查询数据库的云函数(一次运行大约查询读写 各5000次,运行时间30秒),遇到如下问题:在本地调试,频繁出现-501001错误;函数放在云端运行,一切正常。错误如下: -501001 resource system error | errMsg: collection.get:fail ESOCKETTIMEDOUT 请问这个错误是因为频繁查询导致本地调试器断线嘛?还是说在代码实现方面有什么效率瓶颈问题? 附上代码: for ( let j=0; j<data.length; j++){ var openid = data[j]._id var history = data[j].read_history const tasks = [] console.log (openid) //处理这个文章id数组 for( let k=0; k<history.length; k++ ){ let self = history[k] let others = [] history.forEach(element=>{ if ( element !== self){ others.push(element) } }) if ( others.length === 0 ){ continue } let relate = {} let isexist = await db.collection(ARTICLES_DYNAMIC_COLL).where({ _id: self }).get() //新添加 if ( isexist.data.length === 0){ others.forEach( element=>{ let str = `${element}` relate[str] = INC_ONE }) res = await db.collection(ARTICLES_DYNAMIC_COLL).add({ data: { _id:self, read_num: INC_ONE, relate, } }) }else if ( isexist.data.length === 1) { others.forEach( element=>{ let str = `${element}` relate[str] = _.inc(INC_ONE) }) res = db.collection(ARTICLES_DYNAMIC_COLL).doc(self).update({ data: { read_num: _.inc(INC_ONE), relate, } }) tasks.push(res) }
2021-04-12 - #wechat_redirect和vue的hash模式
小程序的#wechat_redirect和vue链接中的#冲突了,有没有解决办法啊???
2018-05-03 - 可以获取到用户进入小程序时所搜索的关键字吗?
当场景值scene为1005或1006时,说明用户是通过搜索进入小程序的。那么,可以获取到用户进入小程序时所搜索的关键字吗?如果可以,如何获取呢?
2021-08-16 - web-view怎么查看console.log?
使用了web-view内嵌了一个vue项目,怎么可以在小程序中console.log?
2019-09-26 - 小程序内怎么调试web-view?
开发工具上在web-view页面内点击鼠标右键有个调试的选项 需要在真机上调试需要自行引入vconsole:https://github.com/Tencent/vConsole/blob/dev/README_CN.md
2019-10-09 - 小程序web-view的src有长度限制吗?
小程序页面中加载关联公众号的页面,想将数据通过src传递,所以想知道src长度方面的限制
2019-10-25 - 如何在web-view的html中调用云函数?
请问各位大神,如何在web-view里面的html中调用云函数? 是通过微信jssdk调用,还是直接调用云开发 HTTP API,还是有其他更合适的方法?
2021-08-14 - 小程序登录之后如何刷新当前tab页面?
比如这个登录规范里面的,登录按钮在每个tab页面,比如ABC各个tab都有登录入口,登录了之后,如何刷新当前页面? 调用onLoad?onShow?onReady?,还是有可以让页面直接刷新重走生命周期的方法? https://developers.weixin.qq.com/community/operate/doc/000640bb8441b82900e89f48351401?blockType=5
2020-12-01 - 利用hash不刷新页面的特性,实现小程序向webView通讯
如果直接使用hash值传递参数,ios上会异常添加页面栈,点击小程序左上角会返回到上一次带hash的地址,参数传递多少次,页面栈就有多少个。以下代码解决了这个问题,废话不多说,直接贴代码。 //在webview中添加代码 let hash; // 监听hash变化 window.addEventListener("popstate", function() { // 有hash值时返回上一个页面,并储存hash。 // 因为返回了上一个页面,会立马进入else分支。 // 将存好的hash渲染到页面 if(location.hash){ hash = location.hash.split('#')[1]; history.back(); } else { //hash值最好是编码后的数据 document.getElementsByTagName('body')[0].innerHTML = '解码后参数:' + decodeURIComponent(hash); } }, false); wxml中引入web-view组件 <web-view src='{{src}}'></web-view> 小程序js代码 const src = 'http://127.0.0.1:8080/'; //替换成webview地址 Page({ data: { src: src, }, onLoad(){ let j = 0; // 每2秒传递一次值 setInterval(() => { let a = {test: j++}; let data = encodeURIComponent(JSON.stringify(a));//hash值最好经过编码 this.setData({src: `${src}#${data}`}) }, 2000); } })
2021-07-15 - Web-View 小程序跳转外部链接,能不能是Http开头的
[图片] [图片] 这个该如何解决?
2019-05-08 - 如何解决微信订阅消息发送失败fail missing wxCloudApiToken的问题?
我是定义了一个云函数 [图片] 然后在开发工具中,使用云调用来调用这个函数,但我手机没收到订阅消息通知,日志里面报错: {"errCode":-501007,"errMsg":"subscribeMessage.send:fail missing wxCloudApiToken"} 请问下有什么解决的思路吗?
2021-03-20 - 云调用subscribeMessage.send出现如下问题如何解决?
一、云调用错误如下: Error: errCode: -501007 invalid parameters | errMsg: subscribeMessage.send:fail missing wxCloudApiToken 二、附源码: async function batchSend(event) { const { messages } = event console.info({event: JSON.stringify(event)}) console.info('处理订阅消息', messages.length) // 循环消息列表 const sendPromises = messages.map(async message => { let { touser, page, data, templateId } = message // 发送订阅消息 await cloud.openapi.subscribeMessage.send({ touser, templateId, page, data, }) }); await Promise.all(sendPromises) } 三、现象描述: 直接云端测试云函数5 次, 结果:失败、成功、失败、成功、成功。一旦出错后,会一直报上述错误。需要调用其他云调用成功一次,才可以恢复。恢复后又是间歇性失败。其他云调用,如“cloud.openapi.wxacode.getUnlimited”从不会失败。总结:这个问题已经追踪了两天了,仍然没有找到必现的规律,失败的概率很大,很容易复现。跟其他人说的miniprogram_statestring参数也无关,因为我一直没有传此参数,默认值为formal。
2021-03-25 - 审核不通过? 原因: 存在登录功能不符合运营规范问题,违反微信小程序平台运营规范常见拒绝情形3.4
下午还能提交成功,之后也没有修改内容,这就提交不成功了,可以给个具体原因吗
2021-05-01 - 【严重安全风险】“云调用直接获取开放数据”如果用户使用自己构造的参数调用,云函数无法验证用户数据?
文档位置: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#method-cloud 问题描述: 根据文档描述,小程序端获取到cloudID后,将cloudID传给云函数,云函数会自动将cloudID替换为解密后的值。 如果用户按照解密后的数据结构构造参数调用云函数,云函数无法判断收到的数据是否是由cloudID解密而来。 举个例子: 小张参照着文档(https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#method-cloud) 写了如下代码,来获取用户手机号: ////// 前端 //////// wx.cloud.callFunction({ name: modifyPhone, data: { phoneCloudID: wx.cloud.CloudID(xxx) } }) //////// 云函数 /////// exports.main = async (e) => { // 获取解密后的手机号,但是无法保证这个数据不是伪造的! const phone = e.phoneCloudID.data.phoneNumer } 小黑可以这样手动构造参数,来欺骗小张写的modifyPhone云函数: wx.cloud.callFunction({ name: modifyPhone, data: { phoneCloudID:{ cloudID:"11111111", data:{ phoneNumber: "17777777777" } } } }) 到此小程序就认为小黑的手机号为17777777777。 [图片] [图片] [图片]
2020-12-21 - 小程序内存泄漏onBeforeUnloadPage如何解决呢?
无需提供代码片段,不管在开发者工具和真机上 只要来回切换10几次页面就会 报 这个警告
2020-09-04 - events事件警告VM47805:1 [Event] 21 listeners of event?
VM47805:1 [Event] 21 listeners of event onBeforeUnloadPage_962 have been added, possibly causing memory leak. 出现这种情况是什么,难是我没关闭吗,我是按文档上用的,只用了emit,难道还要调用off释放吗,还是另有其他原因???
2019-11-15 - 谁给个准信:小程序给用户发消息,现在到底是用订阅消息还是模板消息?
如果都用订阅消息,那用户没有关注绑定的公众号的话,是不是就收不到信息?如果这样的话,用订阅消息明显是不合适的。
2021-07-02 - 页面收录越来越少,收录页面少相关问题
可先确认下是否进行主动推送。若未进行主动推送,建议使用主动推送能力会提高收录量。(入口为:微信公众平台小程序-页面内容接入-基础设置-页面路径推送)。若已主动推送,可发帖并提供appid我们会及时跟进处理。
2020-04-23 - 小程序收录突然变成了0?
[图片] 从6月8日起开始,突然收录变成了0 APPID:wxf6e751d57946e18b
2021-06-21 - 小程序后台—页面内容接入—基础设置—频率上线 此处设置的爬虫次数上限不生效
[图片] 频率上线已设置,但是抓取量还是半小时数十万,服务器负载比较大,对我们来说风险很高 [图片]
2021-04-07 - 电话码
可以用作 挪车码、印到名片上、实体店张贴出来方便顾客联系。 追求极致的用户使用体验。
2020-07-01 - bindinput和bindblur的问题
bindinput 的事件中,如果是手写输入,在最后的时候如果直接点击触发按钮事件,比如查询或者搜索。最后那个字符是不能获取到的。 bindblur 的事件,如果直接在输入的状态下直接点击小程序上面的按钮触发其他事件,这个时候bindblur事件其实并没有拿到input里面的值。请问这些有什么办法可以解决??
2018-07-17 - 流量暴跌,被处罚?
微信官方你好,从昨天开始我们的搜索流量无缘无故暴跌90%以上,我们不知道是什么原因,上个月15号,我们有过一次内容安全警告,但是我们已经按照要求进行了调整,难道我们是因为这个被惩罚的吗? APPid:wxb9710e6cf52cbe4d best wish [图片][图片]
2021-02-06 - 小程序流量直接暴跌98.62%,官方也没有提示违规?
最近搜一搜流量直接暴跌98.62%,页面内容接入也每天都在提交着,官方能不能个点提示wx439ae5c90bf9d641
2021-06-27 - 如何在input的value中存放open-data里的userNickName值呢?
需要在input的value中存储用户昵称,该如何获取userNickName值
2021-03-19 - 微信搜一搜小程序的,最近多少人使用是多长时间段的一个使用人数?
如题 微信搜一搜小程序的,最近多少人使用是多长时间段的一个使用人数? [图片]
2021-01-15 - 小程序缓存可否增加时效性?
wx.setStorageSync(KEY,DATA)这个缓存以及异步等等的缓存都是永久性的缓存,那么问题来了,如果我要定时刷新页面怎么办?难道需要用定时器,这样感觉效率等等都会不好,包括用户体验,那么微信官方可不可以在存缓存的时候可不可以加一个参数,缓存存活的时间,时间一到缓存就自动销毁不存在了,求顶!!!
2018-06-26 - 小程序云开发如何获取集合里所有字段的名称?
如何获取云数据库某个集合里所有字段的名称
2021-03-04 - http api 调用小程序云开发中的云函数随机返回错误getaddrinfo ENOTFOUND?
如题,会随机出现如下错误, RequestError: Error: getaddrinfo ENOTFOUND api.weixin.qq.com api.weixin.qq.com:443 at new RequestError (/srv/node_modules/request-promise-core/lib/errors.js:14:15)
2020-05-03 - 小程序怎么打开视频号?
小程序怎么打开视频号
2021-03-08 - 不明来源的appId和未知场景值列表
可能在开发中会发现有用户小程序带着未知场景值和“不明来源”的appid进入。这些appid在小程序码生成界面查不到,场景值文档列表里也没有。 下面总结了一点点未知的appid和场景值,因为只接触到这些,仅供参考。 appId列表 APPID 官方名称 可能场景值 备注 图例 wxb6d22f922f37b35a 大家在用 1142,1023,无 小程序的发现页 图例1 wx9d7db7620ef5e23c 内容搜索Demo 1006 新版的小程序搜索入口不是这个了,可能只有老版本的微信才会带这个appid了 官方图例,图例2 wx76222b2ffe0c7ac7 好物圈推荐 微信圈子 场景值列表 只写了官方文档里没有的 场景值 备注 图例 1142 可能是小程序发现界面 图例1
2020-05-12 - 天地图问题
微信小程序能加载天地图吗
2019-03-18 - 小程序引入天地图?
小程序是否支持引入天地图
2020-05-18 - getLocation:fail:ERROR_NOCELL&WIFI_LOCAL
已经授权情况下:获取位置信息:errCode:2 getLocation:fail:ERROR_NOCELL&WIFI_LOCALTIONSWITCHOFF [图片]
2019-03-26 - 已经授权位置信息还是一直报错?报getLocation:fail 频繁调用会增加电量损耗,可考虑使用
[图片]
2021-03-09 - getLocation 频繁调用 报错怎么解决?
[图片] 小程序进入后要获取经纬度,只有在mounted 的时候调用一次。 用户点击分享卡片进去后退出再点击分享卡片进入 就会报频繁调用
2021-03-09 - 云开发如何避免接口被恶意频繁调用?
使用云开发,会不会有用户通过模拟程序恶意频繁调用接口的情况? 如果有,如何避免这种情况? 场景是:用户通过看广告获得积分,广告播放完毕后调用云函数为用户增加积分。我担心云函数被频繁调用,导致积分异常。
2020-10-14 - 真机调试出现U.createEvent is not a function?
[图片] 2021/04/28 14:11 再次搜索该问题,发现与我同样头痛的人还真多。 现在我告诉大家,我还没有解决啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 FK 他老母
2021-04-28 - 社区每周 |小程序云开发支持移动端修改及续费预付费配额资源、上周问题反馈(5.24-5.28)
各位微信开发者: 以下是小程序云开发支持移动端修改及续费预付费配额资源公告及上周我们在社区收到的问题反馈与需求的处理进度,希望同大家一同打造小程序生态。 小程序云开发支持移动端修改及续费预付费配额资源 为更好的帮助各位开发者便捷地管理云开发资源,云开发已上线移动端的预付费配额资源的修改及续费操作(暂仅支持微信支付方式),无需登录云开发控制台即可轻松操作。当在微信中收到云开发预付费资源到期或停服的模版消息时,可点击该消息进入“云开发助手”小程序进行相关操作。按量付费及腾讯云支付方式即将支持,敬请期待。 [图片] 上周问题反馈和处理进度(5.24-5.28) 已修复的问题微信支付接口一直报错的问题 查看详情 开发者工具-公众号网页调试-获取定位失败的问题 查看详情 wxs文件在开发者工具没有高亮的问题 查看详情 微信公众号模板消息为空的问题 查看详情 小程序后台配置业务域名点击保存无反应的问题 查看详情 修复中的问题 MediaRecorder.requestFrame在安卓微信版本8.0.3执行速度非常缓慢的问题 查看详情 删除components文件夹后立马撤回文件夹变空的问题 查看详情 需求反馈需求评估中ComponentData版面看不到虚拟化组件的数据 查看详情 RuntimeError: cannot read property 'rename' 查看详情 微信团队 2021.6.4
2021-06-04 - 请问云函数环境的nodejs8.9应该安装哪个版本的nodejieba?
求问:安装不上nodejieba和版本有关吗
2020-03-19 - 不支持npm模块nodejieba
复现错误过程如下。 新建一个云函数test, index.js代码如下:// 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() var nodejieba = require("nodejieba") // 云函数入口函数 exports.main = async (event, context) => { var result = nodejieba.cut("南京市长江大桥") console.log(result) } 2. 命令行下,切换到test目录,执行命令:npm install nodejieba npm安装成功,日志如下: ..\cloudfunctions\test>npm install nodejieba > nodejieba@2.5.2 install ..\cloudfunctions\test\node_modules\nodejieba > node-pre-gyp install --fallback-to-build [nodejieba] Success: "..\cloudfunctions\test\node_modules\nodejieba\build\Release\nodejieba.node" is installed via remote npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN test@1.0.0 No description npm WARN test@1.0.0 No repository field. + nodejieba@2.5.2 added 58 packages from 96 contributors and audited 58 packages in 74.521s 3 packages are looking for funding run `npm fund` for details found 0 vulnerabilities 3.在开发工具中点击“上传并部署:云端安装依赖” 4.执行云函数test 5.此时报错,找不到模块nodejieba: {"errorCode":-1,"errorMessage":"Runtime.ImportModuleError: Error: Cannot find module '/var/user/node_modules/nodejieba/build/Release/nodejieba.node'\n at Object.module.exports.load (/var/runtime/node10/UserFunction.js:35:13)\n at Runtime.handleOnce (/var/runtime/node10/Runtime.engine.js:97:38)\n at Timeout.setTimeout [as _onTimeout] (/var/runtime/node10/Runtime.engine.js:54:12)\n at ontimeout (timers.js:436:11)\n at tryOnTimeout (timers.js:300:5)\n at listOnTimeout (timers.js:263:5)\n at Timer.processTimers (timers.js:223:10)","statusCode":443} 请问如何才能让云函数支持npm模块nodejieba呢?
2021-06-04 - 小程序云数据库是否支持分词搜索?
小程序云数据库和mongodb有些类似,mongodb企业版才支持中文分词搜索。翻阅了一下小程序云开发文档,没发现中文分词搜索的内容。请问有经验的大佬,云数据库到底支不支持分词搜索?
2020-09-14 - db.RegExp查询中字符串中包含中文以及括号时查询不到结果?
text = [path:"格林豪泰(光明西路店)"] path: db.RegExp({ regexp: "(光明西路店)", options: 'i', }),//可以查询到 path: db.RegExp({ regexp: "格林豪泰(光明西路店", options: 'i', }),//查询不到结果 path: db.RegExp({ regexp: "泰(光明西路店", options: 'i', }),//查询不到结果
2020-09-18 - 小程序云函数本地调试无法获取到环境变量?
版本 1.02.2003250 系统 Windows10 [图片]
2020-05-10 - 每个云函数都得init一下那个环境变量吗?
新建云函数,默认 const cloud = require('wx-server-sdk') cloud.init() 我这么调,报错 出不来数据。 每次我都得 cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) 是不是我调用云函数很慢跟这个有关,应该怎么修改,大佬帮忙指点指点
2021-03-17 - 哪些地方会消耗CDN流量?
虽然有很多类似的提问,但翻了一圈仍然没有找到合适的解答。 1.有图片上传到云存储的步骤,但仅仅是为了敏感图片检测所用。通过云函数检测完之后就删掉了,没有留下任何资源。 2.会用到接口,上传图片base64,获取对应的文字数据或者图片链接。 不知道是哪个步骤导致CDN流量一直涨,也不知道从哪里解决问题。 官方文档也写得不清楚。希望熟悉这个板块的解疑!!!
2020-09-25 - 云函数Error: errCode: -501007 invalid parameters 啥原因?
云函数后台报错日志: 2019-11-01T03:15:08.827Z gDate is: 2019-11-01T03:15:08.827Z 2019-11-01T03:15:08.827Z lDate is: 2019-12-01T03:15:08.827Z 2019-11-01T03:15:08.890Z { Error: errCode: -501007 invalid parameters | errMsg: [InvalidParameter] Check request parameter fail. Please check your request, but if the problem cannot be solved, contact us.; at new CloudSDKError (/var/user/node_modules/wx-server-sdk/index.js:6389:28) at Object.returnAsCloudSDKError (/var/user/node_modules/wx-server-sdk/index.js:6441:16) at Object.checkError (/var/user/node_modules/wx-server-sdk/index.js:1672:23) at Aggregate.<anonymous> (/var/user/node_modules/wx-server-sdk/index.js:1351:41) at step (/var/user/node_modules/tslib/tslib.js:136:27) at Object.next (/var/user/node_modules/tslib/tslib.js:117:57) at fulfilled (/var/user/node_modules/tslib/tslib.js:107:62) at <anonymous> at process._tickCallback (internal/process/next_tick.js:188:7) errCode: -501007, errMsg: '[InvalidParameter] Check request parameter fail. Please check your request, but if the problem cannot be solved, contact us.; ' } END RequestId: cf12d219-fc55-11e9-945a-5254007aa7a1 Report RequestId: cf12d219-fc55-11e9-945a-5254007aa7a1 Duration:69ms Memory:256MB MaxMemoryUsed:36.683594MB 云函数代码为: [图片]
2019-11-01 - 云开发Aggregate.match阶段不支持时间比较?
查不到数据,不想用addFields+match的方式 const start = new Date('2020-09-01 00:00:00').toJSON() const end = new Date('2020-09-30 00:00:00').toJSON() db.collection('') .aggregate() .match({ time: _.gte( $.dateFromString({ dateString: start, }) ).lte( $.dateFromString({ dateString: end, }) ) }) .end()
2021-01-12 - 微信开发者工具Git not found. Install it or configure it 解决办法
微信开发者工具Git not found. Install it or configure it using the ‘git.path’ setting解决办法 [图片] 微信开发者工具窗口界面依次选择 设置-》 编辑器设置-》 更多及工作区的编辑器设置-》 扩展-》 GIT-》 PATH-》 在setting.json中编辑 [代码] "git.path": "/usr/local/git/bin/git" #根据自己git的安装目录配置 [代码]
2020-09-10 - RuntimeError: cannot read property 'rename' ?
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/database/command/Command.rename.html 在云函数中可以调用成功,在云开发控制台里面的高级操作里面调用则报错。 RuntimeError: cannot read property 'rename' (from line 8, col 19 to line 8, col 25) 6 | .update({ 7 | data: { > 8 | chukuNum: _.rename('ckNum'), | ^^^^^^ 9 | } 10 | }) [图片]
2021-04-15 - 如何实现一个自定义数据版省市区二级、三级联动
社区可能有其他的方案了,但是再分享下吧,给有需要的童鞋。 效果图: [图片] 额,这个视频转GIF因为社区上传不了大图,所以剪了一部分,具体的效果还是直接工具打开代码片段预览吧~ 第一步:你的页面JSON引入该组件: [代码]{ "usingComponents": { "city-picker": "/components/cityPicker/index" } } [代码] 第二步:你的页面WXML引入该组件 [代码]<city-picker visible="{{visible}}" column="2" bind:close="handleClick" bind:confirm="handleConfirm" /> [代码] 第三步:你的页面JS调用 [代码]// 显示/隐藏picker选择器 handleClick() { this.setData( visible: !this.data.visible }) }, // 用户选择城市后 点击确定的返回值 handleConfirm(e) { const { detail: { provinceName = '', provinceId = '', cityName, cityId='', areaName = '', areaId = '' } = {} } = e this.setData({ cityId, cityName, areaId, areaName, provinceId, provinceName }) } [代码] 组件属性 属性 默认值 描述 visible false 是否显示picker选择器 column 3 显示几列,可选值:1,2,3 values [0, 0, 0] 必填,默认回填的省市区下标,可选择具体省市区后查看AppData的regionValue字段 close function 点击关闭picker弹窗 confirm function 点击选择器的确定返回值 confirm: 属性 默认值 描述 provinceName 北京市 省份名称 provinceId 110000 省份ID cityName 市辖区 城市名称 cityId 110100 城市ID areaName 东城区 区域名称 areaId 110000 区域Id 至于怎么获取你想默认城市的下标,可以滑动操作下选中省市区后,点击确定后查看appData里的regionValue的值。 以上就是一个自定义数据版本的省市区二级、三级联动啦,老规矩,结尾放代码片段。 https://developers.weixin.qq.com/s/F9k9cTmT7LAz
2022-07-20 - navigationStyle怎么js动态设置值啊?
[代码]例如修改标题可以wx.setNavigationBarTitle[代码]({[代码]title:xxx[代码][代码]}),怎么在js里修改navigationStyle值呢?[代码]
2019-05-29 - callout显示图片
map里面的 callout 不能放图片显示吗?
2019-07-29 - 地图自定义callout为什么会这样?
[图片] 正常的应该在黄圈这里,但有些机型,比如oppo的find x,电脑微信打开也是,就会到红圈那里
2020-09-30 - 云函数 geoNear() 分页只能输出前100条
代码如下: let res = await db.collection('cars') .aggregate() .geoNear({ distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离 spherical: true, distanceMultiplier: 0.001, near: db.Geo.Point(event.longitude, event.latitude), key: 'location', // 若只有 location 一个地理位置索引的字段,则不需填 includeLocs: 'location', // 若只有 location 一个是地理位置,则不需填 }) .skip((page-1) * pageSize) .limit(pageSize) .lookup({ from: 'shops', localField: 'shopId', foreignField: '_id', as: 'shop', }) .end() 此代码前100条的分页都正常,但是100条之后,返回的都是空数组 想用geoNear()的limit ,可是 geoNear() 只有limit 并没有skip 想把skip和limit 放geoNear前面,但geoNear必须跟在aggregate后面第一个,不然会报错 这个要怎么解决啊?官方是不是给geoNear 少了个skip字段啊?
2019-12-19 - geoNear无法使用count()
- 当前 Bug 的表现(可附上截图) - 预期表现 - 复现路径 - 提供一个最简复现 Demo [代码]db.collection([代码][代码]'user_address'[代码][代码])[代码] [代码].where({[代码] [代码]location: _.geoNear({[代码] [代码]geometry: user_location[0].location,[代码] [代码]minDistance: 0,[代码] [代码]maxDistance: 5000[代码] [代码]})[代码] [代码]})[代码] [代码].count({[代码] [代码]success: [代码][代码]function[代码] [代码](res) {[代码] [代码]console.debug([代码][代码]"db.collection('user_address')"[代码][代码], res)[代码] [代码]},[代码] [代码]fail:err=>{[代码] [代码]console.debug([代码][代码]"db.collection('user_address')"[代码][代码], err)[代码] [代码]}[代码] [代码]})[代码]如上代码,运行后返回错误: db.collection('user_address') Error: errCode: -502001 database request fail | errMsg: [FailedOperation.Query] (BadValue) $geoNear, $near, and $nearSphere are not allowed in this context 求解使用geoNear查询附近的点如何过去查询结果的总条数,如果不支持count,应该如何获得总的记录条数?
2019-06-16 - 小程序卓手机获取wgs84定位与苹果手机获取wgs84定位偏差很大?换成gcj02还是有问题?
恳请各路大神解答,谢谢了,下面是小程序获取wps84以及gcj02的代码,再下面是定位结果。 [图片][图片][图片] 这个excel获取的是wgs84坐标,其中8是苹果的,32是安卓手机。 [图片] 这个excel获取的是gcj02坐标,其中8是苹果的,32是安卓手机。测试发现不管什么坐标系下,两个手机出来的结果偏差都很大。
2020-09-06 - 云开发Aggregate.geoNear聚合查询没有skip?
Aggregate.geoNear(options: Object): AggregateAggregate聚合查询的参数没有skip,请问如何分页查询? [代码]db.collection('users') .aggregate() .skip(5) .end()[代码]是先查出多少条再剔除多少条,如果数据库记录数大于100我就无法拿到100之后的数据了(因为最大只能取100条记录);分页应该是先剔除前几条再查询后面的多少条(skip应该在limit前面) 已解决: result = await db.collection('tableName').aggregate() .geoNear({ distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离 spherical: true, near: db.Geo.Point(lng, lat), query: { id: id, }, //limit: 10 geoNear里面也有limit,我就是加了这个才没达到效果 }).skip(currentPage * 10).limit(10).end()
2019-12-17 - 小程序流量主、广告位类型和广告收益分析
小程序流量主、广告位类型和广告收益分析 ## 本文介绍 最近在小程序的几个微信群,经常有朋友问到以下几个问题 1、小程序怎么盈利 2、小程序流量主是什么以及怎么开通 3、小程序广告有哪些类型,哪种广告类型相对收益最大 4、 ## 小程序如何盈利 目前对个人小程序开发者而言,只有通过开通流量主,并且按照官方规范要求添加广告位,才能获取收益,当然打赏除外。 ## 什么是流量主如何开通 流量主是微信对外提供的一个服务,通过开通流量主,就可以在小程序合适的位置引入广告位,进而实现收益 登录公众号后台( https://mp.weixin.qq.com/ )在左侧菜单中,找到 推广-流量主,点击进去会看到如下截图 [图片] 小程序流量主: 1.开通条件:小程序累计独立访客(UV)1000以上,且无违规记录,即可开通流量主功能。 温馨提示:如满足条件仍无法开通,可能是数据同步问题,建议等待1-2个工作日后再试。 2.申请方法:进入微信公众平台小程序后台,点击左侧面板“流量主”,满足开通门槛的小程序开发者点击“开通”,提交财务资料,待审核通过后成功开通流量主功能,即可创建相应的广告位。 3.广告接入指引: 广告接入可查看: 微信小程序广告接入指引 在开通流量主的过程中,会绑定个人银行卡,以方便进行后续的广告收益结算,目前结算每月两次,具体官方公告可以查阅 [流量主结算周期及开票规则调整说明][2019-12-03发布] https://mp.weixin.qq.com/promotion/readtemplate?t=notice/detail_page&time=1575340587¬ice_id=634169 ## 广告类型有哪些 Banner激励式视频插屏视频广告前贴视频 以下为各广告类型,截图示例, [banner广告] [图片] [插屏广告] [图片] 视频广告 [图片] 由于插屏广告会影响用户体验,所以不建议放太多场景使用。 具体不同类型广告体验,可以扫码 [图片] 首页模块-->>插屏广告使用说明-->>视频广告关于我们-->>banner广告 ## 哪种广告类型收益相对最大 [图片] 在10月30号,将banner广告同一替换为激励式视频广告和视频广告,收益很明显从30元上升到90元、150元 可以看到视频广告相对于banner广告,对于收益增加是有用的。 下图是某小程序12月4号一天的收益数据 [图片] 12月4号一天,不同广告类型,收益分析 总收益 194.74+23.27+147.82=365.83 具体分拆来看 广告类型点击量总收益单个点击收益(元)banner1956194.740.099插屏广告6223.270.375激励式视频广告152147.820.972 通过上图我们对比分析,不难得出以下结论:激励式视频广告单个点击的收益最大、 当然我们不能通过单一维度来了解哪种收益最好,还要综合考虑,比如哪种广告对用户影响最小,毕竟不管哪种方式,广告的接入肯定会带来交互体验上的障碍, 我们必须在交互体验和广告收益这两者之间做好权衡。 ## 系统公告 激励式广告于7月31日支持30秒视频素材,广告流量将逐步放开,MP后台-广告位管理模块可支持选择6-15秒视频或6-30秒视频素材的功能,请流量主根据产品进行调整。程序视频广告已于9月4日正式全量上线,开通后即按广告曝光获得分成收入,进一步提升流量变现收益。小程序视频前贴广告组件已于8月30日正式全量上线,开通后即按广告曝光获得分成收入,进一步提升流量变现收益。## 官方文档 小程序广告组件流量主操作指引https://wximg.qq.com/wxp/pdftool/get.html?id=BJSyDkLqz&pa=14&name=miniprogramAds_supplier_manual应用规范https://wxa.wxs.qq.com/mpweb/delivery/legacy/pdftool/get.html?id=rynYA8o3f&pa=10&name=miniprogramAds_supplier_guidance小程序流量主应用规范https://wximg.qq.com/wxp/pdftool/get.html?id=rynYA8o3f&pa=10&name=miniprogramAds_supplier_guidance处罚标准https://wxa.wxs.qq.com/mpweb/delivery/legacy/pdftool/get.html?id=BkTGkbs2G&pa=1&name=miniprogramAds_supplier_regulation小程序视频广告流量主指引https://wximg.qq.com/wxp/pdftool/get.html?post_id=1317小程序视频前贴广告流量主指引https://wximg.qq.com/wxp/pdftool/get.html?post_id=1318## 总结三点 从纯收益的角度来讲,在各种广告类型中,视频广告(包含激励式视频广告、视频广告、视频前贴广告)要比banner广告要好,而且好很多从用户体验来讲,插屏广告是首次打开带插屏广告的页面强制弹出的,但是广告过后,在页面是不占空间的,这是区分与其他广告的地方,banner广告、激励式视频广告、视频广告、视频前贴广告都是在页面中占固定的空间的,这一点要小程序运营同学权衡。Banner广告是按点击,激励式视频、视频广告、插屏广告都是按照曝光来收取广告费用的,这一点非常重要,难怪我每次手工点击我的视频广告没有见流量的增加[哭脸.jpg]。[感谢 @ 仙森 补充于2019年12月9号] 虽然对个人开发者而言,我们开发小程序的目的是为了收益(当然也有为了情怀而开发),在了解如何收益的情况下,我们还是应该尽量把精力放在小程序本身的开发上面。 感谢 在此特别感谢,小程序运营讨论群的两位小伙伴,微信号中间两位已打码 1、@迭戈 (yang_##chun) 2、@风猫 (cs##26)
2020-12-25 - 云函数的使用量是如何计算的?
有没有详细的说明 或者简单一点,比如有个10kb的云函数,里面有一个if else各5kb,那每次调用肯定就只走if和else其中一个,那就是按5Kb算吗,还是不管云函数的代码段是否全部执行,都是按云函数文件的大小10KB计算
2020-03-22 - FileSystemManager.readFile读取超过10M的文件会报错?见截图
[图片]
2019-12-11 - 小程序有返回照片完整EXIF信息的api吗
选择本地照片,希望获取到照片的GPS位置信息。
2018-11-15 - 小程序map组件上实现触摸点击拾取坐标
- 需求的场景描述(希望解决的问题) 长按或者点击map地图组件时没有拿到点击处的对应坐标 - 希望提供的能力 希望长按或者点击map地图组件时获取点击处的坐标
2019-05-15 - map组件bindtap属性获取经纬度?
有人用map组件里的bindtap属性来获取点击点的经纬度吗? 目前看好像还不太好使,点击事件有时候需要点多次才会响应返回
2020-05-20 - 小程序可以实现打赏的功能吗?
小程序有打赏相关的API吗? 可以在小程序里放置个人的赞赏码吗? 小程序里有打赏功能违规吗?
2019-10-25 - 如何实现服务通知?非小程序服务通知
[图片]如上图的呗宝有钱推送的 会员卡积分变动通知。不能拒收通知,也不需要关注公众号、小程序就可以强制给微信用户发送通知。 请教这个是如何实现的?
2019-11-15 - 微信小程序自带的map是否支持卫星地图
遇到一个需求,需要显示卫星地图,并且可以在地图上画出矩形区域,看了下开发文档貌似不支持?这个需求可以在小程序上实现吗?
2017-06-13 - 百度地图打车小程序这样的自定义Map callout如何实现?
[图片] 微信官方文档上只提供了单行同色文字的api:https://developers.weixin.qq.com/miniprogram/dev/component/map.html#marker%20%E4%B8%8A%E7%9A%84%E6%B0%94%E6%B3%A1%20callout 有人知道百度地图打车这样的气泡样式是如何实现的吗?
2020-07-09 - 百度地图的API在微信小程序体验版不显示,请问各路大神遇到过这样的问题嘞?
真机调试的时候没问题 [图片] 体验版就出了问题,一直不显示 [图片] 在体验版打开调试模式没问题 [图片]
2019-10-31 - 小程序 地图 支持卫星图吗?
- 需求的场景描述(希望解决的问题) 小程序地图支持卫星图吗? - 希望提供的能力 小程序地图支持卫星图
2018-11-14