鸿蒙专家 发表于 2026-9-29 10:00:00

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

在 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 签名如下:


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:


'use strict';
const db = uniCloud.database()
const collection = db.collection('todos')
module.exports = {
async add(title, content) {
    const result = await collection.add({
      title: title,
      content: content,
      status: 'pending',
      createTime: Date.now()
    })
    return {
      errCode: 0,
      errMsg: '',
      id: result.id
    }
},
async list(page, pageSize) {
    const countResult = await collection.count()
    const listResult = await collection
      .skip((page - 1) * pageSize)
      .limit(pageSize)
      .orderBy('createTime', 'desc')
      .get()
    return {
      errCode: 0,
      errMsg: '',
      list: listResult.data,
      total: countResult.total
    }
},
async updateStatus(id, status) {
    await collection.doc(id).update({
      status: status
    })
    return {
      errCode: 0,
      errMsg: ''
    }
},
async remove(id) {
    await collection.doc(id).remove()
    return {
      errCode: 0,
      errMsg: ''
    }
}
}


导入后直接调用:


const todo = uniCloud.importObject('todo')
const result = await todo.add('标题', '内容')


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

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

uni-app x 是强类型语言,云对象返回值最好定义类型。4.13 版本起支持泛型调用:


type AddResult = {
errCode: number
errMsg: string
id: string
}

type ListResult = {
errCode: number
errMsg: string
list: Array<UTSJSONObject>
total: number
}

const todo = uniCloud.importObject('todo')
todo.add<AddResult>('学习 uni-app x', '写一篇鸿蒙开发文章').then((res) => {
console.log('添加成功,ID:', res.id)
})
todo.list<ListResult>(1, 10).then((res) => {
console.log('总数:', res.total)
console.log('列表:', res.list)
})


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

四、自动 loading 与错误提示

云对象默认会自动展示 loading 和错误提示,可通过 loadingOptions、errorOptions 配置:


const todo = uniCloud.importObject('todo', {
loadingOptions: {
    title: '加载中...',
    mask: true
},
errorOptions: {
    type: 'modal',
    retry: true
}
})

todo.list<ListResult>(1, 10).then((res) => {
console.log('列表:', res.list)
})


如果不想用默认 UI,可以设置 customUI: true 关闭,然后自己 showLoading、hideLoading,并在 catch 中处理错误:


const todo = uniCloud.importObject('todo', {
customUI: true
})

uni.showLoading({ title: '自定义 loading...' })
todo.list<ListResult>(1, 10).then((res) => {
uni.hideLoading()
console.log('列表:', res.list)
}).catch((err) => {
uni.hideLoading()
uni.showToast({
    title: '加载失败',
    icon: 'none'
})
})


五、CRUD 实战

一个完整的待办 CRUD 可以这样组织类型和调用:


type TodoItem = {
_id: string
title: string
content: string
status: string
createTime: number
}

type AddResult = {
errCode: number
errMsg: string
id: string
}

type ListResult = {
errCode: number
errMsg: string
list: Array<TodoItem>
total: number
}

type OperationResult = {
errCode: number
errMsg: string
}

const todo = uniCloud.importObject('todo')

const addTodo = (title: string, content: string) => {
todo.add<AddResult>(title, content).then((res) => {
    if (res.errCode == 0) {
      uni.showToast({ title: '添加成功', icon: 'success' })
      console.log('新 ID:', res.id)
    }
})
}

const listTodos = (page: number) => {
todo.list<ListResult>(page, 10).then((res) => {
    if (res.errCode == 0) {
      console.log('列表:', res.list)
      console.log('总数:', res.total)
    }
})
}

const updateStatus = (id: string, status: string) => {
todo.updateStatus<OperationResult>(id, status).then((res) => {
    if (res.errCode == 0) {
      uni.showToast({ title: '更新成功', icon: 'success' })
    }
})
}

const removeTodo = (id: string) => {
todo.remove<OperationResult>(id).then((res) => {
    if (res.errCode == 0) {
      uni.showToast({ title: '删除成功', icon: 'success' })
    }
})
}


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

六、敏感方法加密调用

对敏感方法可以使用 secretMethods。changePassword 配置为 both,表示请求和响应都加密;updateProfile 配置为 request,表示只加密请求:


const user = uniCloud.importObject('user', {
secretMethods: {
    changePassword: 'both',
    updateProfile: 'request'
}
})

user.changePassword('oldPass', 'newPass').then((res) => {
console.log('修改密码成功')
})


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

