详解小程序云开发攻略(解决最棘手的问题)


Posted in Javascript onSeptember 30, 2019

背景

最近小程序非常的火,应公司业务发展要求,开发维护了几款小程序,公司开发的小程序都是由后端提供的接口,开发繁琐而复杂,直到小程序出现了云开发,仔细研读了文档之后,欣喜不已,于是我着手开发了本人的第一款小程序

  • 小程序云开发教程地址 点我查看>>

分析

云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥。

优势

  • 无需自建服务器,数据库,无需自建存储和CDN
  • 数据库模型很简单,就是一个json形式的对象格式
  • 调用服务端云函数自动获取openid,再也没有繁琐的授权登陆流程了,只要进入小程序就是登陆状态,体验真的好
  • 开发迅速,只需要前端就能搞定所有开发工作

需要解决的问题

数据库切换问题

使用过云开发的人都发现云开发切换数据库环境是最头疼的,如果手动去切换容易搞错,不小心在当前环境修改了线上数据库数据

直到官方出了这个函数问题也就迎刃而解

cloud.updateConfig({
  env: ENV === 'local' ? 'dev-aqijb' : ENV
 });

我使用的是服务端云开发功能,为什么要这样判断,因为在开发工具中ENV = 'local',所以这么判断一下,保证开发工具中使用的是测试环境数据库

使用taro多端开发框架,借助于webpack,还可以通过process.env.NODE_ENV值区分当前代码开发环境

await Taro.cloud.init({
    env: `${process.env.NODE_ENV === 'development' ? 'dev-aqijb' : 'pro-hljv7'}`
    /* env: 'pro-hljv7' */
   });

这样可以保证开发环境和线上环境可以使用对应环境的数据库

数据库字段定义问题

因为JS是弱类型语言,不能像typescript那样静态定义变量类型,这样添加到数据库的字段数量和字段类型都无法控制

我不想用typescript,能不能实现这样的功能呢,可以用superstruct库来实现这个功能

  • superstruct git地址 点我查看>>

详细使用案例见下方代码

函数文件太多的问题

官方和他人教程的例子都是一个文件对应一个云函数,通过开发体验我发现这样做并不好,当项目有多个表的时候,找个函数文件真的太难了
我们可以将一个表的增删改查函数全部写入一个文件中

教程: 首先每个云函数文件中package.json引入superstruct

{
 "dependencies": {
  "wx-server-sdk": "latest",
  "superstruct": "latest"
 }
}

以下代码是一个完整的云函数例子

const cloud = require('wx-server-sdk');
const { struct, superstruct } = require('superstruct');
cloud.init();
//小区信息
const Model = () => {
 const db = cloud.database();
 const _ = db.command;
 const collection = db.collection('address');
 return {
  async add(data) {
   try {
    data = struct({
     name: 'string', //名字
     phone: 'string',
     unit: 'number', //楼单元号
     doorNumber: 'string', //门号
     communityId: 'string', //小区id
     _openid: 'string' //用户的id
     //isDefault: 'boolean' //是否默认地址
    })(data);
   } catch (e) {
    const { path, value, type } = e;
    const key = path[0];

    if (value === undefined) {
     const error = new Error(`${key}_required`);
     error.attribute = key;
     throw error;
    }

    if (type === undefined) {
     const error = new Error(`attribute_${key}_unknown`);
     error.attribute = key;
     throw error;
    }
    const error = new Error(`${key}_invalid`);
    error.attribute = key;
    error.value = value;
    throw error;
   }
   let res = await this.getList({ _openid: data._openid });
   if (res.data.length >= 1) {
    return { msg: '当前只支持保存一个地址' };
   }
   res = await collection.add({
    data,
    createTime: db.serverDate(),
    updateTime: db.serverDate()
   });
   return res;
  },
  async getAdressById({ _openid, _id }) {
   const user = await collection
    .where({
     _openid,
     _id: _.eq(_id)
    })
    .get();
   return user;
  },
  //更新指定的id 先判断手机号修改没,没修改直接就改数据,修改过判断一下库中有没有这条数据
  async update(data) {
   //更新表的操作
  },
  //删除指定id的shop
  async remove({ _id, _openid }) {
   //删除表的操作
  },
  /**
   * 获取商列表
   * @param {*} option {category 类别, pagenum 页码}
   */
  async getList({ _openid }) {
   const shopList = await collection
    .where({
     _openid
    })
    .get();

   return shopList;
  }
 };
};

exports.main = async (event, context) => {
 const { func, data } = event;
 const { ENV, OPENID } = cloud.getWXContext();
 // 更新默认配置,将默认访问环境设为当前云函数所在环境
 console.log('ENV', ENV);
 cloud.updateConfig({
  env: ENV === 'local' ? 'dev-aqijb' : ENV
 });
 let res = await Model()[func]({ ...data, _openid: OPENID });
 return {
  ENV,
  data: res
 };
};

