• 小程序云开发攻略,解决最棘手的问题


    背景

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

    分析

    云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 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库来实现这个功能

    详细使用案例见下方代码

    函数文件太多的问题

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

    教程: 首先每个云函数文件中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地址就可以放到代码中使用了

    扫码体验我的小程序:
    垃圾分类

  • 相关阅读:
    【视频开发】图像清晰度评价方法
    【视频开发】图像清晰度评价方法
    【VS开发】MFC修改Opencv namedWindow的风格
    【VS开发】MFC修改Opencv namedWindow的风格
    【ARM-Linux开发】ctrl-xxx的对应的signal含义
    【ARM-Linux开发】ctrl-xxx的对应的signal含义
    【VS开发】程序如何捕捉signal函数参数中指定的信号
    【VS开发】程序如何捕捉signal函数参数中指定的信号
    【VS开发】windows下的signal
    【VS开发】windows下的signal
  • 原文地址:https://www.cnblogs.com/chengfeng6/p/11611549.html
Copyright © 2020-2023  润新知