Appearance
IPC 通信
IPC(进程间通信)是连接前端 UI 和 Rust 后端的桥梁。灵动桌面框架提供了封装良好的 API 层来简化 IPC 调用。
invoke 调用流程
1. 定义 Rust Command
rust
// src-tauri/src/commands/system.rs
use crate::error::CommandError;
#[tauri::command]
pub fn greet(name: &str) -> Result<String, CommandError> {
if name.is_empty() {
return Err(CommandError::validation("姓名不能为空"));
}
Ok(format!("你好, {}!", name))
}2. 注册 Command
rust
// src-tauri/src/lib.rs
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![
commands::system::greet,
commands::system::get_system_info,
commands::config::get_all_config,
commands::config::get_config,
commands::config::set_config,
commands::config::delete_config,
])3. 前端 API 封装
typescript
// src/lib/api/system.ts
import { invokeCommand } from './client'
export async function greet(name: string): Promise<string> {
return invokeCommand<string>('greet', { name })
}4. 在组件中使用
tsx
import { greet } from '@/lib/api'
function MyComponent() {
const handleClick = async () => {
const message = await greet('灵动')
console.log(message) // "你好, 灵动!"
}
return <button onClick={handleClick}>打招呼</button>
}API Client 封装
框架提供了统一的 invoke 封装,自动处理错误解析:
typescript
// src/lib/api/client.ts
import { invoke } from '@tauri-apps/api/core'
export async function invokeCommand<T>(
cmd: string,
args?: Record<string, unknown>
): Promise<T> {
try {
return await invoke<T>(cmd, args)
} catch (error) {
// 统一错误处理
throw parseCommandError(error)
}
}useCommand Hook
typescript
// src/hooks/useCommand.ts
import { useState, useCallback } from 'react'
import { invokeCommand } from '@/lib/api/client'
export function useCommand<T>(cmd: string) {
const [data, setData] = useState<T | null>(null)
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const execute = useCallback(async (args?: Record<string, unknown>) => {
setLoading(true)
setError(null)
try {
const result = await invokeCommand<T>(cmd, args)
setData(result)
return result
} catch (e) {
setError(String(e))
throw e
} finally {
setLoading(false)
}
}, [cmd])
return { data, loading, error, execute }
}事件通信
除了请求-响应式的 invoke,还支持事件驱动的通信:
rust
// Rust 端发送事件
use tauri::Emitter;
app_handle.emit("update-available", version)?;typescript
// 前端监听
import { listen } from '@tauri-apps/api/event'
const unlisten = await listen('update-available', (event) => {
console.log('新版本:', event.payload)
})
// 清理监听
unlisten()最佳实践
规范
- 所有 invoke 调用必须封装到
src/lib/api/中,禁止在组件中直接使用invoke() - 每个 Command 必须返回
Result<T, CommandError>,禁止使用unwrap() - 大数据传输考虑分批次或使用事件流