跳到主要内容

事件

Tauri 事件系统是一个多生产者多消费者通信原语,允许在前端和后端之间进行消息传递。它类似于命令系统,但在事件处理程序上必须编写有效负载类型检查,它简化了从后端到前端的通信,就像一个通道。

Tauri 应用程序可以监听和发出全局和特定于窗口的事件。下面描述了前端和后端的使用方法。

前端

在前端,事件系统可以通过 `@tauri-apps/api` 包的 `event` 和 `window` 模块访问。

全局事件

要使用全局事件通道,请导入 `event` 模块并使用 `emit` 和 `listen` 函数。

import { emit, listen } from '@tauri-apps/api/event'

// listen to the `click` event and get a function to remove the event listener
// there's also a `once` function that subscribes to an event and automatically unsubscribes the listener on the first event
const unlisten = await listen('click', (event) => {
// event.event is the event name (useful if you want to use a single callback fn for multiple event types)
// event.payload is the payload object
})

// emits the `click` event with the object payload
emit('click', {
theMessage: 'Tauri is awesome!',
})

特定于窗口的事件

特定于窗口的事件在 `window` 模块中公开。

import { appWindow, WebviewWindow } from '@tauri-apps/api/window'

// emit an event that is only visible to the current window
appWindow.emit('event', { message: 'Tauri is awesome!' })

// create a new webview window and emit an event only to that window
const webview = new WebviewWindow('window')
webview.emit('event')

后端

在后端,全局事件通道在 `App` 结构体中公开,可以使用 `Window` trait 发出特定于窗口的事件。

全局事件

use tauri::Manager;

// the payload type must implement `Serialize` and `Clone`.
#[derive(Clone, serde::Serialize)]
struct Payload {
message: String,
}

fn main() {
tauri::Builder::default()
.setup(|app| {
// listen to the `event-name` (emitted on any window)
let id = app.listen_global("event-name", |event| {
println!("got event-name with payload {:?}", event.payload());
});
// unlisten to the event using the `id` returned on the `listen_global` function
// a `once_global` API is also exposed on the `App` struct
app.unlisten(id);

// emit the `event-name` event to all webview windows on the frontend
app.emit_all("event-name", Payload { message: "Tauri is awesome!".into() }).unwrap();
Ok(())
})
.run(tauri::generate_context!())
.expect("failed to run app");
}

特定于窗口的事件

要使用特定于窗口的事件通道,可以在命令处理程序中或使用 `get_window` 函数获取 `Window` 对象。

use tauri::{Manager, Window};

// the payload type must implement `Serialize` and `Clone`.
#[derive(Clone, serde::Serialize)]
struct Payload {
message: String,
}

// init a background process on the command, and emit periodic events only to the window that used the command
#[tauri::command]
fn init_process(window: Window) {
std::thread::spawn(move || {
loop {
window.emit("event-name", Payload { message: "Tauri is awesome!".into() }).unwrap();
}
});
}

fn main() {
tauri::Builder::default()
.setup(|app| {
// `main` here is the window label; it is defined on the window creation or under `tauri.conf.json`
// the default value is `main`. note that it must be unique
let main_window = app.get_window("main").unwrap();

// listen to the `event-name` (emitted on the `main` window)
let id = main_window.listen("event-name", |event| {
println!("got window event-name with payload {:?}", event.payload());
});
// unlisten to the event using the `id` returned on the `listen` function
// an `once` API is also exposed on the `Window` struct
main_window.unlisten(id);

// emit the `event-name` event to the `main` window
main_window.emit("event-name", Payload { message: "Tauri is awesome!".into() }).unwrap();
Ok(())
})
.invoke_handler(tauri::generate_handler![init_process])
.run(tauri::generate_context!())
.expect("failed to run app");
}