查看: 253|回复: 0

鸿蒙 uni-app x 云对象 importObject 适配

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在 HarmonyOS 上做 uni-app x 应用时,云端调用不只有云函数。HarmonyOS 4.61 开始支持 uniCloud.importObject,与 callFunction 云函数是同一批能力。它把云对象导入为本地调用器,之后可以像调本地方法一样调远程方法,例如 todo.add('标题','内容')。对于 todo 列表、用户资料等 CRUD 服务,这种写法比每次 callFunction 传函数名和 data 更直接。下面按 API 签名、云对象编写、泛型、自动 UI、CRUD、加密、鸿蒙强类型适配以及与 callFunction/原生 HTTP 的对比来梳理。

一、importObject 的 API 与兼容点

原先用 callFunction 调云函数,需要传函数名、传 data,再拿 result。云对象则通过 uniCloud.importObject 导入,然后直接调用它的方法。API 签名如下:
  1. uniCloud.importObject(objectName: string, options?: UniCloudImportObjectOptions): UniCloudCloudObjectCaller
复制代码

options 中常见有 loadingOptions 和 errorOptions。泛型从 4.13 版本起支持。鸿蒙平台从 4.61 开始支持 uniCloud.importObject,跟云函数 callFunction 是同一批支持的。

二、云对象编写与基础调用

云对象是一个目录,核心文件是 index.obj.js。例如 cloudfunctions/todo/index.obj.js:
  1. 'use strict';
  2. const db = uniCloud.database()
  3. const collection = db.collection('todos')
  4. module.exports = {
  5.   async add(title, content) {
  6.     const result = await collection.add({
  7.       title: title,
  8.       content: content,
  9.       status: 'pending',
  10.       createTime: Date.now()
  11.     })
  12.     return {
  13.       errCode: 0,
  14.       errMsg: '',
  15.       id: result.id
  16.     }
  17.   },
  18.   async list(page, pageSize) {
  19.     const countResult = await collection.count()
  20.     const listResult = await collection
  21.       .skip((page - 1) * pageSize)
  22.       .limit(pageSize)
  23.       .orderBy('createTime', 'desc')
  24.       .get()
  25.     return {
  26.       errCode: 0,
  27.       errMsg: '',
  28.       list: listResult.data,
  29.       total: countResult.total
  30.     }
  31.   },
  32.   async updateStatus(id, status) {
  33.     await collection.doc(id).update({
  34.       status: status
  35.     })
  36.     return {
  37.       errCode: 0,
  38.       errMsg: ''
  39.     }
  40.   },
  41.   async remove(id) {
  42.     await collection.doc(id).remove()
  43.     return {
  44.       errCode: 0,
  45.       errMsg: ''
  46.     }
  47.   }
  48. }
复制代码

导入后直接调用:
  1. const todo = uniCloud.importObject('todo')
  2. const result = await todo.add('标题', '内容')
复制代码

基础 .then 调用中,若没有泛型,res 可转成 UTSJSONObject 再取 id。错误处理建议在 catch 里 console.error 并给出 toast 提示。

三、泛型让鸿蒙强类型下更安全

uni-app x 是强类型语言,云对象返回值最好定义类型。4.13 版本起支持泛型调用:
  1. type AddResult = {
  2.   errCode: number
  3.   errMsg: string
  4.   id: string
  5. }
  6. type ListResult = {
  7.   errCode: number
  8.   errMsg: string
  9.   list: Array<UTSJSONObject>
  10.   total: number
  11. }
  12. const todo = uniCloud.importObject('todo')
  13. todo.add<AddResult>('学习 uni-app x', '写一篇鸿蒙开发文章').then((res) => {
  14.   console.log('添加成功,ID:', res.id)
  15. })
  16. todo.list<ListResult>(1, 10).then((res) => {
  17.   console.log('总数:', res.total)
  18.   console.log('列表:', res.list)
  19. })
复制代码

这里 res.id、res.total、res.list 可以直接访问,不需要先做类型转换。对鸿蒙端来说,类型越明确,编译期越容易发现字段拼写或结构错误。

四、自动 loading 与错误提示

云对象默认会自动展示 loading 和错误提示,可通过 loadingOptions、errorOptions 配置:
  1. const todo = uniCloud.importObject('todo', {
  2.   loadingOptions: {
  3.     title: '加载中...',
  4.     mask: true
  5.   },
  6.   errorOptions: {
  7.     type: 'modal',
  8.     retry: true
  9.   }
  10. })
  11. todo.list<ListResult>(1, 10).then((res) => {
  12.   console.log('列表:', res.list)
  13. })
复制代码

如果不想用默认 UI,可以设置 customUI: true 关闭,然后自己 showLoading、hideLoading,并在 catch 中处理错误:
  1. const todo = uniCloud.importObject('todo', {
  2.   customUI: true
  3. })
  4. uni.showLoading({ title: '自定义 loading...' })
  5. todo.list<ListResult>(1, 10).then((res) => {
  6.   uni.hideLoading()
  7.   console.log('列表:', res.list)
  8. }).catch((err) => {
  9.   uni.hideLoading()
  10.   uni.showToast({
  11.     title: '加载失败',
  12.     icon: 'none'
  13.   })
  14. })
复制代码

五、CRUD 实战