HarmonyOS 4.61 起支持 uniCloud.importObject,但 uni-app x 是强类型语言,编译时需要读取本地云对象导出的方法列表。因此要确保调用的云对象在本地包含导出的方法。如果云函数加密导致 index.obj.js 无法被解析,需要创建 index.obj.d.ts 声明方法:


type AnyFunction = (...args: any[]) => any;
declare const add: AnyFunction
declare const list: AnyFunction
declare const updateStatus: AnyFunction
declare const remove: AnyFunction
export {
add,
list,
updateStatus,
remove
}


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

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

云函数写法需要传 name 和 data,再从 res.result 取结果:


uniCloud.callFunction({
name: 'todo-add',
data: { title: '标题', content: '内容' }
} as UniCloudCallFunctionOptions).then((res) => {
console.log(res.result)
})


云对象写法更像本地方法:


const todo = uniCloud.importObject('todo')
todo.add('标题', '内容').then((res) => {
console.log(res)
})


云对象可以在一个 index.obj.js 里定义多个方法,不用每个功能创建一个云函数目录。和鸿蒙原生远程调用相比,原生要自己处理 HTTP、序列化和错误处理:


import { http } from '@kit.NetworkKit'
const response = await http.createHttp().request(
'https://your-server.com/api/todo/add',
{
    method: http.RequestMethod.POST,
    extraData: JSON.stringify({ title: '标题' })
}
)
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 运行时约束。

热心网友2 发表于 2026-9-29 19:00:00

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

感谢分享,整理得很实用。以前鸿蒙端调云函数确实要每次 callFunction 带函数名和 data,云对象 importObject 后直接 todo.add 这种写法清爽很多。按 index.obj.js 组织 add、list、updateStatus、remove 的 CRUD 示例也很清楚,容易照着改。泛型那段对 uni-app x 强类型帮助很大,AddResult 和 ListResult 定义好之后,res.id、res.total 能直接访问,少掉一层 UTSJSONObject 转换,编译期也更容易发现字段错误。另外 loadingOptions、errorOptions 默认处理 loading 和错误提示,适合快速页面。想问下 customUI 设为 true 后,手动 showLoading、hideLoading 一般放在调用云对象方法前后,还是在导入对象时做统一封装?还有 list 返回的数组里如果存的是 UTSJSONObject,鸿蒙端渲染前是否还要再转成具体 item 类型?期待后续补充。

热心网友2 发表于 2026-9-29 19:10:00

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

楼主整理得挺全的,鸿蒙端 uni-app x 用 importObject 确实比每次 callFunction 传函数名和 data 顺手很多,尤其是 todo 这种 CRUD,直接 todo.add、todo.list 调起来更像本地方法。泛型那块很实用,uni-app x 本来就是强类型,返回值定义好类型后 res.id、res.total 能直接访问,编译期也能少踩字段拼错的坑。默认 loading 和错误提示加上 loadingOptions、errorOptions 基本够用,想自定义再用 customUI 关掉自己 showLoading、hideLoading 和 catch 处理也更灵活。鸿蒙 4.61 和 callFunction 同批支持这个兼容点很关键,收藏了,期待后面的 CRUD、加密和强类型适配内容。

热心网友3 发表于 2026-9-29 19:20:00

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

看完挺有收获,特别是云对象这套写法用 CRUD 来说明很直观。以前 callFunction 每次都要传函数名和 data,拿 result 再解析;换成 importObject 之后,像 todo.add、todo.list 这样直接调用,代码确实清爽很多。 泛型那段也很实用。uni-app x 在鸿蒙上强类型,返回值如果能定义成 AddResult、ListResult,res.id、res.total、res.list 就能直接访问,不用先转 UTSJSONObject,字段拼写和结构问题也更容易在编译期暴露。鸿蒙 4.61 开始支持 importObject,并且和 callFunction 是同一批能力,这个版本点很关键。 自动 loading 和错误提示那块也挺方便,loadingOptions、errorOptions 能省不少模板代码;如果不想用默认 UI,再 customUI: true 自己 showLoading、hideLoading,并在 catch 里处理,这个思路很清晰。 想问一下,如果 list 返回的每一项结构固定,是不是也可以把 ListResult 里的 Array 换成更具体的类型?这样前端遍历和访问字段应该会更安全。整体感觉 importObject 很适合 todo、用户资料这类服务化接口,比每次 callFunction 更接近本地方
页: [1]
查看完整版本: 鸿蒙 uni-app x 云对象 importObject 适配