函数使用方式

wx.cloud.callFunction({
   'address', //云函数文件名
   data: {
    func: 'add', //云函数中定义的方法
    data: {} //需要上传的数据
   }
  });

图片 视频等文件

直接打开云开发控制台选择存储直接上传文件,复制url地址就可以放到代码中使用了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 动态table添加colspan\rowspan 参数的方法
Jul 25 Javascript
ExtJS如何设置与获取radio控件的选取状态
Jan 22 Javascript
zeroclipboard 单个复制按钮和多个复制按钮的实现方法
Jun 14 Javascript
10分钟掌握XML、JSON及其解析
Dec 06 Javascript
基于jQuery实现Tabs选项卡自定义插件
Nov 21 Javascript
详解Node.js串行化流程控制
May 04 Javascript
Js实现京东无延迟菜单效果实例(demo)
Jun 02 Javascript
JavaScript基于对象方法实现数组去重及排序操作示例
Jul 10 Javascript
Vue实现动态添加或者删除对象和对象数组的操作方法
Sep 21 Javascript
微信小程序用户授权弹窗 拒绝时引导用户重新授权实现
Jul 29 Javascript
js实现二级联动简单实例
Jan 11 Javascript
实现AJAX异步调用和局部刷新的基本步骤
Mar 17 Javascript
webpack3升级到webpack4遇到问题总结
Sep 30 #Javascript
uploadify插件实现多个图片上传并预览
Sep 30 #Javascript
vue中使用[provide/inject]实现页面reload的方法
Sep 30 #Javascript
JavaScript中的null和undefined用法解析
Sep 30 #Javascript
vue resource发送请求的几种方式
Sep 30 #Javascript
Bootstrap table 实现树形表格联动选中联动取消功能
Sep 30 #Javascript
bootstrap table实现iview固定列的效果实例代码详解
Sep 30 #Javascript
You might like
编译php 5.2.14+fpm+memcached(具体操作详解)
2013/06/18 PHP
php轻量级的性能分析工具xhprof的安装使用
2015/08/12 PHP
contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
2011/09/13 Javascript
jquery实现的带缩略图的焦点图片切换(自动播放/响应鼠标动作)
2013/01/23 Javascript
js输出阴历、阳历、年份、月份、周示例代码
2014/01/29 Javascript
JS工作中的小贴士之”闭包“与事件委托的”阻止冒泡“
2016/06/16 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
2016/08/17 Javascript
微信小程序 增、删、改、查操作实例详解
2017/01/13 Javascript
AngularJS使用ocLazyLoad实现js延迟加载
2017/07/05 Javascript
如何编写一个完整的Angular4 FormText 组件
2017/11/18 Javascript
利用jquery如何从json中读取数据追加到html中
2017/12/01 jQuery
微信小程序当前时间时段选择器插件使用方法详解
2018/12/28 Javascript
关于layui 弹出层一闪而过就消失的解决方法
2019/09/09 Javascript
JavaScript Image对象实现原理实例解析
2020/08/26 Javascript
[02:51]2018年度DOTA2最佳中单位选手-完美盛典
2018/12/17 DOTA
简单解析Django框架中的表单验证
2015/07/17 Python
python如何通过twisted实现数据库异步插入
2018/03/20 Python
python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例
2020/03/08 Python
基于python实现判断字符串是否数字算法
2020/07/10 Python
Python如何使用27行代码绘制星星图
2020/07/20 Python
python爬虫如何解决图片验证码
2021/02/14 Python
thinkphp5 路由分发原理
2021/03/18 PHP
纯CSS改变webkit内核浏览器的滚动条样式
2014/04/17 HTML / CSS
HTML5中新标签和常用标签详解
2014/03/07 HTML / CSS
全球领先的全景影像品牌:Insta360
2019/08/21 全球购物
保安部任务及岗位职责
2014/02/25 职场文书
优秀员工自荐书
2015/03/06 职场文书
教师聘用意向书
2015/05/11 职场文书
六一活动主持词
2015/06/30 职场文书
红歌会主持词
2015/07/02 职场文书
2016年小学“感恩教师”主题队日活动总结
2016/04/01 职场文书
2019年暑期法院实习报告
2019/12/18 职场文书
Memcached介绍及php-memcache扩展安装
2021/04/01 PHP
数据库的高级查询六:表连接查询:外连接(左外连接,右外连接,UNION关键字,连接中ON与WHERE的不同)
2021/04/05 MySQL
JavaScript+HTML实现学生信息管理系统
2021/04/20 Javascript
redis中lua脚本使用教程
2021/11/01 Redis