- 微信小程序如何引入npm包?
前言 你还在下载源码复制到项目中去使用吗?现在已经不需要了! 从小程序基础库版本 2.2.1 或以上、及开发者工具 1.02.1808300 或以上开始,小程序支持使用 npm 安装第三方包。 接下来我们以npm引用 dayjs 库为案例。 dayjs:一个轻量的处理时间和日期的 JavaScript 库,和 Moment.js 的 API 设计保持完全一样. 如果您曾经用过 Moment.js, 那么您已经知道如何使用 Day.js。 Moment.js 的 2kB 轻量化方案,拥有同样强大的 API [代码] dayjs() .startOf('month') .add(1, 'day') .set('year', 2018) .format('YYYY-MM-DD HH:mm:ss') [代码] 🕒 和 Moment.js 相同的 API 和用法 💪 不可变数据 (Immutable) 🔥 支持链式操作 (Chainable) 🌐 国际化 I18n 📦 仅 2kb 大小的微型库 👫 全浏览器兼容 地址:https://github.com/iamkun/dayjs 引用步骤 打开调试器区域的【终端】面板。 [图片] 输入[代码]npm init[代码],然后填写初始化信息,默认值可以按回车。 填写完成后,会生成一个package.json文件。 [图片] 安装 dayjs:在终端输入 [代码]npm install dayjs --save[代码] 点击开发者工具中的工具栏:详情 --> 本地设置 --> 勾选【使用 npm 模块】 [图片] 点击开发者工具中的菜单栏:工具 --> 构建 npm [图片] 引入使用 [图片] dayjs 详细使用文档:https://day.js.org/zh-CN/
2020-09-30 - 解析project.config.json文件失败,请检查其内容或删除此文件
在开发者工具中新建项目,修改project.config.json时弹出如下弹窗[图片] 代码内部只删了pages/logs还有utils,如下图:[图片] 调试微信开发者截图如下:[图片] 环境:电脑是win7系统,开发者工具版本1.03.2005140,稳定版。 项目目录:A:\项目\小程序\测试项\test02 采取方法:重登开发者工具,卸载开发者工具,更换开发者工具安装目录方式都没起作用。 还请哪位大神或官方有时间帮忙看下,谢谢。
2020-06-10 - 云开发实战教程
用云开发来做一个小程序的功能与实战教程,讲解核心能力如何用云开发实现,例如:用户管理、小程序码、短信应用、分享卡片等。
2022-03-28 - 在云函数中查询数据
1 云函数应用课程·在云函数中查询数据 [视频] 2 云函数应用课程·在云函数中新增数据 [视频] 3 云函数应用课程·在云函数中删除数据 [视频] 4 云函数应用·在云函数中编辑数据 [视频] 5 云函数应用课程·在云函数中使用存储资源 [视频] 6 云函数应用课程·在云函数中访问第三方服务 [视频] 7 访问数据库 [视频]
2021-09-13 - 云开发入门
重磅打造的小程序学习路径课,从微信小程序到微信云开发体系化的学习,带来更加顺畅的学习体验。
2021-11-19 - 开发实战分享|小程序扫码获取图书信息(内附详细教程)
作者:祈澈姑娘 小程序扫码实现读取isbn,获取图书的各种信息 接触到云函数已经有一段时间了,之前一直在看api,现在自己跟着网络上的资料和视频学习,受到豆瓣读书系列的启发,决定用云函数做一个项目,获取图书信息并存入云数据库。 基本流程 [图片] 1.用户端小程序调用 wx.scanCode接口,获取到ISBN码。 2.使用ISBN码调用云函数,在请求云函数的时候,云函数会请求豆瓣的API,获取豆瓣图书信息。 3.图书信息请求到之后,会将其中无用的信息返回给小程序中,小程序中再拿出获取到的信息,创建图书条目。 4.将对应的数据直接存储到云开大的数据库里面。 具体步骤 下面对该项目的步骤进行一些具体的讲解以及部分关键代码的呈现。 一、扫一扫获取图书ISBN码 二、准备环境、安装依赖 1.安装Node.js准备环境 2.在cmd打开云函数目录中,安装依赖 三、编写云函数代码 1.在云函数中用获取到的ISBN传参 2.编写用户端(小程序端代码) 3.编写云函数端代码 四、调用豆瓣API获取具体数据 五、将获取到的API数据存入云数据库里面 1.初始化 2.添加数据 六、云数据库读取的数据显示在小程序端列表里 1.获取res.data 2.设置界面相关数据 3.显示和布局 4.小程序wxml界面(主要demo) 七、【云开发】首页列表跳转详情页 1.新建一个详情页 2.按钮跳转事件 3.跳转到具体详情页 4.关于详情页的一些代码 一、扫一扫获取图书ISBN码 用户端小程序调用 wx.scanCode接口,获取到图书ISBN码(图书条形码),在办公室找了一圈,找到了一本图书ISBN码,可以自动忽略我这渣渣的像素。 [图片] 关键代码 [代码]// pages/scanCode/scanCode.js Page({ /** * 页面的初始数据 */ data: { }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { }, scanCode: function (event) { console.log(1) // 允许从相机和相册扫码 wx.scanCode({ onlyFromCamera:true, scanType:['barCode'], success:res=>{ console.log(res.result) }, fail:err=>{ console.log(err); } }) } }) [代码] ok,获取到信息: [图片] 二、准备环境、安装依赖 1.安装Node.js准备环境 安装nodejs,准备好环境,这一步就不细说了,没有安装的可以自行百度,不知道有没有安装的可以输入 node -v 查看一下。 2.在cmd打开云函数目录中,安装依赖 输入命令: [代码]npm install --production [代码] 依赖安装成功之后,文件里面多会出现 [代码]package-lock.json[代码]这个文件。 三、编写云函数代码 1.在云函数中用获取到的ISBN传参 云函数API: https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-client-api/functions/callFunction.html 通过看文档可以学会,在云函数里,我们可以通过传递一份data来获取这里面的数据,然后再通过event来拿到对应的数据。 复制这个api里面的方法: [图片] 打开实战一里面写的小程序端的扫码的js界面,把这个方法放在 [代码]success[代码]里面。 要调用的云函数的名称 [代码]name[代码]要改成成实战二教程里面建立的云函数[代码]bookinfo[代码]: [图片] 传递的参数是 [代码]isbn[代码],结果是扫码得到的[代码]result[代码]: [图片] 2.编写用户端(小程序端代码) 将 [代码]result[代码]的结果打印出来,ok,用户端(小程序端)代码写好了。 用户端(小程序端)代码写完了,就这些: [代码]// pages/scanCode/scanCode.js Page({ /** * 页面的初始数据 */ data: { }, scanCode: function(event) { console.log(1) // 允许从相机和相册扫码 wx.scanCode({ onlyFromCamera: true, scanType: ['barCode'], success: res => { console.log(res.result) // wx.cloud.callFunction({ // 要调用的云函数名称 name: 'bookinfo', // 传递给云函数的参数 data: { isbn: res.result }, success: res => { console.log(res) }, fail: err => { console.error(res) } }) }, fail: err => { console.log(err); } }) } }) [代码] 3.编写云函数端代码 打开 [代码]bookinfo[代码]里面的 [代码]index.js[代码],将 [代码]event[代码]结果打印出来,请求云函数,将云函数之中的 [代码]isbn[代码]返回回来。 [代码]// 云函数入口文件 // const cloud = require('wx-server-sdk') // cloud.init() // 云函数入口函数 //var rp = require('request-promise') exports.main = async (event, context) => { console.logI(event); return event.isbn // var res = rp('https://api.douban.com/v2/book/isbn/' + event.isbn).then(html => { // return html; // }).catch(err => { // console.log(err) // }) //return res // const wxContext = cloud.getWXContext() // return { // event, // openid: wxContext.OPENID, // appid: wxContext.APPID, // unionid: wxContext.UNIONID, // } } [代码] 上传并且部署云函数。 测试一下,云函数调用成功,返回的结果(控制台打印)是isbn: [图片] 四、调用豆瓣API获取具体数据 在网上找了一下,找到了一个可以用的豆瓣API: https://api.douban.com/v2/book/isbn/:9787111128069 打开云函数文件夹,index.js里面编写代码,引用request promise: [代码]var rp = require('request-promise') [代码] 自定义的isbn,使用一个+号来连接,在传递一个catch来处理错误情况: [代码]var res = rp( 'https://api.douban.com/v2/book/isbn/'+event.isbn).then(html=>{ return html;}).catch(err=>{ console.log(err)}) [代码] [代码]returnres[代码]res就是对应的html,将html传给用户端后,上传云函数。 继续测试一下,拿到这个条形码的信息了(书本的信息): [图片] [图片] 对于这些信息,进一步处理,拿到自己想要的信息。 打开小程序端scanCode.js: [代码] //进一步的处理方法 var bookString=res.result; console.log(JSON.parse(bookString)) [代码] [图片] 看到了整本图书上面的所有信息,修改这些信息,存入云数据库之中即可。 五、将获取到的API数据存入云数据库里面 1.初始化 使用数据库的时候,首先要进行初始化: 云开发数据库文档: https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/database/init.html 打开云开发控制台创建一个集合books。 打开小程序端js,初始化数据库: [代码] //云数据库初始化 const db = wx.cloud.database({}); const book = db.collection('books'); [代码] 2.添加数据 js代码流程: [代码]// pages/scanCode/scanCode.js Page({ data: { }, scanCode: function (event) { console.log(1) // 允许从相机和相册扫码 wx.scanCode({ onlyFromCamera: true, scanType: 'barCode', success: res => { console.log(res.result) wx.cloud.callFunction({ // 要调用的云函数名称 name: 'bookinfo', // 传递给云函数的参数 data: { isbn: res.result }, success: res => { // console.log(res) //进一步的处理 var bookString = res.result; console.log(JSON.parse(bookString)) //云数据库初始化 const db = wx.cloud.database({}); const book = db.collection('books') db.collection('books').add({ // data 字段表示需新增的 JSON 数据 data: JSON.parse(bookString) }).then(res => { console.log(res) }).catch(err => { console.log(err) }) }, fail: err => { console.error(res) } }) }, fail: err => { console.log(err); } }) } }) [代码] 六、云数据库读取的数据显示在小程序端列表里 1.获取res.data 参考的读取api,请点击: https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/database/read.html 初始化实例和book方法: [代码] //云数据库初始化 const db = wx.cloud.database({}); const book = db.collection('books') [代码] 复制API这段代码获取多个记录的数据的方法,放在项目到onload方法之中。 打印在控制台: [图片] 2.设置界面相关数据 拿到res.data之后,要赋值给page实例里面的data,所以在data里面设置一个默认的空数组: [图片] 创建一个变量来保存页面page示例中的this,方便后续使用,也可以使用箭头函数来打印一下this,看是不是page示例: [代码]const db = wx.cloud.database({}); const cont = db.collection('books'); Page({ data: { book\_list:[] }, onLoad: function(options) { // 创建一个变量来保存页面page示例中的this, 方便后续使用 var _this=this; db.collection('books').get({ success: res =>{ console.log(res.data); console.log(this); } }) }, }) [代码] [图片] 直接使用this来设置data: [图片] 3.显示和布局 使用组件库引入,可以省略自己写很多代码的样式,简单方便,当然也可以自己写:https://youzan.github.io/vant-weapp/#/card 因为数据不止一条,循环,所以要用到小程序框架的列表渲染: https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/list.html 写好之后 wxml如下: [代码]<text>私家书柜</text> <view wx:for="{{book\\_list}}"> <van-card num="2" price="2.00" desc="描述信息" title="商品标题" /> </view> [代码] 4.小程序wxml界面(主要demo) wxml: [代码]<view wx:for="{{book\\_list}}"> <van-card num="2" price="{{item.price}}" desc="{{item.author}}" title="{{item.title}}" thumb="{{item.image }}" /> </view> [代码] js: [代码]const db = wx.cloud.database({}); const cont = db.collection('books'); Page({ data: { book_list:[] }, onLoad: function(options) { // 创建一个变量来保存页面page示例中的this, 方便后续使用 var _this=this; db.collection('books').get({ success: res =>{ console.log(res.data[0]); this.setData({ book_list:res.data }) } }) }, }) [代码] ok,云数据库读取的数据显示在小程序端列表里。 七、【云开发】首页列表跳转详情页 1.新建一个详情页 打开app.json, [代码]"pages/details/details",[代码],自动生成了一个详情页: [图片] 2.按钮跳转事件 打开首页列表页代码,绑定详情按钮跳转事件。 wxml: [代码]<view wx:for="{{book\\_list}}"> <van-card num="2" price="{{item.price}}" desc="{{item.author}}" title="{{item.title}}" thumb="{{item.image }}"> <view slot="footer"> <van-button size="mini" bind:click="viewitem">详情按钮</van-button> </view> </van-card> </view> [代码] [图片] 继续写js里面的绑定事件,在控制台打印一下event,方便后续测试: [代码]viewitem: function(event) { console.log(event) } [代码] 3.跳转到具体详情页 要在云开发里面写一个特定的id,打开云开发控制台,数据库,需要用到这个下划线是_id的字段: [图片] 给这个字段设置一个值,[代码]data-id="{{item._id}}"[代码]: [图片] 点击按钮,可以看到,点击不同的列表,打印的是不同的id,通过不同的id就可以看到不同的内容了: [图片] 4.关于详情页的一些代码 初始化db的实例: [代码]const db = wx.cloud.database({}); [代码] 打开云函数文档里面的读取数据api: https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/database/read.html 复制此段读取数据记录的代码,放在onload里面: [图片] 可以看到,具体数据已经打印过来了: [图片] 这个时候还没有将数据传递到一个具体的页面实例中: [图片] 所以,success开始改成使用箭头函数,进入页面的时候,可以看到appdata里面的book: [图片] 具体展示:在wxml里面写上想要拿到的数据,ok,详情页面展示的数据: [图片] 效果如下: [图片] 这样,我们就完成了利用云开发扫码读取ISBN码并获取图书各种信息的全部步骤啦~
2019-04-17 - 微信云开发基础能力讲解
云数据库、云存储、云函数、云调用等云开发基础能力的使用介绍 [视频] 点此跳转:小程序云开发训练营活动页面
2021-11-26 - 个人店 - 店铺运营(完整)
该课程为个人店的店铺运营指南,包括后台各功能模块的使用和操作指引。 助力您开店后成功卖货,快来看看吧~ [视频] [图片][图片] 以下是「个人店-店铺运营」模块操作指引的PPT版本,欢迎大家继续对照查看~ [图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片][图片] 更多资讯,欢迎到【交流专区】微信小商店主页发帖和寻找答案。
2022-04-13 - 微信开放社区成长中心
[图片] [图片]
2019-12-23 - 【必收】精心整理!小程序开发资源汇总(附带源码)
很多小伙伴想在春节放假期间学小程序,但是小程序学习的资源和教程可能不太好找。所以小助手精心整理了一期,全是干货!认真学,开启美妙的小程序开发之旅,做一个属于自己的微信小程序。有需要的小伙伴收藏好这期文章哦~ 本文收集整理了微信小程序开发资源,包括官方文档,云开发训练营文档,视频教程以及实战源码推荐,会不间断更新。。 欢迎添加云开发小助手CloudBase微信:Tcloudedu1 ,一起加入技术交流群~ 小程序云开发官方公众号 [图片] 目录 官方文档 云开发训练营 视频教程 小程序·云开发Demo 技术交流群 官方文档 小程序开发者工具 小程序设计指南 小程序开发教程 小程序框架 小程序组件 小程序API 小程序开发者工具 小程序云开发文档 云开发训练营 小程序开发入门 小程序与JavaScript 云开发快速入门 [图片] 视频教程 腾讯云云开发B站:https://space.bilibili.com/447496276 [图片] 小程序·云开发Demo 技术博客小程序 包括文章的发布及浏览、评论、点赞、浏览历史、分类、排行榜、分享、生成海报图等。 网盘小程序 兼具文件存储与分享功能的专属网盘小程序。 教务助手小程序 用完即走,查个成绩和课表,无需下载app或去翻看公众号内的历史内容。 功能日历小程序 既能查看日历又能备注事项,看云开发如何支持功能性日历小程序的快速开发。 客户业务需求收集小程序 用云开发快速制作客户业务需求收集小程序,教你用云开发实现小程序版“朋友圈”的发布与展示。 小程序朋友圈 把朋友圈装进小程序需要几步?借助云开发实现小程序朋友圈的发布与展示。 南苑导览 一款由学生独立开发的以地图为载体,提供中山大学南方学院具体地点的位置信息、导航、校园历史及文化介绍的小程序。 互动打卡小程序 用云开发轻松构建精美互动打卡小程序,交互式双人打卡,快乐加倍。 个性头像小程序 别再@官方啦!云开发教你轻松制作个性头像小程序,趣味挂件、个性icon。 二手书商城小程序 云开发轻松制作二手书交易商城小程序,让智慧延续,让温暖传递。 后台数据批量导出 小程序开发过程中如何将云数据库中的数据批量导出至excel。 发送邮件 初学者福音,手把手教你用小程序云开发实现邮件发送功能。 高考查分小程序 实现高考分数轻松查,小程序源码。 mini论坛 仅需两天轻松搭建mini论坛小程序。 运动圈小程序 打造运动圈小程序(以乒乓球为例),实现球友间高效互动。 心情日记小程序 我能想到最浪漫的事,可能就是“你的心事我全知晓”。 最美恋爱小程序 小程序前端用的是taro框架写的,后台用的云开发。教你用云开发为心爱的人做个小程。 校园约拍小程序 校园场景下,小程序·云开发大显身手,校园约拍小程序源码。 体重记录小程序 只想记录每日体重还得下个APP,不用那么麻烦!用云开发做个专属体重记录小程序,看看你每天瘦了多少。 口袋工具 口袋工具之历史上的今天。一个基于云开发的小程序,看看历史上的今天都发生了啥。 迷你微博 独立做个精简版微博出来让你刷刷刷吗?而且,它还兼具搜索、点赞、主页的功能 多媒体小程序 使用小程序·云开发构建多媒体小程序。 技术交流群 交流技术为主,开发学习工作中遇到问题可以在群内交流,欢迎有需要的朋友加群。 添加小助手微信(Tcloudedu1),回复“技术群”,即可加入云开发技术群。 最后 如果你有关于使用腾讯云云开发相关的技术故事/技术实战经验想要跟大家分享,欢迎留言联系我们~ 关注腾讯云云开发,后台回复【源码】,获取更多微信小程序云开发实战源码。 [图片] [图片] [图片] 关注「腾讯云云开发」,后台回复【 源码 】,获取更多微信小程序云开发实战源码。 持续更新中… [图片]
2020-01-16 - 2019年微信小程序开发大赛总结
首先,感谢微信官方举办这一次【微信小程序大赛】大学生专属活动,能让我们更好的去学习,并且锻炼自己。 [图片] 高手请忽略 作为一个真正的菜鸟,在此次活动中我学到了很多: 如何能够更好地与小伙伴沟通?【执行力】 在技术层次上,怎么学习才是正确的? 怎么正确对待技术? 本次项目开发的相关学习经验。 第一:如何解决开发项目时执行力的问题。 此次比赛是面的全体高校学生,个人技术水平的差异+跨地区组合,怎么才能发挥出一个小团队高效的执行力呢?(以下是个人在开发项目时的经验) 正确对待比赛,以锻炼为主。如果是为了拿奖,首先这个想法在一定程度上是错误的。我们团队的愿景就是:锻炼自己为主。边学习边开发,所以在开发项目时团队氛围很好。 约定好时间,组建QQ群开语音来同时开发项目这对于一个团队项目的成果是很重要的,因为我相信如果你愿意挤出你周末休息的时间来学习,不会太差。 定制计划,每周做了什么,学到了什么。 在学习的过程中要学会总结,把用法,钩子函数,语法,关键字,get,post,jsonp请求处理数据等等自己做一个总结 而且有的小伙伴想考研究生,所以你也应该提前准备一下,因为据我了解,研究生也有每周项目计划表 第二:怎么去更好的学习技术【小程序技术路线】 刚学习计算机的小伙伴一脸懵逼,尤其在自己没有参加培训机构,没有开发经验的情况下要完成这样的项目,我当初都不敢想。我们是这么做的: 从基础入手,html,css,js,jq,es6语法,mvc模型 学习官文文档,非常重要 各种地方寻找免费的小程序开发教程 死磕,没其他办法,技术就是这样 学到一定程度,你可以接触一些ajax,node,vue,webpack等知识 充分理解面向对象与闭包,跨域,文件处理,KOA,正则,Express等为架构师先打下一定基础 我最近也是花了好大力气搞到一份2019年黑马程序员联合出品的架构师视频,可以免费分享给看到的学生,我看了差不多俩星期,感觉不错,我也是学生,能理解各位追求技术的热情,希望我们一起学习,加油。 第三:怎么正确对待技术? 菜不可怕,可怕的是你菜,还在群里只吹不做 1. 技术驱动永远是建立在解决需求的层次上。 2.北上广技术大佬多的是,别学了点东西就沾沾自喜,学会谦虚。 第四:本次项目开发的相关学习经验 1. 小程序的相关语法以及table栏的动画效果。 2. 引入框架,学习了vue等前端框架的知识。 3. 排版以简洁易操作为主,培养用户的懒习惯。等等 4.了解了生产环境与开发环境 5.MVC模型与MVVM模型的区别等等 因为我本身很菜,所以我没有运营经验,但我想法是:要专注作品本身,踏踏实实做事运营这方面都是后期的事。 好像没什么可以说的了,文采不好,各位见谅。 再次致谢微信官方,同时也感谢我们队伍的3个小伙伴,谢谢这缘分让我们能组队到一起,接下来的日子里要更好的学习哦 ------------------小程序队伍:太岳军区386旅独立团 ----------------------------时间:2019年6月3日
2019-06-04 - 征文大学篇 - 云开发·后端鉴权思路分享
[图片] 使用场景介绍 微信小程序的进入形式决定了它更适合充当一种“工具”的角色,适合在用户想起它、要用它的时候主动启动。基于此想法,中大猫谱小程序主要服务于猫猫信息记录、搜索的功能,旨在帮助改善校园流浪猫的生存状况、帮助大众了解猫猫及救助知识,同时帮助动保组织管理猫猫资料、募集救助(绝育、治疗)流浪猫所需的资金,为生态环境保护献一份力。 (— 广告时间结束 —) 如我们所知,微信小程序对于所有用户来说,入口都是统一的。目前,官方还没有提供配置管理员id的操作。那么,如果要将一些管理页面整合到小程序中,鉴权操作是非常必要的。例如,在中大猫谱中,普通用户和管理员用户看到的页面元素、能进入的页面是不同的: [图片] 基于这种需求,本文将分享一种在微信·云开发环境下,实现简单、安全的后台鉴权的思路。 云函数实现 在描述方法前,我们先简单介绍一下微信·云开发的三大部件,分别是做啥用的: 云函数:后端的自定义的业务逻辑函数,自带Node.js环境。可以被小程序端调用,通常用于操作云存储和云数据库。拥有微信私有协议天然鉴权(后文重点使用)。 存储:类似云盘,存文件用的,自带CDN(流量不多)。它提供的[代码]cloud://[代码]协议文件链接可以直接用于部分小程序端tag上,比如image的src,但也就不会被缓存。 数据库:一个文档型数据库,可以被小程序端直接使用。权限设置比较迷(为了安全),大部分修改、删除操作要经过云函数来调用。 我们重点关注云函数。开通云开发后,新建一个云函数,我们会得到一个初始模板: [代码]// 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() // 云函数入口函数 exports.main = async (event, context) => { const wxContext = cloud.getWXContext() return { event, openid: wxContext.OPENID, // 调用者的openid,与每个微信号一一对应,用于鉴权 appid: wxContext.APPID, unionid: wxContext.UNIONID, } } [代码] 其中,云函数接受两个参数,[代码]event[代码]是用户调用时提供的data(可理解为形参),[代码]context[代码]是此处调用的调用信息和运行状态。幸运的是,这两个东西我们暂时都用不到,不理解也没有关系。 我们关注函数体的第一句[代码]cloud.getWXContext()[代码],它正是前文提到的微信私有协议天然鉴权。换人话说,这个函数返回的所有资料,都是有微信背书的、可信的。那么,最简单的鉴权方式,就是把管理员的openid硬编码到云函数中,对比一下就完成了: [代码]// isManager云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() // 硬编码管理员的openid const MANAGERS = ['aaaaaaa', 'bbbbbbb', 'cccccccc']; // 云函数入口函数 exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); const openid = wxContext.OPENID; // 取得当前用户openid return MANAGERS.includes(openid); // 完成鉴权 } [代码] 灵活一些 假如说我们的管理员常年不变,那上面那种鉴权方式完全够用了。但如果我们的管理员经常增删,那就利用云存储功能,建立一个[代码]manager[代码]集合(collection),把管理员的openid存放到文档中(听不明白请看下图)。那么上面硬编码的部分,就改为数据库查询: [代码]// isManager云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() // 初始化数据库链接 const db = cloud.database(); const _ = db.command; // 云函数入口函数 exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); const openid = wxContext.OPENID; // 查询条件 const filter = { openid: openid }; // 等待数据库查询 const count = (await db.collection('manager').where(filter).count()).total; // 检查是不是管理员 return (count === 1); } [代码] 现在管理管理员的方式(没打错字)更灵活了,可以直接打开小程序云开发控制台来添加/删除一个管理员。 [图片] 小程序端调用 在小程序端,我们可以简单包装一个鉴权函数,用callback的方式灵活地用在各种需要鉴权的地方: [代码]function checkManager(callback) { // 这里的callback将接受一个参数res, // 为bool类型,当前用户为manager时为true, // 否则为false // 调用云函数 wx.cloud.callFunction({ name: 'isManager', // 指明云函数的名字,没有形参 }).then(res => { // res是云函数的返回值,形如: // {errMsg: "cloud.callFunction:ok", result: true, requestID: "44b0xxxx-8xxx-xxxx-xxxx-xxxx0068xxxx"} // 其中的result字段是我们所需要的鉴权结果 callback(res.result); }); } [代码] 给定不同的回调函数,就可以简单地完成各种权限控制任务。例如,在某个Page的[代码]onLoad[代码]中控制元素显示: [代码]const that = this; checkManager(res => { if (res) { that.setData({ showBtns: true }); } }) [代码] 上面的鉴权操作,对非管理员用户的影响几乎没有。假如普通用户确实“闯进”了不该进入的页面,也可以简单地在上面加个else分支显示提示。 安全性分析 有了云函数的啥啥啥背书(微信私有协议天然鉴权),我们不用担心用户伪造openid的问题。但是,如果有中间人篡改了服务器发来的消息(说的就是你Mallory),小程序端获得的鉴权结果已经被修改了,那这种鉴权也不太可靠。因此,在一些关键的操作(例如数据库修改)上,鉴权和实际操作都应该放在后端云函数中,一条龙完成。 幸运的是,我们上面实现的[代码]isManager[代码]云函数仍可发光发热,被其他云函数调用。但是,间接调用的云函数无法获取调用者的OPENID(因为调用者不是一个微信用户,而是另一个云函数),我们要对上面的[代码]isManager[代码]函数进行一点点修改: [代码]// isManager云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() // 初始化数据库链接 const db = cloud.database(); const _ = db.command; // 云函数入口函数 exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); const openid = wxContext.OPENID || event.openid; // !! 只修改了这里:如果不能获取openid,就从参数event里取 // 查询条件 const filter = { openid: openid }; // 等待数据库查询 const count = (await db.collection('manager').where(filter).count()).total; // 检查是不是管理员 return (count === 1); } [代码] 其中修改只有一行:[代码]const openid = wxContext.OPENID || event.openid;[代码],这意味着如果[代码]cloud.getWXContext()[代码]函数返回的结果里不包含openid,那就从调用时给的参数[代码]event[代码]里取(说明当前调用是由其他云函数发起的)。 稍做修改后,在其他云函数中,只需在函数体最前面,增加以下几行,即可完成后端的安全鉴权: [代码]////// 省略一些初始化代码 ////// // 其他需要后端验证的云函数入口 exports.main = async (event, context) => { // 获取调用者的openid const wxContext = cloud.getWXContext(); const openid = wxContext.OPENID; // 用data参数的形式,把openid传给isManager云函数 const isManager = (await cloud.callFunction({ name: 'isManager', data: { openid: openid }})); // 如果不是管理员,直接886 if (!isManager.result) { return { msg: 'not a manager', result: isManager }; } ////// 下面放这个云函数要做的业务逻辑 ////// } [代码] 小总结 本文介绍了在微信小程序云开发环境下,利用云函数中微信背书的openid进行用户鉴权的一种思路。有了管理员鉴权接口、小程序端可以控制页面元素展示、路由访问、接口调用等情况,保护数据安全。目前小程序云开发的资料较少,本文也只是一种简单鉴权的实现思路,肯定还存在许多不足,希望大家多多交流、多多指正! 广告时间 今年上半年,中山大学四校区合拍的中大猫谱小程序正式开机,我们将与你一起继续扮演云吸猫爱好者、校园猫猫摄影大师、环境保护热心人士,希望大家多多关注,多多支持! 小程序演示视频请戳:https://v.qq.com/x/page/u0882tecle7.html [图片]
2019-06-28 - #小程序大赛# 如何以产品视角打造一款小程序?
[图片] 5月31日,小程序大赛作品提交,终于告一段落。 这段时间,相信很多同学和我们一样,在项目过程中积累、收获了不少经验,或是设计,或是开发,或是其他,都能从不同角度体会到小程序大赛的意义。今天,我想分享一下,在项目过程中,是如何以一种产品的视角,去打造小程序“ddl冲鸭”。扫描下方小程序码即可体验哦~ [图片] 【写在前面】虽然本文是个人撰写,但小程序项目是团队共同完成,无论如何,在这里都应该先致谢我们“咕咕咕”队伍的指导老师和参赛队友,以及各位作为体验用户、帮忙测试程序并给予意见反馈的朋友。 本文篇幅较长,主要包括以下内容: 一、产品定位——目标用户与主要功能 二、产品灵感——为什么选择小程序“ddl冲鸭”? 三、关注用户——从用户角度进行需求分析与功能设计 四、竞品现状——我们如何做得比他人更好? 五、精益求精——抓住用户心理进行产品设计 六、把握细节——优化产品体验,提高用户粘性 七、创新运营——产品已从0到1,还要从1到100 八、小结 感谢阅读。 一、产品定位——目标用户与主要功能这次参赛作品是微信小程序“ddl冲鸭”,主要目标用户是高校学生,主要是为了解决大学生ddl记录、管理需求。“ddl”即“deadline”,意为“最后期限/截止时间”,相信很多同学对这个词并不陌生,甚至内心有着强烈的共鸣。大学生日常ddl:提交作业的ddl,提交社团工作方案的ddl,提交比赛作品的ddl……日常ddl任务繁多,高效记录与管理成一大需求。 然而,目前市场上并没有针对ddl推出的产品,因此,针对性地解决用户需求、并实现产品的特色化功能,可成为产品的一大亮点。 “ddl冲鸭”的主要功能有: (1)记录ddl(可设置ddl分类、使用文本或语音记录、上传相关图片、选择相关位置等); (2)通过将ddl设为星标、设置分类,以及查看不同状态,高效地管理ddl; (3)通过分享ddl,让好友了解自己的ddl,更可将好友的类似ddl(如同班同学具有共同的班级作业)直接添加为自己的ddl,简化手动创建步骤; (4)发起群组ddl,小组好友共同为ddl努力,交流感想,促进完成; (5)消息提醒功能,如ddl过期提醒等。 [图片] [图片] 由于介绍作品功能并非本文重点,更多详情可查看以下演示视频: [视频] 如果您看完了演示视频,相信接下来的大部分内容都更加易懂。 二、产品灵感——为什么选择小程序“ddl冲鸭”?同样作为大学生,我们深感ddl在大学日常生活中的影响,推出“ddl冲鸭”,在为自己解决需求的同时,也希望它能够给更多人带来方便。因此,我们从实际出发,着重于解决ddl记录、管理需求,并在此基础上力求创新、创意。 小程序的命名: 我们很熟悉的微信、淘宝、饿了么这些产品的命名,基本都是通过名称就可以比较直观地体现主要功能,同时又避免枯燥无味而缺乏新意。比如,微信为什么不叫“信息”,淘宝为什么不叫“购物”,饿了么为什么不叫“叫外卖”,所以产品的命名还是比较重要的。 “ddl”不仅与主题对应,同时引起目标用户内心强烈共鸣,也让用户对产品的主要功能有初步设想;“冲鸭”即“冲呀”,结合了当下的网络流行词语,符合大学生的喜好。同时,小程序命名也体现了希望用户在面对ddl时向前冲、加油努力。 小程序的出现,不是为了取代手机app,它是为了在适当的情景下,更好地为用户提供服务。如小程序官方所介绍的,它无需下载,实现了应用“触手可及”的梦想,也体现了“用完即走”的理念。相对app,小程序开发门槛较低,能够满足用户的简单需求,同时,结合微信本身为小程序奠定的基础,如“搜一搜”等,也有利于产品运营、降低引流成本。 相信使用iPhone的朋友都了解,iOS 12有个新功能,可以统计每天使用手机上各款app的时长。不难发现,对于多数人来说,微信使用时长稳居第一,且占比极大。既然如此,我们也应该思考基于微信环境下,用户的使用习惯。“ddl冲鸭”在UI设计方面,以白色为主色,绿色为辅色,与微信7.0版本设计风格基本对应,能让用户产生高度融入之感。同时,风格简洁直观,让用户易懂易操作。用户长期使用微信的习惯也为小程序的使用带来了方便的基础,比如使用微信小程序可以方便用户充分利用碎片时间,进行ddl管理。 三、关注用户——从用户角度进行需求分析与功能设计相信之前有关注过2019微信公开课的朋友,应该都对张小龙的这句话比较熟悉:“我们应该关注用户,而不是竞争对手。”作为一个产品策划的角色,应该有着“用户至上”的基本理念,同理心、善于换位思考成为了必备基本技能之一。所以我们从用户的角度出发,注重用户的实际需求,进行需求分析、管理、功能设计。 从宏观到微观,整体的功能设计都应该以解决用户实际需求为基本原则。 我们以问卷收集、用户访谈、竞品调研等多种形式,挖掘用户需求,同时也是为了针对市场上已有竞品的不足,针对性进行弥补。 [图片] 具体的调研分析,这里不进行详细介绍,但我们大致得到了如下结论: (1)用户现状:ddl记录与管理需求存在,产品开发必要性强——这充分论证了我们产品定位的合理性; (2)竞品现状:目前市场无针对ddl产品,用户个性化需求未被满足——在针对ddl主题进行产品设计的同时,我们也应该针对用户的个性化需求,打造具有特色的产品; (3)用户关联:一般在完成任务中有一定的好友互动,群组任务也较为常见——我们据此设计了好友分享ddl、群组ddl等功能,满足用户的常见需求; (4)用户习惯:存在ddl紧迫感、未完成愧疚感、已完成成就感等——便于我们抓住用户习惯与心理特点,完善产品设计; (5)用户期望:希望需求得到满足,产品体验良好——实现功能后,应该注意细节,追求为用户提供最好的产品体验。 进行需求分析、分类后,应对其进行分类管理。不可能第一个版本就解决所有的需求,也没有这个必要,因为这样会导致开发成本大、风险也高、且发展空间小。我们会着重于解决基本型需求与期望型需求,在此基础上完善魅力型需求,从各种细节优化出发,力求在满足功能需求的基础上提升用户对产品的体验好感度。 四、竞品现状——我们如何做得比他人更好?有的人会说,“ddl冲鸭”不就是一个记事本工具那样的产品吗?不是这样的,我们针对ddl主题,并对比竞品,实现了许多特色化的功能。以下谈谈“ddl冲鸭”的几个功能上的亮点: (1)ddl记录 区别于传统的文本记录,“ddl冲鸭”加入了语音、图片、位置等多种不同形式的记录,多样化完善ddl记录,满足用户的个性化需求。 比如,有时用户觉得输入大段文字记录比较麻烦,就可以用语音记录;上课时拍到老师的PPT,不方便转换为文字,就可以用图片记录;需要到某地办理港澳通行证,ddl又与位置有关等。 [图片] (2)ddl管理 在ddl列表页面可以快速切换不同状态的ddl(全部、进行中、已完成、已删除、已过期),并可以通过设置ddl星标、分类等,快速筛选符合条件的ddl,还可以选择按最新创建时间、ddl时间为ddl列表排序,使原本繁琐的ddl列表变得一目了然; [图片] (3)管理进行中的ddl 相信大家都很了解,许多类似产品会在待办事项右侧显示剩余时间,如3天、5天等,而“ddl冲鸭”则在此基础上,根据剩余时间的不同,给予不同颜色的文本和不同长度的进度条进行提示,时间越少时文字颜色越深(从绿色到黄色、橙色、红色)、同时进度条长度越小,从视觉上给予用户ddl紧迫之感,督促用户更快完成ddl。 [图片] (4)便捷的创建ddl 当与好友具有共同或类似ddl时(如同班同学具有相同的课程作业ddl),可直接将好友分享给自己的ddl添加为自己的ddl,简化了用户手动创建ddl的步骤,为用户带来了方便(创建时也可对原有内容进行修改)。 [图片] (5)群组ddl功能 为进一步增强用户互动与提高效率,设计了群组ddl功能,当一个小组具有共同的ddl(如班级课程作业小组)时,可发起群组ddl,大家在同一个ddl中共同加油努力,交流ddl感想,互相促进完成。但我们设计这个功能的定位是小组,而不是社区,因此群组上限为20人。 [图片] 以上是关于作品,在区别于其他竞品方面的几个特色功能。总体而言,“ddl冲鸭”具有以下几个特点: (1)用途明确,用户共鸣强 (2)使用便捷,用户粘性大 (3)形式新颖,用户兴趣大 五、精益求精——抓住用户心理进行产品设计根据调研结果,结合我们自身换位思考、深入体验,我们从用户心理的角度,精益求精,完善产品设计。 (1)未完成ddl的心理罪恶感——设计过期提醒功能 当有未完成的ddl时,进入小程序首页将会弹出提示,为鸭子落泪的图片,并播放“咕咕咕”的鸽子声,提醒用户已经放了自己的ddl的鸽子; 这样设计是为了与用户未完成ddl时的心理愧疚感对应,提醒用户以后要按时完成ddl任务,不能再放了自己的鸽子。 [图片] (2)无ddl时的悠闲感——无ddl时提示相关图片 没有ddl时,显示一只正在睡觉的鸭子,表明当前没有ddl任务的悠闲感,与用户当前的心理对应。 [图片] (3)有ddl时的紧迫感——通过不同颜色、进度条显示剩余时间 这个前面已经简单介绍过,即根据剩余时间的不同,给予不同颜色的文本和不同长度的进度条进行提示,时间越少时文字颜色越深(从绿色到黄色、橙色、红色)、同时进度条长度越小,从视觉上给予用户ddl紧迫之感,督促用户更快完成ddl。 [图片] (4)用户懒、害怕选择——合理设置默认值、提供方便用户的功能 ①创建ddl时,默认时间为当前时间三天后的22时,默认ddl类别为“学习”。这是根据我们调研结果,得出通常在ddl剩余三天时,用户会开始重视ddl,且当下大学生面临的多数ddl为学习方面的(如课程作业)。设置默认值,用户无需选择,方便用户。 [图片] ②记录ddl,可以粘贴文本、语音记录、将好友分享的ddl直接添加为自己的ddl,这些都是为了方便用户而推出的功能。 [图片] [图片] (5)用户渴望得到鼓励——弹图提示,群组交流 ①个人创建或完成ddl时,要与用户充满斗志的激情感、完成时的喜悦感与成就感对应,因此我们设计了相关的图片进行提示,而不是普通的文本模态框。 [图片] [图片] ②设计了群组功能,完成ddl时可以交流感想,鼓励他人;同时,群组排行榜也有利于促进用户完成ddl。 [图片] [图片] 六、把握细节——优化产品体验,提高用户黏性产品设计过程中,充分考虑多个细节。虽然它们不一定会对产品的主要功能产生影响,但积少成多,优化了用户使用体验,有利于提高用户黏性,如: (1)启动页展示轮播图,让未使用过的新用户初步了解小程序的功能,只有第一次进入时会显示。 [图片] (2)不是第一次使用的用户,已经了解过小程序的基本功能,那么用户进来最想要看到的内容是什么——当然ddl列表,且是“进行中”状态(即还未完成的)的ddl列表。 就像微信,我们打开微信后最先想要看到的是什么?当然是微信的未读消息,而不是通讯录之类的页面。 (3)操作体验优化,更加易用:标签页除了点击顶部导航切换,也可以左右滑动进行切换,有利于方便用户单手操作。 [图片] (4)操作时,必要时给予提示,避免用户误操作,如误删除 [图片] [图片] (5)充分考虑多种可能的不同情况,如: ①用户第一次进入小程序时,进入启动页,在启动页进行授权,授权后才可以使用小程序;但如果用户是通过他人分享ddl页面第一次进入小程序,则还需要进行授权才能使用。 [图片] [图片] ②前面提到,群组ddl功能的设计,是针对小组,而不是为了打造社区,因此群组上限为20人,必要时也应给予提示。这样的设计是遵循了产品的定位,与产品定位对应——即做效率类工具,而不是做社交平台。 [图片] (6)尊重用户隐私与体验,如: ①用户只是想与他人分享自己正在忙的ddl,但没有打算让他人添加为自己的ddl——分享时可进行选择。 [图片] ②为避免消息过多给用户带来骚扰,消息列表最多只显示最近20条消息。 [图片] (7)在线客服、意见反馈等不可缺少,这是作为用户与我们沟通的桥梁之一,也有利于不断改进产品。 [图片] [图片] 七、创新运营——产品已从0到1,还要从1到100由于本文主要是在讲产品策划,因此开发方面不多讲。但产品运营与产品策划密不可分,产品策划强调从0到1,产品运营强调从1到100,在产品被设计开发出来之后,还要结合运营推广,让它真正投入使用,才能体现它的价值。 这里简单提几点想法: (1)既然产品是微信小程序,那么最基本的就是结合微信进行推广,除了普通的微信群、朋友圈、公众号,还可以结合微信新功能“时刻视频”、“看一看”等。在微信环境下的推广,有利于用户快速定位到产品,减少引流成本; (2)针对目标用户:由于目标用户是高校学生,可以借助各高校相关微信公众号、微博、贴吧等进行线上宣传; (3)培养目标KOL(关键意见领袖),KOL在产品上线后发挥小范围同化辐射作用,提高其他用户对产品的信任度,也是作为用户自传播的方式之一; (4)组建线上ddl交流群或活动,在收集用户反馈的同时提高产品存在感,同时也可作为MVP产品,更好地了解用户的需求与实际情况; (5)结合当下深受年轻群体(包括目标用户即大学生在内)喜爱的短视频,可制作相关宣传短视频(要追求创意),借助腾讯微视、快手、抖音等短视频平台进行宣传; (6)结合小程序项目已有“冲鸭”系列图片设计,进一步拓展,制作微信表情包“冲鸭”系列,可申请在微信表情包商店上架,在微信聊天中进行使用,提高产品曝光、辅助产品推广。 [图片] 如果能在作品提交前上线运营,有运营数据支撑(如用户量、用户使用情况等),就说明产品的确有人用,说明产品开发的合理性、必要性。 八、小结其实我和其他的队友一样,我们队里的同学没有软件专业的,也没有计算机专业的,甚至有中文之类的文科专业同学。我们都是凭借兴趣自学了相关的技能,这也是驱动我们认真投入的重要原因之一——是为了兴趣,为了挑战,不是为了参赛,不是为了拿奖。论开发技术,我们也许并不如很多计算机专业的,但在我眼里,产品思维比技术重要,这也是我今天写文章,是以产品的角度来写、而不是以开发的角度来写的原因(当然,写得也比较简单,还望见谅)。以下是我的几点简单的参赛感想: 1、首先应该确定的问题,是产品定位、目标用户等,这些作为整个项目的基础以及方向,至关重要;在构思时应该多方面考虑(功能设计、目标用户、开发成本、运营方案等),在满足基本需求的前提下,力求创新,才能比别人做得更好(一味地实现必备需求而不追求创新,则很难突出产品亮点); 2、开发固然占了很重要的一部分,但一个完整的项目,不是只有开发,设计、运营等都很重要,这些是共同推进一个产品成功的必不可少的因素; 3、大赛提到了“以赛促学”,个人认为对于初学者来说,不要急于使用高大上的技术以便快速做出功能很高大上的产品。技术基础要扎实,才有利于长远的发展。所以我们用的是原生开发技术,不使用任何第三方开发框架(这里说的是开发框架,但我们有一定程度地使用了UI组件库)。在WXML、WXSS、js等原生技术基础上,力求创新实践。 【写在最后】“ddl冲鸭”产品初步成形,虽已上线运营投入使用,但依然有很多不足之处,后面会尽力再继续完善。这一次做项目,同时也是为了实现个人理想。我本人是打算往互联网产品策划方向发展的,这次项目也是相当于一个伟大的尝试。 在学习、借鉴一些去年参赛作品的过程中,我发现有一些作品现在已经停止了更新维护,甚至还有作品暂停服务、无法访问、或者至今没有正式发布上线等,这也让我再次思考了大赛和作品的意义。 单纯抱着“想试试、想参与”的态度,真的容易做出一款很好的产品吗?我想起以前面试社团,其实那个部门没有很想去,尽管一开始很顺利,面到最后一轮的时候还是挂了。当时我的老师对我说:“其实你的内心根本就没有那种特别想去的决心,那么这种情况下你又怎么可能发挥出你最大的潜力呢?” 4月底,面了腾讯暑期实习产品策划岗,面了三轮后挂在了总监面,无缘HR面。但是也并不遗憾,毕竟当时面试好像是随机分配?所以我面的部门和产品,并不是我想要做的,我不怎么接触、兴趣也很一般,确实没有“非去不可”的心态。然而塞翁失马,焉知非福?印象深刻,当时面试官问我:“你为什么想要选择做腾讯的产品策划?”现在我想说:“我和腾讯一样,有着一颗想要创造出能够改变世界的产品的心。”鹅厂是我美丽羞涩的梦,祝鹅厂越来越好,也希望我和鹅厂有缘再次相遇。 文粗词浅,感谢阅读。如有意见,恳请指教,感激不尽。
2019-06-28 - 高校微信小程序大赛经验分享杂谈
本文参加2019年「小程序征文·大学篇」征文活动。 大家好,我是「Resser 阅见」小程序的开发团队DeveSA的队长,虽然小程序暂时无缘赛区决赛,那我就只能先厚颜无耻地码下这些字,作为对比赛以来小程序开发中收获的经验与教训的总结。 What —— 我们开发的是什么? 我们开发的「Resser 阅见」(以下简称「阅见」)是一款基于RSS/ATOM的资讯聚合阅读小程序,其特点是门槛低,姿态新,聚合度高。 说得太拗口?看图就懂了👇 [图片] 接触过RSS的朋友可能会说,“哦,不就是个RSS阅读器嘛,RSS不是已经半死不活了吗”。的确,「阅见」就是一款基于微信小程序平台的RSS的阅读器。不过,我们降低了RSS的使用门槛,让普通用户能像关注微信公众号一样简单的关注自己喜欢的几乎所有内容(从微信公众号、B站到微博等),而高级用户也能延续RSS的使用习惯玩出各种高阶功能。 由于小程序尚在参赛阶段,为了评委能第一时间用上最新版本的小程序,我们还未将小程序正式上线,因此很遗憾大家暂时无法体验到小程序的功能了。 How —— 我们是怎样从入门到不入土的? 作为在校生,要从繁忙的课程和考试中抽出时间来开发一个完整的小程序,着实不易。能在ddl之前完成这个项目,主要归功于我们团队良好的时间规划和任务安排。作为队长,我将比赛过程分为备赛、开发、精修三大过程。 备赛过程 对上届获奖作品分析 既然开发这个小程序的目的是为了参赛,那么当然要奔着获奖为终极目标。因此,团队在4月份体验了去年获奖的30个小程序,从小程序的界面、操作、新颖程度等方面进行分析。在体验这些优秀作品的同时,我们也获益良多。产品中让我们惊喜的点可以作为之后开发的参考和灵感,产品中使用不畅的地方也为我们提前敲响警钟。 [图片] 初步入门 在参赛之前,我们团队中无一人有小程序开发经验,但是凭着初生牛犊不怕虎的精神和魄力,我们照着学做小程序-学堂在线-精品中文慕课(mooc)平台上的课程和官方开发文档实现了对小程序的初步入门。 当然,学习小程序的开发并不是一个单向的吸收知识的过程,边学边做是最好的入门方式。 开发过程 前期规划 考虑到我们开发小程序的过程也是学习小程序的过程,我们并不清楚某个提出的功能是否能得到实现。因此,我们先确定了小程序的大体架构,也就是页面的布局,每个页面要实现怎样的功能,通过什么方式去实现。通过经验的累积,再逐步往这个框架中填沙子,这样便不至于出现“走一步看一步”的窘况。 [图片] 协同工具 由于团队规模很小,只由两人构成,因此使用各种todo工具就显得杀鸡用牛刀了,我们选择的团队协作工具是非常质朴而接地气的——QQ群。 [图片] 在每周我会给团队布置任务并要求组员提交任务报告,这种半强迫性质的ddl一定程度上能有效防止组员划水并且增加团队成员的参与感。 而我作为主开发手,将各种功能划分为基础型、进阶型、配置型、魅力型四种类型,使用Markdown编辑器Bear记录功能的完成进度。 [图片] 当然,如果是较大型的团队,则需要更加专业的协同工具,这里推荐Slack和Teambition。 开发工具 虽然在备赛学习过程中看到许多开发者都使用VS Code和JetBrains系列软件,但我们依旧采用了官方的微信开发者工具,因为微信开发者工具毕竟是微信官方专门为小程序开发的IDE,体验上来说更加原生,也方便从IDE的更新日志中了解到小程序的最新动向。 [图片] 但是由于微信开发者工具还不够完善,实际使用过程中出现过几次问题,这里一个小技巧就是——稳定版出问题换Beta版,Beta版出问题换稳定版。 填坑与技巧 微信小程序合法域名校验:可以使用云函数进行反向代理 常用API接口:BAT都有在做NLP的接口、以及url2io的正文提取接口等等、更多接口提供商如易源数据等 云开发云存储图片可以直接调用,但是加载速度比较慢,建议还是用七牛云CDN SVG图片的体积小而且矢量图更清晰 精修过程 这里的精修,一方面是指对小程序的操作流程中可能存在的Bug进行排查和修复,另一方面是对用户界面和交互逻辑进行更细致地精调。 内测排查Bug 在这一过程中,我们在校园内开放了内测活动,聆听不同的声音,也从这些内测用户口中得到宝贵的意见和建议。在获得用户反馈这一过程中,我们发现用户特别懒于前往我们提供的反馈网址提交反馈,因此我们在小程序中加入了客服功能,用户在体验小程序的过程中遇到任何Bug或是有任何建议都可以不需要离开小程序就能够反馈给我们。 UI设计 我们也在比赛ddl前一周完成了对小程序Icon的绘制、UI的精调。 [图片] 有必要说一下Icon的设计理念,因为完成了Icon的设计后,UI的设计也就完成了一半。何出此言呢?因为小程序的界面配色要和Icon呼应,配色确定好了,可不就是完成了一半的设计嘛。 图标背景色使用Brandeis Blue(布兰迪斯大学蓝,蔚蓝色)和Solitude(孤独蓝,浅蓝)。布兰迪斯大学被称为全美最年轻的主要研究大学,而布兰迪斯大学蓝也被寄予“年轻”、“实践”、“应用性”的美好寓意。正如同「阅见」这款小程序一样,年轻而实用。孤独蓝则对应「阅见」小程序的Slogan——看见开放互联网未经过滤的样子,「阅见」希望每个人能作为一个独立的个体,去客观看待这个世界。 外形上,图标由中文汉字和圆弧形背景组成。蔚蓝色的圆弧象征地球(舒适区内),另一半的浅蓝色象征大气(舒适区外),「阅见」两字分别位于两种颜色上,寄予「阅见」能打破回音壁,让用户看到更全局的世界的美好愿景。 发布之前的收尾工作 对于小程序来说,除了用户用的了看得到的功能,还有隐藏在功能和界面之下的东西,比如小程序的体积、打开的速度、边界条件的设定等等,这些是用户不容易感知到的,但无形中又影响着用户体验的点。 减小小程序的体积:去除不需要的console.log等测试代码、代码文件压缩、图片尽量使用SVG格式。 加快小程序的打开速度:其实在减小小程序的体积的操作里,就能加快程序的运行速度了,还有就是可以将引用的图片CDN加速。 边界条件的设定:所有需要用户输入的地方,都需要边界条件的设定,比如用户输入RSS订阅链接时不小心输错成了标题,如果不做边界条件设定的话,小程序就会request一个不合法的网址,就可能造成小程序崩溃 One More Thing —— 上线之后的规划 说实话,在做这个小程序之前,我一直没有找到称心如意的跨平台RSS阅读器,然后碰巧看到有这么一个比赛,就想着自己开发一个好用的RSS阅读器。开发过程中,也调研了很多国内外的相似产品,比如国内的轻芒阅读、国外的红板报、Feedly、Inoreader等等。资料查得越多,心就越凉,因为几乎都是RSS已死的论调。但既然选择了这个主题,一条路也要走到黑。所以我又去探究RSS没落的原因,归纳成如下几点: 订阅源规范不统一:当前存在的Feed规范有RSS 0.91、1.0、2.0和ATOM等,不同源输出的XML格式不同,导致解析困难。 正文获取困难:越来越多网站为了广告和引流停止输出RSS或者不输出正文,传统的RSS 阅读器无法正常显示。 使用门槛高:传统RSS阅读器手动输入链接添加RSS操作麻烦。 无参与感:RSS相当于提供了一种单向的服务,用户只能作为信息的被动接受者,没有参与感。 平台和内容提供方盈利困难:RSS Feed不能给内容提供者带来流量和收益,提供者放弃RSS内容输出,也导致内容平台流失用户。 说白了,就是没有盈利去维持RSS的生态,所以我想,如果能够解决内容平台和内容提供者的盈利问题,是不是可以给RSS续一秒。 我们计划采用盈利补贴、竞价排名、数据反馈三种方式打通和内容提供者之间的壁垒,实现内容平台与内容提供者互利共赢。 盈利补贴:我们计划在小程序上线并积累一定用户后,在首页信息流和文章内投放广告。文章内广告的营收将按一定比例作为该文章内容提供者的补贴。即:优质的文章带来大量流量,广告投放将流量变现,变现的一部分作为对内容提供者的补贴。 竞价排名:并且,对于知名度不高的内容提供方,「阅见」可以作为除微信公众号、网站、今日头条外另一个平台帮助其推广。发现页面每个分类下展示的订阅源以及搜索建议将采用竞价排名形式,即前3个订阅源根据用户订阅热度排名,往后的4-10个订阅源采用竞价排名形式,一方面为「阅见」提供营收,一方面也可以增加内容提供方的曝光率。 数据反馈:由于「表态」功能的引入,「阅见」可以获得用户对特定文章的反馈,我们不希望这些反馈只是作为一个摆设,而希望用户的反馈能够达到内容提供方,帮助其提升内容质量,了解用户的心理。 喜欢就点个赞吧 😃 有任何疑问,欢迎联系作者:rhinoc@outlook.com
2019-06-28 - 一场比赛,一窥小程序的有限与无限
本文参加2019年「大赛文章征集」征文活动 大家好,我是华南赛区二等奖「Resser 阅见」小程序的开发团队DeveSA的队长。继上一篇高校微信小程序大赛经验分享杂谈流水账般介绍小程序的开发流程,这次我们来谈谈更Deep一点的——小程序的有限与无限。 「有限」和「无限」乍一看是不是很玄乎?让我稍稍剧透一下,这里的「有限」指的是小程序开发和运营上受到的限制,而「无限」则是小程序与生俱来的裂变能力和发展前景。本文的目的不只是简单地罗列这些Pros&Cons,也会根据在比赛中汲取到的经验分享给大家如何越过这些Cons并利用好Pros。 技术层面 wx.request 我相信每一个开发过小程序的developer,都记得大明湖畔的[代码]wx.request[代码]。曾几何时,比赛群里都是大家讨论如何在ddl前搞好备案,又或是ddl前一天匆匆忙忙设置好调试模式。 [代码]wx.request[代码]是微信提供的网络请求接口,限制诸多,有: 只支持HTTPS协议 不能使用IP地址或localhost 不支持8080以外端口 请求的域名必须经过ICP备案 用来鉴权的[代码]api.weixin.qq.com[代码]不能配置为服务器域名 Header中不能设置User-Agent 20个域名限制 而我们开发的「阅见」本质上是RSS阅读器,请求的feed链接都是用户自定义的外链,这些外链有HTTP的,也有没有备案的,数量更是无限的。这不就完美和[代码]wx.request[代码]的限制撞车了吗? 在这些限制下,很多同学第一反应是匆忙给自己的服务器上证书、上备案,却也不免遇上使用的第三方开放API(如[代码]http://api.github.com[代码])没上备案的问题。这就引出了更高阶的解决方法——在自己已备案的域名上设置[代码]tracker[代码]域名转发。然而,还有一种更优雅的方法——云函数。 也就是,原本从小程序到目标服务器的过程(上图)中间加入了云函数(下图)。 [图片] [图片] 借助于云函数与小程序得天独厚的血缘关系,小程序配置和调用云函数都十分方便。 云函数使用原生的[代码]request[代码]对传入的网址进行请求: [代码]const request = require('request'); exports.main = (event, context) => { return new Promise((resolve, reject) => { request(event.options, (error, res, body) => { if (error) return reject(error); resolve(res); }) }); } [代码] 小程序端则将原本的[代码]wx.request[代码]封装一下,代码有点长,只给个思路: [代码]wx.vrequest = function (options) { //将options转发到params,过程省略 return new Promise((RES, REJ) => { wx.cloud.callFunction({ //请求云函数 name: 'v-request', data: { options: params }, success: res => { const { result } = res; options.success && options.success(result); RES(result); }, fail: err => { //错误回调 REJ(err); }, complete: options.complete }) }) } [代码] 具体部署可以参考Github上guren-cloud/v-request WXML与富文本解析 解决了[代码]wx.request[代码]的问题,「阅见」遇到的第二个问题就是很多网站不支持RSS全文输出,因此我们计划让「阅见」能得到文章原文的HTML内容输出,再经过富文本渲染,呈现在小程序上。 小程序采用WXML,微信设计的一套标签语言,然而,网页上的富文本都是通过HTML呈现出来的,这样的话,当小程序想显示网页内容时,只能调用[代码]web-view[代码]了,而[代码]web-view[代码]不支持个人类型的小程序…… Butttt,多亏了小程序良好的生态环境,有很多开发者为小程序编写插件和库,其中,有关富文本渲染的就有wxParse和Towxml。其中wxParse已经两年没有更新了,虽然也有各路大神fork改良,但由于RSS获取到的文章千差万别,支持性不是很好(比如代码显示以及[代码]ruby[代码]标签等)。这里我强烈推荐Towxml,除了这个渲染库比较新之外,Towxml还有许多优良特性,比如,官方号称的“极致的中文排版优化”。 Thanks to Towxml,在「阅见」中,用户可以看到排版优良的订阅内容,甚至还能看视频哦。 [图片] 除了Towxml,「阅见」还借助了URL2Article提供的API提取正文内容,其能精准识别网页的正文部分,提取的内容不含广告导航等非正文内容。 [图片] 资源占用 说起小程序,你能想到最合适的形容词是什么?对我来说,就是「小」,这个「小」不只提现在小程序「触手可及、用完即走」的轻量,还有对开发者实在的限制——打包体积不能超过2M,本地缓存上限10M。 [图片] 这对于在大内存时代动辄上百兆代码的coder们来说,无疑是极大的限制。Butttt,在实际编写小程序时,只要有良好的编程习惯,这2M和10M是完全够用的,因为代码包经过了GZIP压缩后压缩率可以达到80%。 话虽如此,在「阅见」中,主要操作都是在小程序端完成的,所以相应的逻辑代码很多,在开发后期我们也的确遇到了代码包超过2M的情况。下面给一些减小代码包的体积的Tips: 小程序中只保存图标需要的图片文件,除tabbar外图标都使用[代码]·svg[代码]矢量格式,不仅体积相比[代码].png[代码]等传统点阵格式小了很多,而且也有矢量图永远高清的优点。 其他静态图片保存在服务器上或托管在图床上,七牛云就是个不错的选择,每个月还有免费的10G CDN流量,访问速度比云开发中的云储存快了不少。 删除测试使用的[代码]console.log()[代码]语句 压缩CSS代码 如果使用了第三方UI框架库,可以删除没有使用到的组件 如果以上Tips还不能解决代码包体积超过限制的问题,可以使用分包。 大部分小程序都会由某几个功能组成,通常这几个功能之间是独立的,但会依赖一些公共的逻辑,并且这些功能通常会对应某几个独立的页面。那么小程序代码的打包,大可不必一定要打成一个,可以按照功能的划分,拆分成几个分包,当需要用到某个功能时,才加载这个功能对应的分包。 使用分包方式加载小程序,能使小程序承载更多的功能与服务;而对用户而言,可以获得更快的加载速度,同时在不影响启动速度前提下使用更多功能。 目前小程序分包大小有以下限制: 整个小程序所有分包大小不超过 8M 单个分包/主包大小不能超过 2M 除了代码包2M的限制外,别忘了还有10M的缓存限制。在刚开发小程序时,我在所有跨页面传参使用的都是[代码]wx.setStorageSync[代码]和[代码]wx.getStorageSync[代码],不仅拖慢了程序的运行速度,还占用了宝贵了n/10M。其实,对于不需要存储在本地的跨页面传参,完全可以用[代码]app.globalData[代码]来代替: [代码]app.globalData[代码]是全局变量,下次进入的时候,就要重新获取。 [代码]Storage[代码]是本地缓存,除非缓存被清除不需要重新获取。 运营规范 登陆 相信大家对下图的warning都不陌生: [图片] 在之前,小程序可以直接通过[代码]wx.getUserInfo[代码]调起授权弹窗,这一操作虽然很便利,但却被一些开发者滥用,有些小程序一打开就要求授权甚至不授权就不能使用。在考虑到这一点的基础上,[代码]wx.getUserInfo[代码]不再显示授权弹窗,只能用button组件的开放功能调用。引用官方的话: 用户使用登录功能就像“面基”,第一印象很重要。这几个小改动在提升小程序使用的流畅体验、避免用户对数据采集授权担忧的同时,也将驱动用户更乐意尝试使用小程序服务。 因此,好的选择是在用户第一次登陆时“微妙地提示”用户授权登陆,并且在用户未授权时也可以访问到小程序的公共内容。 模版消息 我们知道,iOS上有专门的消息推送机制,而安卓上只能通过让应用后台运行实现24小时接受消息。借助于微信的装机率和使用率,小程序不需要时刻保持后台运行也能让用户接受到消息,这靠的就是微信的模版消息功能。Butttt,为了防止此功能的滥用,模版消息的发送有两个触发条件: 支付:当用户在小程序内完成过支付行为,可允许开发者向用户在7天内推送有限条数的模板消息(1次支付可下发3条,多次支付下发条数独立,互相不影响) 提交表单:当用户在小程序内发生过提交表单行为且该表单声明为要发模板消息的,开发者需要向用户提供服务时,可允许开发者向用户在7天内推送有限条数的模板消息(1次提交表单可下发1条,多次提交下发条数独立,相互不影响) 所以开发者难免会遇到模版消息发送次数不够用的窘况。但根据第二点,小程序每获得一次[代码]formId[代码],相当于就多了一条模版消息的「命」。简单来说,我们可以将小程序的表单组件进行封装,把用户的交互点击的[代码]bindtap[代码]事件替换为[代码]bindsubmit[代码],乔装一下小程序中其他功能按钮,当用户点击这些按钮时,就能获取到更多的[代码]formId[代码]。 ⚠️ 不过即便如此,开发者也应该遵守小程序运营规范,不要滥用模板消息。 更新:根据7月25日「微信广告小程序流量主大会」消息,微信小程序将上线「一次性订阅消息」的能力,只要经用户确认,超过七天的模版消息也能送达用户。 总结 小程序脱胎于微信,出生时便自带「降低门槛、充实能力、场景流量、提高转化、交易变现」等强有力的Buff,在电商零售、政务平台多方面可以说是全面赋能,有无限的发展潜能。小程序在方便用户,降低用户使用门槛的同时,也为开发者们提供了诸多上手即用的API和组件。如此强有力的工具想要长青,自然需要在开发、运营上施加限制,此之谓「有限」,而施加限制的目的是建立友好的微信生态体系,实现用户、微信、开发者三方互利共赢,此之谓「无限」。
2019-07-26 - 小程序征文·大学篇——分享你和小程序的故事
[图片] “2019中国高校计算机大赛·微信小程序应用开发赛”已进入决赛阶段,我们看到了许多同学对小程序的深入思考和精心设计。在每一份成果背后,都是同学们用心专研的结晶,而每一次克服困难的经历都弥足珍贵。此刻,我们迎来了小程序征文活动,鼓励围绕小程序主题的各种经验分享与总结沉淀。这里将是另一个展现自己的舞台,我们期待大家更加出色的表现。 征文范围 学习、开发与运营小程序过程中的经验总结 针对某项小程序能力的深入研究与应用 参加小程序比赛的设计开发思路 结合小程序与特定场景的创新想法或实践 建议参考浏览社区“精选”板块的优秀文章,我们期待你用心分享你和小程序的故事 征文时间 2019年6月3日22:00--2019年6月21日22:00 征文要求 文章内容必须和微信小程序相关 文章必须为本人原创作品,严禁抄袭或洗稿 文章结构清晰、排版整洁,内容有深度 投稿篇数不限,但内容雷同文章不得重复投稿 不得使用征文开始时间前已发布过的文章重复投稿 本次征文对象为在校大学生或参加过“中国高校计算机大赛微信小程序应用开发赛”的大学毕业生 必须使用下述投稿方式投稿 投稿方式 投稿地址:微信开放社区(https://developers.weixin.qq.com/community/) 投稿流程: [图片] 3. 投稿必填项:必须填写文章标签为“征文大学篇”,发表后方视为投稿成功,否则投稿无效;如下图所示: [图片] 评选规则 初审:文章发表后,主办方根据文章质量评选出入围的作品,入围作品将被列入文章的精选板块 终审:为了保证活动的公平公正,主办方会邀请5位微信资深技术专家担任本次活动的终审评委,给所有入围的作品评分,评选出最后的获奖作品 评审标准:文章内容(40%)、技术干货或运营思路(30%)、互动[浏览、收藏与评论、点赞数] (20%)、排版(10%) 奖品安排、公示、发放 [图片] 一等奖(2名):微信开放社区官方认证“优秀创作者”勋章一枚;限量版微信数码相框1个 二等奖(5名):微信开放社区官方认证“优秀创作者”勋章一枚;限量版微信跳一跳运动系列套装1份 三等奖(若干):限量版微信红包抱枕1个 最佳人气奖(1名):限量版微信logo-T恤1件 最受欢迎奖(1名):限量版微信黄脸-T恤1件 获奖结果公示:活动结束后一周内在官方公告中发布 奖品发放:结果公示后一个月内发放到作者帐户/邮寄给作者 其他注意事项 本次征文不向参赛个人收取任何费用 获奖作品著作权归作者所有,并授权腾讯基于本次征文活动进行使用、分享、传播 如果对征文有任何疑问,请到微信开放社区“小程序-问题解答”版块发帖咨询 [图片] 关注微信开发者公众号,了解更多活动详情
2019-06-18 - 「高校开发者」小程序 + 云开发 = 个人开发者快速创作的平台
个人介绍 大家好,我是Zero,一名大三的前端开发爱好者,目前主要研究微信小程序和iOS开发。 这是第二次参加微信小程序应用开发赛,2018年我们设计了一款通过二维码寻找丢失物品的小程序《蝴蝶寻物》,获得了华北赛区三等奖。 [图片] 今年,在小程序云开发功能的大力推广下,我决定采用云开发的方式,实现一个双人互动打卡互动的小程序《Mango Daily》(中文名称《芒果日常》)。 [图片] 得力于云开发提供的API,本项目在较短的时间内就实现了比较理想的效果。 接下来,我想从项目的立项开始,讲讲我是如何依靠小程序+云开发平台将想法快速实现。 1. 立项 1.1 项目背景 熟悉我的朋友都知道,我是个懒人 😦 ,所以我决定做一个两人互相监督完成目标的小程序。 目前市场上存在的大部分习惯日常类应用是通过个人或者群体打卡,我们更希望互相绑定的两个用户之间去完成一些日常活动。例如在完成自己的每日任务时,可以查看对方的打卡进度,提醒对方及时完成任务;或者可以根据任务为对方制订一套奖励计划,鼓励对方按时完成任务。另外,你可以在广场记录当天完成的任务,发生的故事,这可以只在你与同伴之间分享,也可以设置允许其他人阅读。 1.2 设计 一开始UI是在脑海中浮现的,只是想做一个以芒果色为主,并且能够快速看到对方打卡进度的界面。于是就有了一个以芒果色和树叶绿为主的界面。 [图片] 后来进行了第二版的设计,抛去了复杂的颜色组合,采用更简洁的设计,同时自定义了部分组件。 [图片] 1.3 技术准备 在去年的项目中,我们采用ThinkPHP开发了一套API系统,其中需要实现小程序的授权登录,设置鉴权来保证数据安全等操作。整个过程只有我一名开发人员,所以大致就是“先搞定后端,其次搞定界面,最后进行联调”的一个过程。 后来在云+社区看到一篇文章:《1个开发如何撑起一个过亿用户的小程序》,觉得确实可以通过新的方式去尝试一下前后端分离的开发过程。通读小程序云开发文档之后,发现并不需要学习新的技术,就可以快速上手。 这是第一次使用Serverless实现一款作品,打开了我创作应用的大门。 这次使用了 Teambition 来做任务看板,由于是个人开发维护,所以简单的 ‘ToDo, Doing, Done’ 模式就完全够用了。 [图片] 2. 开发 Mango Daily 使用的是小程序原生开发+云开发结合的方式进行开发的。 2.1 界面开发 界面没有使用第三方UI框架,而是自己将常用的模块封装成了组件。 [图片] 图中比较核心的模块包括 TabBar、Toast、Modal、Nav等。 [图片] 这里打算介绍一下我自己设计的Toast提示框,通过自定义视图+图片,替换掉了官方的loading,success,failure,warning效果。 在实现该组件的时候,我考虑了两种方案,一是通过普通image组件和设置z-index的方式实现Toast;另一个是使用cover-view组件。之所以考虑这两种方案,是因为我在发布随笔页面会是用到textarea,如果使用方案一会被原生组件遮挡。 自定义TabBar则是使用小程序官方提供的方法去实现的。但是这个方法会在首次切换时出现跳动,页面滑动时错位等问题,后来使用过完全自定义的方式去实现TabBar。 [代码]"usingComponents": { "tabbar": "/components/tabbar/tabbar" } [代码] 在每个需要使用自定义TabBar的页面调用自定义组件。 [代码]<tabbar sIndex="1"></tabbar> [代码] 下图是通过自定义组件实现的一个TabBar: [图片] 另外,Mango Daily中使用CSS3实现了部分动画,考虑到iOS端和安卓端小程序的渲染引擎不同,需要对代码进行兼容性处理。 [代码]/* 淡入 */ .fade-in { animation-name: fade-in; -webkit-animation-name: fade-in; } @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } @-webkit-keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } [代码] 这是我个人实现的一个动画: [图片] 2.2 云开发 云开发包括云数据库,云函数和云存储。本项目中三个功能均使用到。 2.2.1 云数据库 云数据库是一个非关系型数据库,在实际开发中基本符合本项目的需求。部分表关联查询则是通过分步查询的方式代替。 云数据库已经实现了自动鉴权,可以保证数据的安全性。目前云数据库只支持以下几种权限: 所有用户可读,仅创建者可读写 仅创建者可读写 所有用户可读 所有用户不可读写 默认情况下是***仅创建者可读写***,所以在首次开发时,手动插入的测试数据并不一定可以在前端顺利读取,需要修改集合的权限。 云数据库的调用在前端代码中即可完成。但是从上面几种读写权限来看,并没有办法实现对另一个用户创建的数据进行修改或者删除的操作(当然这也是非常不可取的),于是云函数就派上用场了。 2.2.2 云函数 我理解的云函数,则是跑在云端的一个函数脚本文件。 在接触云开发之前,如果我们想要去调用微信公众平台提供的API(例如发起退款、发送模板消息等),则需要在后端代码去实现,然后只需要给前端返回一个JSON表示请求状态即可。或者想要去实现上述描述中,修改一条由他人创建的数据的功能时,都是有后端工程师去完成的。 在本次开发中,我深刻体会到了云函数的强大,以及微信公众平台工程师设计产品的严谨性。 Mango Daily用到了微信公众平台的模板消息功能,所以需要在合适的时机请求微信官方提供的API。 因为取消了后端的开发,所以一开始打算直接在小程序端去请求官方API。但是失败了。因为此请求涉及APPKEY等重要信息,禁止在前端直接请求。这样就可以通过云函数去代替先前的后端开发,最后将状态返回给小程序端即可。 另外,云函数对云数据库有更高的操作权限,所以想要修改、删除他人生成的数据时,云函数可以直接进行操作。 云函数还提供定时触发功能,不过在本项目中暂未涉及。 2.2.3 云存储 本次开发省去了使用其他服务商的存储服务,全部得力于云存储功能。云存储允许上传多种文件类型,像图片、音频等文件还可以直接在小程序端调用。这里我们使用云存储实现了文章插图的功能。 [图片] 2.3 优化 2.3.1 全局配置 之前在某个项目中实现过国际化功能,即按照不同使用地区显示中英文的操作。这里我沿用了之前的设计,将代码中所有的提示文字提取到一个文件中,在wxml中使用变量代替文字。这样处理之后,文案可以集中管理。 全局文案配置文件: [图片] js文件 [代码]const app = getApp(); Page({ data: { text: app.text.calendar, } // ... }) [代码] wxml文件 [代码]<!-- 保存 --> <view class="btn-bg"> <view class='finish-btn mango-bg' bindtap="editHabit">{{ text.editHabit }}</view> </view> <!-- 保存 end --> [代码] 2.3.2 数据层封装 Mango Daily 数据操作进行了两次封装,一层是对云数据库API进行封装,第二层是每一个数据集合都对应一个Manager管理层。 以用户集合 User,Article 为例,项目中的结构如下: util |- db.js manager |- Article.js |- User.js db.js 是对云数据库API的封装,实现了增删查改等操作,以更新数据为例。 [代码]/** * 更新数据 */ const update = (collection, _id, data) => { return new Promise((resolve, reject) => { if (!exist(collection)) { reject(401, resCode[401]); } db.collection(collection).doc(_id).update({ data: data }).then(res => { resolve(res); }).catch((code, msg) => { reject(code, msg); }); }); } [代码] Article.js 是文章集合的管理类,同样实现了增删查改等操作,不过其是基于 db.js 进行扩展的。以更新文章操作为例: [代码]/** * 更新 */ const update = (_id, data) => { return new Promise((resolve, reject) => { db.update(collection, _id, data).then(res => { resolve(res); }).catch((code, msg) => { reject(db.errMsg); }); }); } [代码] 之所以封装两层,是想尽量减少Page对象中对云数据库的直接调用。这样在页面js文件中只需要调用某一个Manager提供的函数即可。 2.3.3 后台上传策略 Mango Daily还实现了发送模板消息的功能,这就涉及到了FromID的收集。目前FromID的收集大部分采用埋点的方式。 如果每次采集到新的FromID都直接上传到数据库存储,可能会造成网络资源的浪费,所以需要选择合适的时机上传数据。 在本项目中,每次采集到FromID,首先存到 globalData 中,当小程序进入后台状态时,再进行数据的上传。 app.js 中的实现: [代码]/** * 后台监听 */ onHide: function() { this.uploadFormID(); }, /** * 上传token */ uploadFormID: function() { let ids = this.globalData.formIds; if (ids.length == 0) { return ; } let formId = ids.pop(); this.push.upload(formId).then(_ => { console.log("上传formID:" , formId); this.uploadFormID(); }).catch(err => { console.log(err); }); }, [代码] 3. 维护 很遗憾,这一部分可能没有太多需要写的。 在18年的项目中,需要考虑数据库的维护问题。但是使用了云开发之后,Serverless的优点就表现出来了。我无须将太多的精力放在后端的维护上。 4. 总结 在本次项目开发中,我深刻体会到了云开发的便捷性。无须自己实现鉴权,对接第三方存储。数据方面,增删查改功能非常方便。云开发提供的种种便利,让我在有新创意的时候,优先选择小程序+云开发的方式去实现。 [代码]你好,你的小程序涉及用户自行生成内容的发布/分享/交流,属社交范畴,为个人主体小程序未开放类目,建议申请企业主体小程序 [代码] 另外,Mango Daily中的随笔功能属于用户自行生成内容功能,所以在上架的时候,个人开发者账号是不被允许的,所以在考虑上架产品的时候,请按照实际情况酌情考虑选择账号主体类型。 2019.6.21补充:很遗憾,本项目没有进决赛。后续加油啦!
2019-06-28