从 Tauri 1.0 升级
本指南引导你将 Tauri 1.0 应用升级到 Tauri 2.0。
🌐 This guide walks you through upgrading your Tauri 1.0 application to Tauri 2.0.
🌐 Preparing for Mobile
Tauri 的移动端界面要求你的项目输出一个共享库。如果你针对现有应用进行移动端开发,你必须更改你的 crate,以生成这种类型的构件以及桌面可执行文件。
🌐 The mobile interface of Tauri requires your project to output a shared library. If you are targeting mobile for your existing application, you must change your crate to produce that kind of artifact along with the desktop executable.
- 更改 Cargo 清单以生成库。追加以下代码块:
[lib]name = "app_lib"crate-type = ["staticlib", "cdylib", "rlib"]- 将
src-tauri/src/main.rs重命名为src-tauri/src/lib.rs。此文件将由桌面和移动端共享。 - 将
lib.rs中的main函数头重命名为以下内容:
#[cfg_attr(mobile, tauri::mobile_entry_point)]pub fn run() { // your code here}tauri::mobile_entry_point 宏准备你的函数在移动设备上执行。
🌐 The tauri::mobile_entry_point macro prepares your function to be executed on mobile.
- 重新创建调用共享运行函数的
main.rs文件:
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() { app_lib::run();}🌐 Automated Migration
Tauri v2 CLI 包含一个 migrate 命令,它可以自动补齐大部分流程并帮助你完成迁移:
🌐 The Tauri v2 CLI includes a migrate command that automates most of the process and helps you finish the migration:
npm install @tauri-apps/cli@latestnpm run tauri migrateyarn upgrade @tauri-apps/cli@latestyarn tauri migratepnpm update @tauri-apps/cli@latestpnpm tauri migratecargo install tauri-cli --version "^2.0.0" --lockedcargo tauri migrate在命令行接口参考中了解有关migrate命令的更多信息
🌐 Learn more about the migrate command in the Command Line Interface reference
🌐 Summary of Changes
以下是 Tauri 1.0 到 Tauri 2.0 的变更摘要:
🌐 Below is a summary of the changes from Tauri 1.0 to Tauri 2.0:
🌐 Tauri Configuration
package > productName和package > version已移至顶层对象。- 二进制名称不再自动重命名以匹配
productName,因此你必须在顶层对象中添加一个匹配productName的mainBinaryName字符串。 package已删除。tauri键已重命名为app。tauri > allowlist已移除。请参阅 迁移权限。tauri > allowlist > protocol > assetScope移动到了app > security > assetProtocol > scope。tauri > cli移动到了plugins > cli。tauri > windows > fileDropEnabled已重命名为app > windows > dragDropEnabled。tauri > updater > active已删除。tauri > updater > dialog已删除。tauri > updater移动到了plugins > updater。bundle > createUpdaterArtifacts已添加,使用应用更新器时必须设置。- 在从已经分发的 v1 应用升级时,将其设置为
v1Compatible。有关更多信息,请参阅更新指南。
- 在从已经分发的 v1 应用升级时,将其设置为
tauri > systemTray已重命名为app > trayIcon。tauri > pattern移动到了app > security > pattern。tauri > bundle移动到了顶层。tauri > bundle > identifier移动到顶层对象。tauri > bundle > dmg搬到了bundle > macOS > dmgtauri > bundle > deb搬到了bundle > linux > debtauri > bundle > appimage搬到了bundle > linux > appimagetauri > bundle > macOS > license已被移除,请改用bundle > licenseFile。tauri > bundle > windows > wix > license已被移除,请改用bundle > licenseFile。tauri > bundle > windows > nsis > license已被移除,请改用bundle > licenseFile。tauri > bundle > windows > webviewFixedRuntimePath已被移除,请改用bundle > windows > webviewInstallMode。build > withGlobalTauri移动到了app > withGlobalTauri。build > distDir已重命名为frontendDist。build > devPath已重命名为devUrl。
🌐 New Cargo Features
- linux-protocol-body:启用自定义协议请求体解析,允许 IPC 使用它。需要 webkit2gtk 2.40。
🌐 Removed Cargo Features
- reqwest-client:reqwest 现在是唯一支持的客户端。
- reqwest-native-tls-vendored:改用
native-tls-vendored。 - process-command-api:请改用
shell插件(详见下一节的说明)。 - shell-open-api:请改用
shell插件(详见以下部分的说明)。 - windows7-compat:已移至
notification插件。 - 更新器:更新器现在是一个插件。
- linux-protocol-headers:自从我们升级了最低的 webkit2gtk 版本后,现在默认已启用。
- 系统托盘:已重命名为
tray-icon。
🌐 Rust Crate Changes
api模块已被移除。每个 API 模块都可以在 Tauri 插件中找到。api::dialog模块已被移除。请改用tauri-plugin-dialog。 迁移api::file模块已被移除。请改用 Rust 的std::fs。api::http模块已被移除。请改用tauri-plugin-http。迁移api::ip模块已重写并移动到tauri::ipc。查看新的 API,特别是tauri::ipc::Channel。api::path模块功能和tauri::PathResolved已移动到tauri::Manager::path。迁移api::process::Command、tauri::api::shell和tauri::Manager::shell_scopeAPI 已被移除。请改用tauri-plugin-shell。迁移api::process::current_binary和tauri::api::process::restart搬到了tauri::process。api::version模块已被移除。请改用 semver 套件。App::clipboard_manager和AppHandle::clipboard_manager已移除。请改用tauri-plugin-clipboard。迁移App::get_cli_matches已被移除。请改用tauri-plugin-cli。迁移App::global_shortcut_manager和AppHandle::global_shortcut_manager已移除。请改用tauri-plugin-global-shortcut。迁移Manager::fs_scope已移除。文件系统范围可以通过tauri_plugin_fs::FsExt访问。Plugin::PluginApi现在将插件配置作为第二个参数接收。Plugin::setup_with_config已被移除。请改用更新后的tauri::Plugin::PluginApi。scope::ipc::RemoteDomainAccessScope::enable_tauri_api和scope::ipc::RemoteDomainAccessScope::enables_tauri_api已移除。请改为通过scope::ipc::RemoteDomainAccessScope::add_plugin单独启用每个核心插件。scope::IpcScope已被移除,请改用scope::ipc::Scope。scope::FsScope、scope::GlobPattern和scope::FsScopeEvent已移除,分别使用scope::fs::Scope、scope::fs::Pattern和scope::fs::Event。updater模块已被移除。请改用tauri-plugin-updater。 迁移Env.args字段已被移除,请改用Env.args_os字段。Menu、MenuEvent、CustomMenuItem、Submenu、WindowMenuEvent、MenuItem和Builder::on_menu_eventAPI 已移除。迁移SystemTray、SystemTrayHandle、SystemTrayMenu、SystemTrayMenuItemHandle、SystemTraySubmenu、MenuEntry和SystemTrayMenuItemAPI 已移除。迁移
🌐 JavaScript API Changes
@tauri-apps/api 包不再提供非核心模块。仅以前的 tauri(现在的 core)、path、event 和 window 模块被导出。所有其他模块都已移至插件。
🌐 The @tauri-apps/api package no longer provides non-core modules. Only the previous tauri (now core), path, event and window modules are exported. All others have been moved to plugins.
@tauri-apps/api/tauri模块已重命名为@tauri-apps/api/core。迁移@tauri-apps/api/cli模块已被移除。请改用@tauri-apps/plugin-cli。 迁移@tauri-apps/api/clipboard模块已被移除。请改用@tauri-apps/plugin-clipboard。 迁移@tauri-apps/api/dialog模块已被移除。请改用@tauri-apps/plugin-dialog。迁移@tauri-apps/api/fs模块已被移除。请改用@tauri-apps/plugin-fs。 迁移@tauri-apps/api/global-shortcut模块已被移除。请改用@tauri-apps/plugin-global-shortcut。迁移@tauri-apps/api/http模块已被移除。请改用@tauri-apps/plugin-http。迁移@tauri-apps/api/os模块已被移除。请改用@tauri-apps/plugin-os。 迁移@tauri-apps/api/notification模块已被移除。请改用@tauri-apps/plugin-notification。迁移@tauri-apps/api/process模块已被移除。请改用@tauri-apps/plugin-process。迁移@tauri-apps/api/shell模块已被移除。请改用@tauri-apps/plugin-shell。迁移@tauri-apps/api/updater模块已被移除。请改用@tauri-apps/plugin-updater迁移@tauri-apps/api/window模块已重命名为@tauri-apps/api/webviewWindow。迁移
v1 插件现在发布为 @tauri-apps/plugin-<plugin-name>。之前它们可以从 git 获取,名称为 tauri-plugin-<plugin-name>-api。
🌐 Environment Variables Changes
Tauri CLI 读取和写入的大多数环境变量都已重命名,以保持一致性和防止错误:
🌐 Most of the environment variables read and written by the Tauri CLI were renamed for consistency and prevention of mistakes:
TAURI_PRIVATE_KEY->TAURI_SIGNING_PRIVATE_KEYTAURI_KEY_PASSWORD->TAURI_SIGNING_PRIVATE_KEY_PASSWORDTAURI_SKIP_DEVSERVER_CHECK->TAURI_CLI_NO_DEV_SERVER_WAITTAURI_DEV_SERVER_PORT->TAURI_CLI_PORTTAURI_PATH_DEPTH->TAURI_CLI_CONFIG_DEPTHTAURI_FIPS_COMPLIANT->TAURI_BUNDLER_WIX_FIPS_COMPLIANTTAURI_DEV_WATCHER_IGNORE_FILE->TAURI_CLI_WATCHER_IGNORE_FILENAMETAURI_TRAY->TAURI_LINUX_AYATANA_APPINDICATORTAURI_APPLE_DEVELOPMENT_TEAM->APPLE_DEVELOPMENT_TEAMTAURI_PLATFORM->TAURI_ENV_PLATFORMTAURI_ARCH->TAURI_ENV_ARCHTAURI_FAMILY->TAURI_ENV_FAMILYTAURI_PLATFORM_VERSION->TAURI_ENV_PLATFORM_VERSIONTAURI_PLATFORM_TYPE->TAURI_ENV_PLATFORM_TYPETAURI_DEBUG->TAURI_ENV_DEBUG
🌐 Event System
事件系统被重新设计为更易于使用。它不再依赖事件的来源,而是采用了基于事件目标的更简单的实现方式。
🌐 The event system was redesigned to be easier to use. Instead of relying on the source of the event, it now has a simpler implementation that relies on event targets.
emit函数现在会向所有事件监听器触发事件。- 新增了一个
emit_to/emitTo函数,用于触发针对特定目标的事件。 emit_filter现在基于EventTarget进行过滤,而不是基于窗口。- 已将
listen_global重命名为listen_any。它现在会监听所有事件,不管它们的筛选器和目标如何。 - JavaScript:
event.listen()的行为类似于listen_any。它现在会监听所有事件,不管它们的过滤器和目标是什么,除非在Options中设置了目标。 - JavaScript:
WebviewWindow.listen等只监听发往各自EventTarget的事件。
🌐 Multiwebview support
Tauri v2 引入了多网页视图支持,目前处于 unstable 功能标志下。为了支持它,我们将 Rust 的 Window 类型重命名为 WebviewWindow,并将 Manager 的 get_window 函数重命名为 get_webview_window。
🌐 Tauri v2 introduces multiwebview support currently behind an unstable feature flag.
In order to support it, we renamed the Rust Window type to WebviewWindow and the Manager get_window function to get_webview_window.
WebviewWindow JS API 类型现在从 @tauri-apps/api/webviewWindow 重新导出,而不是从 @tauri-apps/api/window。
🌐 The WebviewWindow JS API type is now re-exported from @tauri-apps/api/webviewWindow instead of @tauri-apps/api/window.
🌐 New origin URL on Windows
在 Windows 上,生产应用中的前端文件现在托管在 http://tauri.localhost 而不是 https://tauri.localhost。因此,除非在 v1 中使用了 dangerousUseHttpScheme,否则 IndexedDB、LocalStorage 和 Cookies 都会被重置。为防止这种情况,你可以将 app > windows > useHttpsScheme 设置为 true,或者使用 WebviewWindowBuilder::use_https_scheme 来继续使用 https 方案。
🌐 On Windows the frontend files in production apps are now hosted on http://tauri.localhost instead of https://tauri.localhost. Because of this IndexedDB, LocalStorage and Cookies will be reset unless dangerousUseHttpScheme was used in v1. To prevent this you can set app > windows > useHttpsScheme to true or use WebviewWindowBuilder::use_https_scheme to keep using the https scheme.
🌐 Detailed Migration Steps
将 Tauri 1.0 应用迁移到 Tauri 2.0 时可能会遇到的常见场景。
🌐 Common scenarios you may encounter when migrating your Tauri 1.0 app to Tauri 2.0.
🌐 Migrate to Core Module
@tauri-apps/api/tauri 模块已重命名为 @tauri-apps/api/core。
只需重命名模块导入即可:
🌐 The @tauri-apps/api/tauri module was renamed to @tauri-apps/api/core.
Simply rename the module import:
import { invoke } from "@tauri-apps/api/tauri"import { invoke } from "@tauri-apps/api/core"🌐 Migrate to CLI Plugin
Rust 的 App::get_cli_matches JavaScript @tauri-apps/api/cli API 已被移除。请改用 @tauri-apps/plugin-cli 插件:
🌐 The Rust App::get_cli_matches JavaScript @tauri-apps/api/cli APIs have been removed. Use the @tauri-apps/plugin-cli plugin instead:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-cli = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_cli::init())}{ "dependencies": { "@tauri-apps/plugin-cli": "^2.0.0" }}import { getMatches } from '@tauri-apps/plugin-cli';const matches = await getMatches();fn main() { use tauri_plugin_cli::CliExt; tauri::Builder::default() .plugin(tauri_plugin_cli::init()) .setup(|app| { let cli_matches = app.cli().matches()?; Ok(()) })}🌐 Migrate to Clipboard Plugin
Rust 的 App::clipboard_manager 和 AppHandle::clipboard_manager 以及 JavaScript 的 @tauri-apps/api/clipboard API 已被移除。请改用 @tauri-apps/plugin-clipboard-manager 插件:
🌐 The Rust App::clipboard_manager and AppHandle::clipboard_manager and JavaScript @tauri-apps/api/clipboard APIs have been removed. Use the @tauri-apps/plugin-clipboard-manager plugin instead:
[dependencies]tauri-plugin-clipboard-manager = "2"fn main() { tauri::Builder::default() .plugin(tauri_plugin_clipboard_manager::init())}{ "dependencies": { "@tauri-apps/plugin-clipboard-manager": "^2.0.0" }}import { writeText, readText } from '@tauri-apps/plugin-clipboard-manager';await writeText('Tauri is awesome!');assert(await readText(), 'Tauri is awesome!');use tauri_plugin_clipboard::{ClipboardExt, ClipKind};tauri::Builder::default() .plugin(tauri_plugin_clipboard::init()) .setup(|app| { app.clipboard().write(ClipKind::PlainText { label: None, text: "Tauri is awesome!".into(), })?; Ok(()) })🌐 Migrate to Dialog Plugin
Rust 的 tauri::api::dialog JavaScript @tauri-apps/api/dialog API 已被移除。请改用 @tauri-apps/plugin-dialog 插件:
🌐 The Rust tauri::api::dialog JavaScript @tauri-apps/api/dialog APIs have been removed. Use the @tauri-apps/plugin-dialog plugin instead:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-dialog = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_dialog::init())}{ "dependencies": { "@tauri-apps/plugin-dialog": "^2.0.0" }}import { save } from '@tauri-apps/plugin-dialog';const filePath = await save({ filters: [ { name: 'Image', extensions: ['png', 'jpeg'], }, ],});use tauri_plugin_dialog::DialogExt;tauri::Builder::default() .plugin(tauri_plugin_dialog::init()) .setup(|app| { app.dialog().file().pick_file(|file_path| { // do something with the optional file path here // the file path is `None` if the user closed the dialog });
app.dialog().message("Tauri is Awesome!").show(); Ok(()) })🌐 Migrate to File System Plugin
Rust 的 App::get_cli_matches 和 JavaScript 的 @tauri-apps/api/fs API 已被移除。请改用 Rust 的 std::fs 和 JavaScript 的 @tauri-apps/plugin-fs 插件:
🌐 The Rust App::get_cli_matches JavaScript @tauri-apps/api/fs APIs have been removed. Use the std::fs for Rust and @tauri-apps/plugin-fs plugin for JavaScript instead:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-fs = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_fs::init())}{ "dependencies": { "@tauri-apps/plugin-fs": "^2.0.0" }}import { mkdir, BaseDirectory } from '@tauri-apps/plugin-fs';await mkdir('db', { baseDir: BaseDirectory.AppLocalData });某些函数和类型已重命名或删除:
🌐 Some functions and types have been renamed or removed:
Dir枚举别名已移除,使用BaseDirectory。FileEntry、FsBinaryFileOption、FsDirOptions、FsOptions、FsTextFileOption和BinaryFileContents接口及类型别名已被移除,并已替换为适合各个功能的新接口。createDir已重命名为mkdir。readBinaryFile已重命名为readFile。removeDir已被移除并替换为remove。removeFile已被移除并替换为remove。renameFile已被移除并替换为rename。writeBinaryFile已重命名为writeFile。
🌐 Migrate to Global Shortcut Plugin
Rust 的 App::global_shortcut_manager 和 AppHandle::global_shortcut_manager 以及 JavaScript 的 @tauri-apps/api/global-shortcut API 已被移除。请改用 @tauri-apps/plugin-global-shortcut 插件:
🌐 The Rust App::global_shortcut_manager and AppHandle::global_shortcut_manager and JavaScript @tauri-apps/api/global-shortcut APIs have been removed. Use the @tauri-apps/plugin-global-shortcut plugin instead:
- 添加到 Cargo 依赖:
[dependencies][target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]tauri-plugin-global-shortcut = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_global_shortcut::Builder::default().build())}{ "dependencies": { "@tauri-apps/plugin-global-shortcut": "^2.0.0" }}import { register } from '@tauri-apps/plugin-global-shortcut';await register('CommandOrControl+Shift+C', () => { console.log('Shortcut triggered');});use tauri_plugin_global_shortcut::GlobalShortcutExt;
tauri::Builder::default() .plugin( tauri_plugin_global_shortcut::Builder::new().with_handler(|app, shortcut| { println!("Shortcut triggered: {:?}", shortcut); }) .build(), ) .setup(|app| { // register a global shortcut // on macOS, the Cmd key is used // on Windows and Linux, the Ctrl key is used app.global_shortcut().register("CmdOrCtrl+Y")?; Ok(()) })🌐 Migrate to HTTP Plugin
Rust 的 tauri::api::http JavaScript @tauri-apps/api/http API 已被移除。请改用 @tauri-apps/plugin-http 插件:
🌐 The Rust tauri::api::http JavaScript @tauri-apps/api/http APIs have been removed. Use the @tauri-apps/plugin-http plugin instead:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-http = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_http::init())}{ "dependencies": { "@tauri-apps/plugin-http": "^2.0.0" }}import { fetch } from '@tauri-apps/plugin-http';const response = await fetch( 'https://raw.githubusercontent.com/tauri-apps/tauri/dev/package.json');use tauri_plugin_http::reqwest;
tauri::Builder::default() .plugin(tauri_plugin_http::init()) .setup(|app| { let response_data = tauri::async_runtime::block_on(async { let response = reqwest::get( "https://raw.githubusercontent.com/tauri-apps/tauri/dev/package.json", ) .await .unwrap(); response.text().await })?; Ok(()) })HTTP 插件重新导出 reqwest,所以你可以查看他们的文档以获取更多信息。
🌐 The HTTP plugin re-exports reqwest so you can check out their documentation for more information.
🌐 Migrate to Notification Plugin
Rust 的 tauri::api::notification JavaScript @tauri-apps/api/notification API 已被移除。请改用 @tauri-apps/plugin-notification 插件:
🌐 The Rust tauri::api::notification JavaScript @tauri-apps/api/notification APIs have been removed. Use the @tauri-apps/plugin-notification plugin instead:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-notification = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_notification::init())}{ "dependencies": { "@tauri-apps/plugin-notification": "^2.0.0" }}import { sendNotification } from '@tauri-apps/plugin-notification';sendNotification('Tauri is awesome!');use tauri_plugin_notification::NotificationExt;use tauri::plugin::PermissionState;
fn main() { tauri::Builder::default() .plugin(tauri_plugin_notification::init()) .setup(|app| { if app.notification().permission_state()? == PermissionState::Unknown { app.notification().request_permission()?; } if app.notification().permission_state()? == PermissionState::Granted { app.notification() .builder() .body("Tauri is awesome!") .show()?; } Ok(()) })}🌐 Migrate to Menu Module
Rust 的 Menu API 已移动到 tauri::menu 模块,并重构为使用 muda crate。
🌐 The Rust Menu APIs were moved to the tauri::menu module and refactored to use the muda crate.
🌐 Use tauri::menu::MenuBuilder
使用 tauri::menu::MenuBuilder 代替 tauri::Menu。注意,它的构造函数需要一个 Manager 实例(App、AppHandle 或 WebviewWindow 之一)作为参数:
🌐 Use tauri::menu::MenuBuilder instead of tauri::Menu. Note that its constructor takes a Manager instance (one of App, AppHandle or WebviewWindow) as an argument:
use tauri::menu::MenuBuilder;
tauri::Builder::default() .setup(|app| { let menu = MenuBuilder::new(app) .copy() .paste() .separator() .undo() .redo() .text("open-url", "Open URL") .check("toggle", "Toggle") .icon("show-app", "Show App", app.default_window_icon().cloned().unwrap()) .build()?; app.set_menu(menu); Ok(()) })🌐 Use tauri::menu::PredefinedMenuItem
使用 tauri::menu::PredefinedMenuItem 替代 tauri::MenuItem:
🌐 Use tauri::menu::PredefinedMenuItem instead of tauri::MenuItem:
use tauri::menu::{MenuBuilder, PredefinedMenuItem};
tauri::Builder::default() .setup(|app| { let menu = MenuBuilder::new(app).item(&PredefinedMenuItem::copy(app)?).build()?; Ok(()) })🌐 Use tauri::menu::MenuItemBuilder
使用 tauri::menu::MenuItemBuilder 替代 tauri::CustomMenuItem:
🌐 Use tauri::menu::MenuItemBuilder instead of tauri::CustomMenuItem:
use tauri::menu::MenuItemBuilder;
tauri::Builder::default() .setup(|app| { let toggle = MenuItemBuilder::new("Toggle").accelerator("Ctrl+Shift+T").build(app)?; Ok(()) })🌐 Use tauri::menu::SubmenuBuilder
使用 tauri::menu::SubmenuBuilder 替代 tauri::Submenu:
🌐 Use tauri::menu::SubmenuBuilder instead of tauri::Submenu:
use tauri::menu::{MenuBuilder, SubmenuBuilder};
tauri::Builder::default() .setup(|app| { let submenu = SubmenuBuilder::new(app, "Sub") .text("Tauri") .separator() .check("Is Awesome") .build()?; let menu = MenuBuilder::new(app).item(&submenu).build()?; Ok(()) })tauri::Builder::menu 现在接受一个闭包,因为菜单需要一个 Manager 实例来构建。更多信息请参见 文档。
🌐 Menu Events
Rust 的 tauri::Builder::on_menu_event API 已被移除。请改用 tauri::App::on_menu_event 或 tauri::AppHandle::on_menu_event:
🌐 The Rust tauri::Builder::on_menu_event API was removed. Use tauri::App::on_menu_event or tauri::AppHandle::on_menu_event instead:
use tauri::menu::{CheckMenuItemBuilder, MenuBuilder, MenuItemBuilder};
tauri::Builder::default() .setup(|app| { let toggle = MenuItemBuilder::with_id("toggle", "Toggle").build(app)?; let check = CheckMenuItemBuilder::new("Mark").build(app)?; let menu = MenuBuilder::new(app).items(&[&toggle, &check]).build()?;
app.set_menu(menu)?;
app.on_menu_event(move |app, event| { if event.id() == check.id() { println!("`check` triggered, do something! is checked? {}", check.is_checked().unwrap()); } else if event.id() == "toggle" { println!("toggle triggered!"); } }); Ok(()) })请注意,有两种方法可以检查选择了哪个菜单项:将该项移动到事件处理程序闭包中并比较 ID,或者通过 with_id 构造函数为该项定义自定义 ID,并使用该 ID 字符串进行比较。
🌐 Note that there are two ways to check which menu item was selected: move the item to the event handler closure and compare IDs, or define a custom ID for the item through the with_id constructor and use that ID string to compare.
🌐 Migrate to OS Plugin
Rust 的 tauri::api::os JavaScript @tauri-apps/api/os API 已被移除。请改用 @tauri-apps/plugin-os 插件:
🌐 The Rust tauri::api::os JavaScript @tauri-apps/api/os APIs have been removed. Use the @tauri-apps/plugin-os plugin instead:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-os = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_os::init())}{ "dependencies": { "@tauri-apps/plugin-os": "^2.0.0" }}import { arch } from '@tauri-apps/plugin-os';const architecture = await arch();fn main() { tauri::Builder::default() .plugin(tauri_plugin_os::init()) .setup(|app| { let os_arch = tauri_plugin_os::arch(); Ok(()) })}🌐 Migrate to Process Plugin
Rust 的 tauri::api::process JavaScript @tauri-apps/api/process API 已被移除。请改用 @tauri-apps/plugin-process 插件:
🌐 The Rust tauri::api::process JavaScript @tauri-apps/api/process APIs have been removed. Use the @tauri-apps/plugin-process plugin instead:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-process = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_process::init())}{ "dependencies": { "@tauri-apps/plugin-process": "^2.0.0" }}import { exit, relaunch } from '@tauri-apps/plugin-process';await exit(0);await relaunch();fn main() { tauri::Builder::default() .plugin(tauri_plugin_process::init()) .setup(|app| { // exit the app with a status code app.handle().exit(1); // restart the app app.handle().restart(); Ok(()) })}🌐 Migrate to Shell Plugin
Rust 的 tauri::api::shell JavaScript @tauri-apps/api/shell API 已被移除。请改用 @tauri-apps/plugin-shell 插件:
🌐 The Rust tauri::api::shell JavaScript @tauri-apps/api/shell APIs have been removed. Use the @tauri-apps/plugin-shell plugin instead:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-shell = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init())}{ "dependencies": { "@tauri-apps/plugin-shell": "^2.0.0" }}import { Command, open } from '@tauri-apps/plugin-shell';const output = await Command.create('echo', 'message').execute();
await open('https://github.com/tauri-apps/tauri');- 打开 URL
use tauri_plugin_shell::ShellExt;
fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .setup(|app| { app.shell().open("https://github.com/tauri-apps/tauri", None)?; Ok(()) })}- 生成子进程并检索状态代码
use tauri_plugin_shell::ShellExt;
fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .setup(|app| { let status = tauri::async_runtime::block_on(async move { app.shell().command("which").args(["ls"]).status().await.unwrap() }); println!("`which` finished with status: {:?}", status.code()); Ok(()) })}- 生成子进程并捕获其输出
use tauri_plugin_shell::ShellExt;
fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .setup(|app| { let output = tauri::async_runtime::block_on(async move { app.shell().command("echo").args(["TAURI"]).output().await.unwrap() }); assert!(output.status.success()); assert_eq!(String::from_utf8(output.stdout).unwrap(), "TAURI"); Ok(()) })}- 生成子进程并异步读取其事件:
use tauri_plugin_shell::{ShellExt, process::CommandEvent};
fn main() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .setup(|app| { let handle = app.handle().clone(); tauri::async_runtime::spawn(async move { let (mut rx, mut child) = handle.shell().command("cargo") .args(["tauri", "dev"]) .spawn() .expect("Failed to spawn cargo");
let mut i = 0; while let Some(event) = rx.recv().await { if let CommandEvent::Stdout(line) = event { println!("got: {}", String::from_utf8(line).unwrap()); i += 1; if i == 4 { child.write("message from Rust\n".as_bytes()).unwrap(); i = 0; } } } }); Ok(()) })}🌐 Migrate to Tray Icon Module
Rust 的 SystemTray API 为了一致性已重命名为 TrayIcon。新的 API 可以在 Rust 的 tray 模块中找到。
🌐 The Rust SystemTray APIs were renamed to TrayIcon for consistency. The new APIs can be found in the Rust tray module.
🌐 Use tauri::tray::TrayIconBuilder
使用 tauri::tray::TrayIconBuilder 替代 tauri::SystemTray:
🌐 Use tauri::tray::TrayIconBuilder instead of tauri::SystemTray:
let tray = tauri::tray::TrayIconBuilder::with_id("my-tray").build(app)?;有关更多信息,请参阅 TrayIconBuilder。
🌐 See TrayIconBuilder for more information.
🌐 Migrate to Menu
使用 tauri::menu::Menu 代替 tauri::SystemTrayMenu,使用 tauri::menu::Submenu 代替 tauri::SystemTraySubmenu,使用 tauri::menu::PredefinedMenuItem 代替 tauri::SystemTrayMenuItem。
🌐 Use tauri::menu::Menu instead of tauri::SystemTrayMenu, tauri::menu::Submenu instead of tauri::SystemTraySubmenu and tauri::menu::PredefinedMenuItem instead of tauri::SystemTrayMenuItem.
🌐 Tray Events
tauri::SystemTray::on_event 已被拆分为 tauri::tray::TrayIconBuilder::on_menu_event 和 tauri::tray::TrayIconBuilder::on_tray_icon_event:
use tauri::{ menu::{MenuBuilder, MenuItemBuilder}, tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},};
tauri::Builder::default() .setup(|app| { let toggle = MenuItemBuilder::with_id("toggle", "Toggle").build(app)?; let menu = MenuBuilder::new(app).items(&[&toggle]).build()?; let tray = TrayIconBuilder::new() .menu(&menu) .on_menu_event(move |app, event| match event.id().as_ref() { "toggle" => { println!("toggle clicked"); } _ => (), }) .on_tray_icon_event(|tray, event| { if let TrayIconEvent::Click { button: MouseButton::Left, button_state: MouseButtonState::Up, .. } = event { let app = tray.app_handle(); if let Some(webview_window) = app.get_webview_window("main") { let _ = webview_window.unminimize(); let _ = webview_window.show(); let _ = webview_window.set_focus(); } } }) .build(app)?;
Ok(()) })🌐 Migrate to Updater Plugin
Rust 的 tauri::updater 和 JavaScript 的 @tauri-apps/api-updater API 已被移除。要使用 @tauri-apps/plugin-updater 设置自定义更新目标:
🌐 The Rust tauri::updater and JavaScript @tauri-apps/api-updater APIs have been removed. To set a custom updater target with the @tauri-apps/plugin-updater:
- 添加到 Cargo 依赖:
[dependencies]tauri-plugin-updater = "2"- 在 JavaScript 或 Rust 项目中使用:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_updater::Builder::new().build())}{ "dependencies": { "@tauri-apps/plugin-updater": "^2.0.0" }}import { check } from '@tauri-apps/plugin-updater';import { relaunch } from '@tauri-apps/plugin-process';
const update = await check();if (update?.available) { console.log(`Update to ${update.version} available! Date: ${update.date}`); console.log(`Release notes: ${update.body}`); await update.downloadAndInstall(); // requires the `process` plugin await relaunch();}要检查更新:
🌐 To check for updates:
use tauri_plugin_updater::UpdaterExt;
fn main() { tauri::Builder::default() .plugin(tauri_plugin_updater::Builder::new().build()) .setup(|app| { let handle = app.handle(); tauri::async_runtime::spawn(async move { let response = handle.updater().check().await; }); Ok(()) })}要设置自定义更新程序目标:
🌐 To set a custom updater target:
fn main() { let mut updater = tauri_plugin_updater::Builder::new(); #[cfg(target_os = "macos")] { updater = updater.target("darwin-universal"); } tauri::Builder::default() .plugin(updater.build())}🌐 Migrate Path to Tauri Manager
Rust tauri::api::path 模块的函数和 tauri::PathResolver 已经被移动到 tauri::Manager::path:
🌐 The Rust tauri::api::path module functions and tauri::PathResolver have been moved to tauri::Manager::path:
use tauri::{path::BaseDirectory, Manager};
tauri::Builder::default() .setup(|app| { let home_dir_path = app.path().home_dir().expect("failed to get home dir");
let path = app.path().resolve("path/to/something", BaseDirectory::Config)?;
Ok(()) })🌐 Migrate to new Window API
在 Rust 方面,Window 已被重命名为 WebviewWindow,它的构建器 WindowBuilder 现在被命名为 WebviewWindowBuilder,而 WindowUrl 现在被命名为 WebviewUrl。
🌐 On the Rust side, Window was renamed to WebviewWindow, its builder WindowBuilder is now named WebviewWindowBuilder and WindowUrl is now named WebviewUrl.
此外,Manager::get_window 函数被重命名为 get_webview_window,窗口的 parent_window API 被重命名为 parent_raw,以支持高级窗口父级 API。
🌐 Additionally, the Manager::get_window function was renamed to get_webview_window and
the window’s parent_window API was renamed to parent_raw to support a high level window parent API.
在 JavaScript 端,WebviewWindow 类现在在 @tauri-apps/api/webviewWindow 路径中导出。
🌐 On the JavaScript side, the WebviewWindow class is now exported in the @tauri-apps/api/webviewWindow path.
onMenuClicked 函数已被移除,你可以在创建 JavaScript 菜单时拦截菜单事件。
🌐 The onMenuClicked function was removed, you can intercept menu events when creating a menu in JavaScript instead.
🌐 Migrate Embedded Additional Files (Resources)
在 JavaScript 端,确保你 迁移到文件系统插件。 另外,请注意在 迁移权限 中对 v1 白名单所做的更改。
🌐 On the JavaScript side, make sure you Migrate to File System Plugin. Additionally, note the changes made to the v1 allowlist in Migrate Permissions.
在 Rust 方面,确保你 将路径迁移到 Tauri 管理器。
🌐 On the Rust side, make sure you Migrate Path to Tauri Manager.
🌐 Migrate Embedded External Binaries (Sidecar)
在 Tauri v1 中,外部二进制文件及其参数是在允许列表中定义的。在 v2 中,请使用新的权限系统。有关更多信息,请阅读 迁移权限 。
🌐 In Tauri v1, the external binaries and their arguments were defined in the allowlist. In v2, use the new permissions system. Read Migrate Permissions for more information.
在 JavaScript 端,确保你迁移到 Shell 插件。
🌐 On the JavaScript side, make sure you Migrate to Shell Plugin.
在 Rust 方面,tauri::api::process API 已被移除。请改用 tauri_plugin_shell::ShellExt 和 tauri_plugin_shell::process::CommandEvent API。阅读 嵌入外部二进制文件 指南了解具体操作。
🌐 On the Rust side, tauri::api::process API has been removed. Use tauri_plugin_shell::ShellExt and tauri_plugin_shell::process::CommandEvent APIs instead. Read the Embedding External Binaries guide to see how.
在 v2 中,“process-command-api” 功能标志已被移除。因此,运行外部二进制文件不再需要在 Tauri 配置中定义此功能。
🌐 The “process-command-api” features flag has been removed in v2. So running the external binaries does not require this feature to be defined in the Tauri config anymore.
🌐 Migrate Permissions
v1 白名单已经被重写为一个全新的权限系统,适用于单个插件,并且对于多窗口和远程 URL 支持有更高的可配置性。 这个新系统的工作原理类似于访问控制列表(ACL),你可以允许或拒绝命令,将权限分配给特定的一组窗口和域,并定义访问范围。
🌐 The v1 allowlist have been rewritten to a completely new system for permissions that works for individual plugins and is much more configurable for multiwindow and remote URL support. This new system works like an access control list (ACL) where you can allow or deny commands, allocate permissions to a specific set of windows and domains, and define access scopes.
要为你的应用启用权限,你必须在 src-tauri/capabilities 文件夹中创建功能文件,Tauri 会自动为你配置其他所有内容。
🌐 To enable permissions for your app, you must create capability files inside the src-tauri/capabilities folder, and Tauri will automatically configure everything else for you.
migrate CLI 命令会自动解析你的 v1 允许列表并生成相关的能力文件。
🌐 The migrate CLI command automatically parses your v1 allowlist and generates the associated capability file.
要了解有关权限和功能的更多信息,请参阅安全文档。
🌐 To learn more about permissions and capabilities, see the security documentation.
Tauri 中文网 - 粤ICP备13048890号
Nodejs.cn 旗下网站