Tauri 插件

通过插件,您可以连接到 Tauri 应用程序生命周期,并引入新的命令。

使用插件

要使用插件,只需将插件实例传递给应用程序的plugin方法即可:


fn main() {
  tauri::Builder::default()
    .plugin(my_awesome_plugin::init())
    .run(tauri::generate_context!())
    .expect("failed to run app");
}

编写插件

插件是 Tauri API 的可重用扩展,用于解决常见问题。它们也是构建代码库的一种非常方便的方式!

如果您打算与他人共享您的插件,我们会提供一个现成的模板!安装 Tauri CLI 后,只需运行

  • npm
  • Yarn
  • pnpm
  • Cargo

npm run tauri plugin init -- --name awesome

yarn tauri plugin init --name awesome

pnpm tauri plugin init --name awesome

cargo tauri plugin init --name awesome

API 软件包

默认情况下,插件的用户可以像这样调用提供的命令:


import { invoke } from '@tauri-apps/api'
invoke('plugin:awesome|do_something')    

其中 awesome 将由您的插件名称代替。

不过,这样做并不方便,因此插件通常会提供一个所谓的 API 包,即一个可以方便地访问命令的 JavaScript 包。

例如,tauri-plugin-store 为访问商店提供了方便的类结构。你可以像这样用一个附加的 javascript 应用程序接口包为 tauri 插件搭建脚手架:

  • npm
  • Yarn
  • pnpm
  • Cargo

npm run tauri plugin init -- --name awesome --api

yarn tauri plugin init --name awesome --api

pnpm tauri plugin init --name awesome --api

cargo tauri plugin init --name awesome --api

编写插件

使用 tauri::plugin::Builder 可以像定义应用程序一样定义插件:



use tauri::{
  plugin::{Builder, TauriPlugin},
  Runtime,
};

// the plugin custom command handlers if you choose to extend the API:

#[tauri::command]
// this will be accessible with `invoke('plugin:awesome|initialize')`.
// where `awesome` is the plugin name.
fn initialize() {}

#[tauri::command]
// this will be accessible with `invoke('plugin:awesome|do_something')`.
fn do_something() {}

pub fn init<R: Runtime>() -> TauriPlugin<R> {
  Builder::new("awesome")
    .invoke_handler(tauri::generate_handler![initialize, do_something])
    .build()
}


插件可以像应用程序一样设置和维护状态:



use tauri::{
  plugin::{Builder, TauriPlugin},
  AppHandle, Manager, Runtime, State,
};

#[derive(Default)]
struct MyState {}

#[tauri::command]
// this will be accessible with `invoke('plugin:awesome|do_something')`.
fn do_something<R: Runtime>(_app: AppHandle<R>, state: State<'_, MyState>) {
  // you can access `MyState` here!
}

pub fn init<R: Runtime>() -> TauriPlugin<R> {
  Builder::new("awesome")
    .invoke_handler(tauri::generate_handler![do_something])
    .setup(|app_handle| {
      // setup plugin specific state here
      app_handle.manage(MyState::default());
      Ok(())
    })
    .build()
}


规范

  • 板块会导出一个 init 方法来创建插件。
  • 插件应有一个明确的名称,并以 tauri-plugin- 为前缀。
  • Cargo.toml/package.json 中加入 tauri-plugin 关键字。
  • 用英语编写插件文档。
  • 添加一个示例应用程序,展示您的插件。

高级

与其依赖 tauri::plugin::Builder::build 返回的 tauri::plugin::TauriPlugin 结构,你可以自己实现 tauri::plugin::Plugin。这样你就可以完全控制相关数据。

请注意,除了 name 函数外,Plugin 特质上的每个函数都是可选的。



use tauri::{plugin::{Plugin, Result as PluginResult}, Runtime, PageLoadPayload, Window, Invoke, AppHandle};

struct MyAwesomePlugin<R: Runtime> {
  invoke_handler: Box<dyn Fn(Invoke<R>) + Send + Sync>,
  // 插件状态,配置字段
}

// 如果您选择扩展 API,还可以使用插件的自定义命令处理程序。
#[tauri::command]
// 可通过 `invoke('plugin:awesome|initialize')` 访问。
// 其中 `awesome` 是插件名称。
fn initialize() {}

#[tauri::command]
// 可通过 `invoke('plugin:awesome|do_something')` 访问。
fn do_something() {}

impl<R: Runtime> MyAwesomePlugin<R> {
  // 您可以在此添加配置字段,
  // 请查阅 https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
  pub fn new() -> Self {
    Self {
      invoke_handler: Box::new(tauri::generate_handler![initialize, do_something]),
    }
  }
}

impl<R: Runtime> Plugin<R> for MyAwesomePlugin<R> {
  /// 插件名称。必须在调用 `invoke` 时定义和使用。
  fn name(&self) -> &'static str {
    "awesome"
  }

  /// 初始化时要评估的 JS 脚本。
  /// 当您的插件可通过 `window` 访问时非常有用
  /// 或需要在应用程序初始化时执行 JS 任务
  /// 例如 "window.awesomePlugin = { ... the plugin interface }"
  fn initialization_script(&self) -> Option<String> {
    None
  }

  /// 使用 `tauri.conf.json > plugins > $yourPluginName` 中提供的配置或默认值初始化插件。
  fn initialize(&mut self, app: &AppHandle<R>, config: serde_json::Value) -> PluginResult<()> {
    Ok(())
  }

  /// 窗口创建时调用的回调。
  fn created(&mut self, window: Window<R>) {}

  /// 当 webview 执行导航操作时调用的回调。
  fn on_page_load(&mut self, window: Window<R>, payload: PageLoadPayload) {}

  /// 扩展调用处理程序。
  fn extend_api(&mut self, message: Invoke<R>) {
    (self.invoke_handler)(message)
  }
}