- 小程序改名后,通过搜索小程序名称在全部里面搜不到小程序?只有点击小程序才可以看到,
小程序原始ID:gh_98568c39412e 小程序名称:臭熊熊去水印 问题:小程序改名称后,通过微信搜索不会出现在全部页面里面 ,而是只能点到小程序才能看到! 没改名之前都可以搜索到,改名称后搜索不到,改名都有几个月了,望解决!谢谢! [图片][图片]
2021-05-26 - 公众帐号无法被搜索到是什么原因?
你好,公众号搜索建议你通过搜一搜—>公众号,搜一搜tab标签页公众号区域进行搜索,若无法搜索到,请你参考以下几种情况: 1、修改公众号名称,简介无法被搜索到 若公众号帐号修改名称和简介,在审核在此期间,建议你将微信公众号帐号的二维码保存在电脑本地后,通过可过微博、空间、网 站等途径进行推广,让更多的粉丝关注你,与粉丝进行更多的互动。 温馨提醒:修改帐号昵称简介等,会动态影响搜索的相关排序,建议稍后重试。 2、是否在公众号后台设置了禁止被搜索? 若微信公众号帐号昵称无法被搜索到,建议你查看是否设置了禁止被搜索,请你通过以下方法查看和设置; 设置方法:登录微信公众微信平台->设置->帐号信息->隐私设置->允许。 温馨提示: 1)设置禁止用户通过昵称搜到该帐号后,粉丝通过ID和二维码可以搜到该帐号。(搜索公众号一栏,默认是搜索原始ID,如果已设置了微信号,原始ID会被微信号取代) 2)设置设置成功,半小时后即可生效。 [图片] 3、帐号信息登记审核中、未审核通过、封号、冻结、注销等 若你的微信公众号信息登记审核中/未审核通过、公众号违规被封/冻结、或公众号被注销时,他人在手机微信->搜一搜->“搜索公众号名称”或“搜索公众号微信号”,是无法搜索到你的公众号帐号。 4、公众号不在搜一搜全部中展示 你好,搜一搜的入口是可以搜到属于正常的,这个不属于搜不到的范围。关于公众号的搜索问题,我们会通盘考虑公众号运营者和微信搜索用户的搜索需求与使用习惯。大致的排序原则:排序结果受公众号的运营时间,运营频率,历史违规行为,搜索用户的使用行为反馈,搜索关键词的匹配程度等因素共同决定的,请运营者坚持运营,我们相信优质的公众号一定会受到用户的喜爱脱颖而出的。 5、在搜一搜公众号模糊搜索不一定搜得到 你好,公众号召回都是以账号名称、内容和简介为主要依据的,我们会通盘考虑公众号运营者和微信搜索用户的搜索需求与使用习惯。因帐号运营质量过低,无法被召回,建议提高公众号的运营质量 6、通过微信搜公众号昵称的逻辑 微信根据用户搜索习惯及公众号质量等信息进行算法排序,暂时无法手动干预。请你以微信页面的实际展示为准,感谢你对微信的支持。 可通过以下两种搜索公众号的方法: 1)通过微信“查找”功能,通过昵称搜索,未认证的公众号和已认证的公众号都可通过昵称搜索到。 2)通过搜一搜,通过昵称搜索和微信号,点击标签页中公众号区域。未认证的公众号和已认证的公众号都可通过昵称搜索到。 温馨提示:注册成功后,手机端最迟48小时内便可搜索到新注册的公众帐号。 [图片] [图片]
2021-06-04 - 提高性能的几种写法
任何优秀的大软件里面都是一个优秀的小程序。<br> 点完赞,在查看哦 setData 频繁使用setData会造成js阻塞问题,甚至卡顿,崩溃(崩溃没试过哈);所以我们应该如何用正确的姿势提高性能呢? 尽量把需要setData的内容放到一起setData,不要出现一个函数多个或者同时使用setData; 更新对象内的某个值,不应该整个对象重新更新,只需要更新对应的值即可,例如<br> [代码]this.setData({'userInfo.headImg': '更新的内容'})[代码]; 如果是列表数据,需要改变某个值变成true,也不应该全部数据更新一遍,只需要更新某一个值即可,例如<br> [代码]this.setData({[`list[${index}].show`]: true})[代码]; 页面不需要渲染的数据,尽量不要写在js里面的data里面,你可以定义一个全局参数都可以或者this.timer等生成一个全局变量; setData单次不能超过1M,超过会导致设置不成功,建议分页数据可以使用二维数组设置,例如 [代码]// 1.通过一个二维数组来存储数据 let feedList = [[array]]; // 2.维护一个页面变量值,加载完一次数据page++ let page = 1 // 3.页面每次滚动到底部,通过数据路径更新数据 onReachBottom:()=>{ fetchNewData().then((newVal)=>{ this.setData({ ['feedList[' + (page - 1) + ']']: newVal, }) } } // 4.最终我们的数据是[[array1],[array2]]这样的格式,然后通过wx:for遍历渲染数据 [代码] relativeToViewport 我们会发现很多时候,列表展示都是图文展示,而图片后端又没有提供缩略图,这会导致浏览器一次请求多张图片会非常消耗http请求,并且浏览器也有请求数量限制,例如chrome浏览器就限制一次性最多6个,严重还会影响我们业务接口请求,这时我们使用[代码]IntersectionObserver[代码]就太美妙了 解决思路 先创建对象实例[代码]wx.createIntersectionObserver()[代码]; 用数据列表遍历监听页面渲染的元素; 条件判断,动态设置状态显示图片,如果返回滚动则过滤不需要在setData,减轻js工作任务; js代码 [代码] data: { list: [ // 测试数据自己随便造 {id: 0, url: 'https://devapicard.itop123.com/files/img/20201213/20201213141209123634220.png'}, {id: 1, url: 'https://devapicard.itop123.com/files/img/20201213/20201213141209123634220.png'}, {id: 2, url: 'https://devapicard.itop123.com/files/img/20201213/20201213141209123634220.png'}, ] }, onReady() { let list = this.data.list; list.forEach((item,index)=>{ // 遍历监听元素在页面的位置 wx.createIntersectionObserver().relativeToViewport({bottom: 0}).observe(`.img-${index}`,res=>{ if (res.intersectionRatio > 0 && !list[index].show){ // intersectionRatio值大于0,说明元素出现在视图中了 // console.log(item, 'list', res) this.setData({ [`list[${index}].show`]: true }) } }) }) }, [代码] wxml代码 [代码] <view> <block wx:for="{{list}}" mode="aspectFill" wx:key="index"> <view class="test-img img-{{index}}"> <image class="image" wx:if="{{item.show}}" src="{{item.url}}"></image> </view> </block> </view> [代码] wxss代码 [代码].test-img{ width: 600rpx; height: 400rpx; margin-bottom: 20rpx; overflow: hidden; } .image{ width: 100%; } [代码] onPageScroll 这个监听页面滚动事件,输出顶部滚出页面多少距离,单位是px;这个事件非必要时不要写也不要输出内容,这样会很消耗性能,如果必须要使用到,我们要学会写节流或者防抖事件,减少过快的去setData;下面代码是网上复制,结合自己业务改造下即可 [代码]// 防抖 function debounce(fn, wait) { var timeout = null; return function() { if(timeout !== null) clearTimeout(timeout); timeout = setTimeout(fn, wait); } } // 处理函数 function handle() { console.log(Math.random()); } // 滚动事件 window.addEventListener('scroll', debounce(handle, 1000)); // 节流throttle代码(定时器): var throttle = function(func, delay) { var timer = null; return function() { var context = this; var args = arguments; if (!timer) { timer = setTimeout(function() { func.apply(context, args); timer = null; }, delay); } } } function handle() { console.log(Math.random()); } window.addEventListener('scroll', throttle(handle, 1000)); [代码] 代码分包 代码肯定是越写越多,需求也是越来越多的,小程序单个分包最大只能是2M,这就不能让我们的业务代码都写在主包,这会导致我们无法提交代码,并且也会导致我们打开小程序会很慢,体验很差。 为了解决这个问题,微信提供了小程序总共代码包支持最大16M,还支持我们分包功能,这样我们就可以开发更强大的功能,分包又分为普通分包和独立分包,他们又是什么关系,有何不同? 总的不同是,主包不能调用任何分包的东西,例如js,组件等,但是分包或者独立分包是可以调用或者使用主包的任何东西 分包:分包就是一个可以节省主包代码的一个普通分包,启动分包页面,会把主包下载,普通分包可以使用主包的 js 文件、template、wxss、自定义组件、插件等 独立分包:独立分包不依赖主包即可运行,不需要下载主包,可以很大程度上提升分包页面的启动速度,固并不能使用主包的 js,组件,wxss,插件等 预加载:分包后,如果想打开主包后,跳转不出现加载模块中的等待提示,可以使用预加载,这样就可以做到无缝跳转,增强了用户体验,跳转就像主包跳转主包页面一样顺滑。更多分包讲解请查看微信文档 [代码]{ "pages": [ "pages/index", "pages/logs" ], "subpackages": [ { "root": "moduleA", // 分包 "pages": [ "pages/rabbit", "pages/squirrel" ] }, { "root": "moduleB", // 独立分包 "pages": [ "pages/pear", "pages/pineapple" ], "independent": true // 独立分包的标志 } ], "preloadRule": { // 预加载写法 "pages/index": { "network": "all", "packages": ["moduleA"] // 需要预加载的分包 }, "pages/logs": { "packages": ["moduleB"] // 需要预加载的分包 } } } [代码] 结束 本次写作先到这里,更多丰富好用的内容,请等待下一期~ 都看完了,别忘了给个赞再走~,创作不容易,谢谢哦 本文与掘金号文章同步,欢迎查阅掘金对应的文章
2021-07-09 - 如何提单“公众平台”腾讯客服?
第一步:用手机打开微信 在微信首页的顶部“发现搜索按钮”(如图1.1)->搜索“腾讯客服”,打开“腾讯客服”小程序(如图1.2) 图1.1: [图片] 图1.2: [图片] 第二步:进入“腾讯客服”小程序,点击相应的“标签”进行跳转 在顶部tab,点击“其他”(如图2.1)->点击“更多其他问题”(如图2.1)->点击“公众平台”(如图2.2)->点击底部的“提交问题”(如图2.3) 图2.1: [图片] 图2.2 :[图片] 图2.3:[图片] 第三步:点击“提交问题”,跳转到编辑页面。 选择“问题类型”(如图3.1)->对应的选项进行填写(如图3.2) 图3.1:[图片] 图3.2:[图片]
2021-02-25 - 微信开放社区正确的提问方式
调侃 某萌新:为什么我在社区提问的问题都没人回答啊 某大佬:社区的问题质量是越来越低了,真不想看社区的问题了 如何提问 今天,在下就来告诉大家如何优雅的提问: 在提问之前,先想好自己遇到的问题是什么,让想要帮助你的人,知道你的问题所在 提问语言简洁明了,详细说明重现步骤及可能存在的问题 附上问题截图,比如调试工具报错信息、提审被驳回信息 写明代码环境,如工具版本、手机版本、基础库版本等 如果调用接口报错,请直接把接口的官方文档地址贴出来,标明调用接口地址,附上请求的参数以及返回的数据 必要时请提供代码截图或代码片段 点击查看如何创建代码片段 最重要的一点:提问时请务必注意礼貌。这一点特别重要,因为这关乎到回答者决定要不要回答以及以怎么样的态度来回答 依然是重要的一点:请务必给认真回答协助解决问题的回答者一个“赞”,这会更加激起他们回答的积极性 千万不要投机,把问题提到“文章”版块,这样会被直接隐藏。不仅不会加快被解答的速度,还会耽误解答机会 示例 (仅为示例,不代表该问题实际存在) 标题:picker组件多级联动会出现选项为 null 的情况? 内容: 使用picker组件,设定为多级联动,仅滚动一级栏后确定,后面的栏目获取到的值为 null,能麻烦帮忙看下吗?最新版开发者工具,基础库版本 2.9.2 代码片段:xxxxxxxxxxxxxxxx 继续调侃 某萌新:诶?真的诶,这样提问,好多问题都被解决了 某大佬:这问题问得是真的好,多来点这样的问题,回答也舒坦
2020-01-03 - 云开发入门
重磅打造的小程序学习路径课,从微信小程序到微信云开发体系化的学习,带来更加顺畅的学习体验。
2021-11-19 - 云开发快速入门
如果你想免费、快速的开发出一个完整的项目,用小程序的云开发可能是最好的选择。小程序的云开发所用到的主要是前端开发的知识。 注册微信小程序 小程序的注册非常方便,打开小程序注册页面,按照要求填入个人的信息,验证邮箱和手机号,扫描二维码绑定你的微信号即可,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 - 小程序图片裁剪插件 image-cropper
之前的插件类目没有了导致搜不到了,重新发个文章。 image-cropper 一款高性能的小程序图片裁剪插件,支持旋转。 [图片] 优势 [代码]1.功能强大。[代码] [代码]2.性能超高超流畅,大图毫无卡顿感。[代码] [代码]3.组件化,使用简单。[代码] [代码]4.点击中间窗口实时查看裁剪结果。[代码] ㅤ 初始准备 1.json文件中添加image-cropper [代码] "usingComponents": { "image-cropper": "../image-cropper/image-cropper" }, "navigationBarTitleText": "裁剪图片", "disableScroll": true [代码] 2.wxml文件 [代码]<image-cropper id="image-cropper" limit_move="{{true}}" disable_rotate="{{true}}" width="{{width}}" height="{{height}}" imgSrc="{{src}}" bindload="cropperload" bindimageload="loadimage" bindtapcut="clickcut"></image-cropper> [代码] 3.简单示例 [代码] Page({ data: { src:'', width:250,//宽度 height: 250,//高度 }, onLoad: function (options) { //获取到image-cropper实例 this.cropper = this.selectComponent("#image-cropper"); //开始裁剪 this.setData({ src:"https://raw.githubusercontent.com/1977474741/image-cropper/dev/image/code.jpg", }); wx.showLoading({ title: '加载中' }) }, cropperload(e){ console.log("cropper初始化完成"); }, loadimage(e){ console.log("图片加载完成",e.detail); wx.hideLoading(); //重置图片角度、缩放、位置 this.cropper.imgReset(); }, clickcut(e) { console.log(e.detail); //点击裁剪框阅览图片 wx.previewImage({ current: e.detail.url, // 当前显示图片的http链接 urls: [e.detail.url] // 需要预览的图片http链接列表 }) }, }) [代码] 参数说明 属性 类型 缺省值 取值 描述 必填 imgSrc String 无 无限制 图片地址(如果是网络图片需配置安全域名) 否 disable_rotate Boolean false true/false 禁止用户旋转(为false时建议同时设置limit_move为false) 否 limit_move Boolean false true/false 限制图片移动范围(裁剪框始终在图片内)(为true时建议同时设置disable_rotate为true) 否 width Number 200 超过屏幕宽度自动转为屏幕宽度 裁剪框宽度 否 height Number 200 超过屏幕高度自动转为屏幕高度 裁剪框高度 否 max_width Number 300 裁剪框最大宽度 裁剪框最大宽度 否 max_height Number 300 裁剪框最大高度 裁剪框最大高度 否 min_width Number 100 裁剪框最小宽度 裁剪框最小宽度 否 min_height Number 100 裁剪框最小高度 裁剪框最小高度 否 disable_width Boolean false true/false 锁定裁剪框宽度 否 disable_height Boolean false true/false 锁定裁剪框高度 否 disable_ratio Boolean false true/false 锁定裁剪框比例 否 export_scale Number 3 无限制 输出图片的比例(相对于裁剪框尺寸) 否 quality Number 1 0-1 生成的图片质量 否 cut_top Number 居中 始终在屏幕内 裁剪框上边距 否 cut_left Number 居中 始终在屏幕内 裁剪框左边距 否 [代码]img_width[代码] Number 宽高都不设置,最小边填满裁剪框 支持%(不加单位为px)(只设置宽度,高度自适应) 图片宽度 否 [代码]img_height[代码] Number 宽高都不设置,最小边填满裁剪框 支持%(不加单位为px)(只设置高度,宽度自适应) 图片高度 否 scale Number 1 无限制 图片的缩放比 否 angle Number 0 (limit_move=true时angle=n*90) 图片的旋转角度 否 min_scale Number 0.5 无限制 图片的最小缩放比 否 max_scale Number 2 无限制 图片的最大缩放比 否 bindload Function null 函数名称 cropper初始化完成 否 bindimageload Function null 函数名称 图片加载完成,返回值Object{width,height,path,type等} 否 bindtapcut Function null 函数名称 点击中间裁剪框,返回值Object{src,width,height} 否 函数说明 函数名 参数 返回值 描述 参数必填 upload 无 无 调起wx上传图片接口并开始剪裁 否 pushImg src 无 放入图片开始裁剪 是 getImg Function(回调函数) [代码]Object{url,width,height}[代码] 裁剪并获取图片(图片尺寸 = 图片宽高 * export_scale) 是 setCutXY X、Y 无 设置裁剪框位置 是 setCutSize width、height 无 设置裁剪框大小 是 setCutCenter 无 无 设置裁剪框居中 否 setScale scale 无 设置图片缩放比例(不受min_scale、max_scale影响) 是 setAngle deg 无 设置图片旋转角度(带过渡效果) 是 setTransform {x,y,angle,scale,cutX,cutY} 无 图片在原有基础上的变化(scale受min_scale、max_scale影响) 根据需要传参 imgReset 无 无 重置图片的角度、缩放、位置(可以在onloadImage回调里使用) 否 GitHub https://github.com/wx-plugin/image-cropper/tree/master 如果有什么好的建议欢迎提issues或者提pr
2021-12-15