uniCloud中云函数的使用与工具类封装

uni-app是一个方便小程序开发的基于Vue的框架,它为开发者提供了一个非常方便的平台叫做uniCloud,使用它可以代替部分传统的服务端功能,使用云数据库和云函数(可以理解为数据接口)进行方便的CRUD操作。

但是uniCloud中原生的uniCloud.callFunction方法比较底层,在接口数量较多时会造成维护不便,所以需要一个结构对它进行解耦。这里对云函数的基本使用和一种简易的封装方式做个笔记。

uniCloud开发环境搭建

首先需要在hbuilderX中新建一个uni-app项目,可以先创建一下,选择默认模板,然后勾选使用uniCloud,完成创建。

然后在uniCloud文件夹中选择关联云服务空间或项目。

云服务空间需要在uniCloud网站上实名认证申请才可以得到。我这里已经申请完了,可以看到管理界面如下:

云函数的基本使用

在管理界面→云数据库中,创建一个用于测试的数据库表,写入一些测试数据,然后创建一个云函数用于获取这个列表。

在云函数的index.js里面这样写:

1
2
3
4
5
6
7
8
9
10
'use strict';
// 获取数据库连接
const db = uniCloud.database();
exports.main = async (event, context) => {
// 异步操作,需要使用await等待
// 使用collection方法获取对应的数据库集合的引用
// 使用get获取全部内容
let AccountsList = await db.collection("accounts").get();
return AccountsList;
};

使用上传并运行云函数将这个云函数上传到云端,并测试运行结果:

看到能正常返回数据,说明运行成功了。

对于返回的数据格式,最好做一个简单的封装,即带有HTTP状态码,请求信息等数据的对象。所以将云函数改写一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'use strict';
// 获取数据库连接
const db = uniCloud.database();
exports.main = async (event, context) => {
// 异步操作,需要使用await等待
// 使用collection方法获取对应的数据库集合的引用
// 使用get获取全部内容
let AccountsList = await db.collection("accounts").get();
return {
code: 200,
msg: "已成功返回accounts表的数据",
data: AccountsList.data
}
};

再次上传运行一下(需要注意,每次修改完云函数之后都要将它上传到云端才可以正常使用),查看输出结果:

云函数调试完成,接下来返回前端,尝试在index.vue里面调用它并显示信息在页面上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
export default {
data() {
return {
data: [],
}
},
onLoad() {
this.getList();
},
methods: {
getList() {
uniCloud.callFunction({
name: 'getAccountsList'
})
.then(res => {
this.data = res.result.data;
console.log(this.data);
})
}
}
}
</script>

使用callFunction对云函数调用,它返回一个Promise,可以用.then获取调用成功的信息。控制台显示:

这样就表示一个云函数调用完成了。

云函数API的工具类封装

云函数虽然好用,但每个需要用云函数的地方如果都需要这样写,不太利于维护项目,所以需要通过一些方式对它进行封装,以到达解耦的效果。

封装之后,在调用时就不再需要写一大堆的callFunction了,可以让代码更加直观而且可维护。首先新建目录:

这里面api文件夹代表跟api相关的操作封装,http.js封装一个uniCloud.callFunction请求的Promise,用于各云函数请求调用时使用;index.js用于批量导出模块;list.js用于声明云函数模块(随着项目规模的增加,可以不用只有一个list.js,可以将不同的云函数分散开来,方便维护,只需要再加一些js文件就可以)。

先在app的入口程序main.js里面注册一下自定义的工具类,将它挂载到Vue的原型对象就可以。

1
2
import API from './common/api'
Vue.prototype.$api = API

在http.js中这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
export default function $http(options) {
const { url, data } = options;
return new Promise((reslove, reject) => {
uniCloud.callFunction({
name: url,
data
}).then((res) => {
if (res.result.code === 200) {
reslove(res.result)
} else {
reject(res.result)
}
}).catch((err) => {
reject(err)
})
})
}

对于每个uniCloud.callFunction,需要给它提供一个云函数名称和参数列表,分别对应name和data,在传入时name通过url传入,data作为同名变量可以简写。让它返回一个Promise,内部执行这个callFunction,并判断返回的状态码是不是200,如果是,则转resolve,如果不是,则转reject,如果出错也转reject,对于其他需求,也可以在内部继续扩展。

在index.js中这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const requireAPI = require.context(
// ./api 目录的相对路径
'.',
// 判断是否查询子目录
false,
// 使用正则判断.js文件后缀
/.js$/
)

let module = {}; // 导出模块对象
requireAPI.keys().forEach((key,index) => {
// 使用forEach对所有的文件进行检索,但不需要检索index.js
if(key === './index.js')
return;
// 将对应的key绑定到moudule里导出
Object.assign(module,requireAPI(key))
})

export default module

require.context是webpack里面的一个工具,通过给定的条件获取指定的上下文,主要用于实现自动化导入模块。使用这个API可以遍历某个文件夹下面的所有文件并自动导入,不用再手动import了。

require.context函数接受下面三个参数:

  1. directory,字符串,读取文件的路径
  2. useSubdirectories bool值,是否遍历文件的子目录
  3. regExp,正则表达式,用于匹配对应文件名的文件

在list.js中这样写:

1
2
3
4
5
6
7
import $http from './http.js'

export const getList = () => {
return $http({
url: 'getAccountsList',
})
}

此后,如果想要添加新的云函数,只需要新建云函数后,在list.js里按照这个getList的写法再写一个就可以了,这种方式是无参的,如果需要有参的传递,则函数里写入一个data,$http中也传入一个data即可。

经过一系列封装后,前端代码就可以改写成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
export default {
data() {
return {
data: [],
}
},
onLoad() {
this.getList();
},
methods: {
getList() {
this.$api.getList()
.then(res => {
console.log(res);
})
}
}
}
</script>

最终运行结果:

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2018-2021 Shawn Zhou
  • Hexo 框架强力驱动 | 主题 - Ayer
  • 访问人数: | 浏览次数:

感谢打赏~

支付宝
微信