一个完整的待办 CRUD 可以这样组织类型和调用:
  1. type TodoItem = {
  2.   _id: string
  3.   title: string
  4.   content: string
  5.   status: string
  6.   createTime: number
  7. }
  8. type AddResult = {
  9.   errCode: number
  10.   errMsg: string
  11.   id: string
  12. }
  13. type ListResult = {
  14.   errCode: number
  15.   errMsg: string
  16.   list: Array<TodoItem>
  17.   total: number
  18. }
  19. type OperationResult = {
  20.   errCode: number
  21.   errMsg: string
  22. }
  23. const todo = uniCloud.importObject('todo')
  24. const addTodo = (title: string, content: string) => {
  25.   todo.add<AddResult>(title, content).then((res) => {
  26.     if (res.errCode == 0) {
  27.       uni.showToast({ title: '添加成功', icon: 'success' })
  28.       console.log('新 ID:', res.id)
  29.     }
  30.   })
  31. }
  32. const listTodos = (page: number) => {
  33.   todo.list<ListResult>(page, 10).then((res) => {
  34.     if (res.errCode == 0) {
  35.       console.log('列表:', res.list)
  36.       console.log('总数:', res.total)
  37.     }
  38.   })
  39. }
  40. const updateStatus = (id: string, status: string) => {
  41.   todo.updateStatus<OperationResult>(id, status).then((res) => {
  42.     if (res.errCode == 0) {
  43.       uni.showToast({ title: '更新成功', icon: 'success' })
  44.     }
  45.   })
  46. }
  47. const removeTodo = (id: string) => {
  48.   todo.remove<OperationResult>(id).then((res) => {
  49.     if (res.errCode == 0) {
  50.       uni.showToast({ title: '删除成功', icon: 'success' })
  51.     }
  52.   })
  53. }
复制代码

完整页面里通常用 ref 管理 newTitle、newContent、todoList,onMounted 调 loadList。删除前可用 uni.showModal 做二次确认。云对象仍负责 add、list、updateStatus、remove,客户端只关心方法名和返回结构。

六、敏感方法加密调用

对敏感方法可以使用 secretMethods。changePassword 配置为 both,表示请求和响应都加密;updateProfile 配置为 request,表示只加密请求:
  1. const user = uniCloud.importObject('user', {
  2.   secretMethods: {
  3.     changePassword: 'both',
  4.     updateProfile: 'request'
  5.   }
  6. })
  7. user.changePassword('oldPass', 'newPass').then((res) => {
  8.   console.log('修改密码成功')
  9. })
复制代码

七、鸿蒙强类型限制与 index.obj.d.ts

HarmonyOS 4.61 起支持 uniCloud.importObject,但 uni-app x 是强类型语言,编译时需要读取本地云对象导出的方法列表。因此要确保调用的云对象在本地包含导出的方法。如果云函数加密导致 index.obj.js 无法被解析,需要创建 index.obj.d.ts 声明方法:
  1. type AnyFunction = (...args: any[]) => any;
  2. declare const add: AnyFunction
  3. declare const list: AnyFunction
  4. declare const updateStatus: AnyFunction
  5. declare const remove: AnyFunction
  6. export {
  7.   add,
  8.   list,
  9.   updateStatus,
  10.   remove
  11. }
复制代码

这一步是鸿蒙适配里最容易漏掉的点。没有声明时,编译期方法列表不完整,类型检查会报错或无法解析方法。

八、和 callFunction、鸿蒙原生 HTTP 对比

云函数写法需要传 name 和 data,再从 res.result 取结果:
  1. uniCloud.callFunction({
  2.   name: 'todo-add',
  3.   data: { title: '标题', content: '内容' }
  4. } as UniCloudCallFunctionOptions).then((res) => {
  5.   console.log(res.result)
  6. })
复制代码

云对象写法更像本地方法:
  1. const todo = uniCloud.importObject('todo')
  2. todo.add('标题', '内容').then((res) => {
  3.   console.log(res)
  4. })
复制代码

云对象可以在一个 index.obj.js 里定义多个方法,不用每个功能创建一个云函数目录。和鸿蒙原生远程调用相比,原生要自己处理 HTTP、序列化和错误处理:
  1. import { http } from '@kit.NetworkKit'
  2. const response = await http.createHttp().request(
  3.   'https://your-server.com/api/todo/add',
  4.   {
  5.     method: http.RequestMethod.POST,
  6.     extraData: JSON.stringify({ title: '标题' })
  7.   }
  8. )
  9. const result = JSON.parse(response.result as string)
复制代码

uniCloud 云对象省去搭服务器和处理 HTTP 的步骤,但前提是项目已经接入 uniCloud,并且按鸿蒙强类型要求补好本地声明。

适配清单

1. 确认 HarmonyOS 4.61 及以上,使用 uniCloud.importObject,它与 callFunction 同批支持。
2. 云对象目录放在 cloudfunctions/对象名/index.obj.js,module.exports 暴露方法。
3. 鸿蒙端优先用泛型定义返回结构,减少 UTSJSONObject 转换。
4. 默认自动 UI 可用 loadingOptions/errorOptions;需要自定义交互时设置 customUI: true。
5. 敏感方法通过 secretMethods 配置 both 或 request。
6. 若 index.obj.js 因加密无法解析,补 index.obj.d.ts,声明所有被调方法。
7. 与 callFunction 相比,云对象适合模块化 CRUD;与原生 HTTP 相比,少写网络层,但要接受 uniCloud 运行时约束。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-29 12:17 , Processed in 0.020803 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部