Tauri2学习笔记

教程地址:https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from=333.788.player.switch\&vd_source=707ec8983cc32e6e065d5496a7f79ee6

官方指引:https://tauri.app/zh-cn/start/

目前Tauri2的教程视频不多,我按照Tauri1的教程来学习,转成Tauri2


一、Tauri2 安装

  1. 安装win系统依赖,Microsoft C++

https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/

  1. 若没有的,要安装WebView2

下载并安装"常青独立安装程序(Evergreen Bootstrapper)

https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/?form=MA13LH#download

  1. 安装Rust

https://www.rust-lang.org/zh-CN/tools/install

打开,选择1,进行默认安装

安装完成后,输入 rustc --version和cargo --version来验证

配置cargo环境变量

PATH里,加入%USERPROFILE%.cargo\bin

  1. 安装nodejs

https://nodejs.org/zh-cn

验证是否安装成功:

node -v

npm -v

nodejs环境变量配置

Path中输入nodejs的地址,比如C:\Program Files\nodejs\

  1. 安装Android,若要导出Android App的话
    下载Android Studio

https://developer.android.com/studio?hl=zh-cn

确保安装了以下内容

Android SDK Platform

Android SDK Platform-Tools

NDK (Side by side)

Android SDK Build-Tools

Android SDK Command-line Tools

配置 ANDROID_HOME 和 NDK_HOME 环境变量

Path中添加

%ANDROID_HOME%\platform-tools

%ANDROID_HOME%\tools

%ANDROID_HOME%\tools\bin

%NDK_HOME%

输入adb --version 验证


二、建立工程

  1. 在文件夹下,放入.npmrc文件,帮助镜像代理
bash 复制代码
registry=https://registry.npmmirror.com/
disturl=https://registry.npmmirror.com/-/binary/node
electron_mirror=https://npmmirror.com/mirrors/electron/
electron-builder-binaries_mirror=https://registry.npmmirror.com/-/binary/electron-builder-binaries/
  1. 进入cmd,输入
bash 复制代码
npm create tauri-app@latest
  1. 安装配置过程
  • 填写项目名,选择前端代码
  1. 下载完毕,用vscode打开
  • 拷贝.npmrc
  • 执行npm i 安装插件
  • 执行npm run tauri dev

三、工程介绍

  • 各目录的说明

    tauri-app/

    ├── src/ # 前端源代码(Vue/React/Svelte 等)

    ├── src-tauri/ # Tauri 后端(Rust 代码)

    ├── public/ # 静态资源(图片、字体等)

    ├── node_modules/ # 前端依赖

    ├── target/ # Rust 编译输出(自动生成)

    ├── dist/ # 前端构建输出(自动生成)

    ├── package.json # 前端项目配置

    ├── vite.config.js # Vite 配置

    └── index.html # 前端入口 HTML

  • tauri.conf.json,用于配置窗口信息


四、页面调用rust方法

https://tauri.app/zh-cn/develop/calling-rust/

  1. 调用rust函数
  • 前端:
javascript 复制代码
import { invoke } from "@tauri-apps/api/core"; //获取接口函数 invoke

// 通过异步的方式调用greet函数,并传递参数,参数以键值对传递
async function greet() {
  // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
  greetMsg.value = await invoke("greet", { name: name.value });
}
  • Rust端:
rust 复制代码
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_opener::init())
        .invoke_handler(tauri::generate_handler![greet]) // 绑定greet函数
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
  1. 同步的方式
  • 前端
javascript 复制代码
invoke('login', { user: 'tauri', password: '0j4rijw8=' })
  .then((message) => console.log(message))
  .catch((error) => console.error(error));
  • rust端
rust 复制代码
#[tauri::command]
fn login(user: String, password: String) -> Result<String, String> {
  if user == "tauri" && password == "tauri" {
    // resolve
    Ok("logged_in".to_string())
  } else {
    // reject
    Err("invalid credentials".to_string())
  }
}

五、事件系统(双工消息)

  1. 前端发送
  • 前端emit事件,是更简单的通讯方式,没有返回值;
javascript 复制代码
import { emit } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';

// emit(eventName, payload)
emit('file-selected', '/path/to/file'); //全局发送

const appWebview = getCurrentWebviewWindow();
appWebview.emit('route-changed', { url: window.location.href }); //指定窗口发送
  • 触发特定监听事件的emitTo发送
javascript 复制代码
import { emitTo } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';

// emitTo(webviewLabel, eventName, payload)
emitTo('settings', 'settings-update-requested', {
  key: 'notification',
  value: 'all',
});

const appWebview = getCurrentWebviewWindow();
appWebview.emitTo('editor', 'file-changed', {
  path: '/path/to/file',
  contents: 'file contents',
});
  1. Rust接收
  • 全局接收
rust 复制代码
use tauri::Manager;

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            // 监听全局事件
            app.listen_global("global-event", |event| {
                println!("Received global event: {:?}", event.payload());
                // 可解析数据(需 serde)
                if let Some(payload) = event.payload() {
                    println!("Parsed payload: {}", payload);
                }
            });
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("Failed to run Tauri");
}
  • 特定窗口接收
rust 复制代码
use tauri::Window;

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            // 获取目标窗口(假设标签为 "secondary")
            let secondary_window = app.get_window("secondary").unwrap();
            secondary_window.listen("window-specific-event", |event| {
                println!("Received window-specific event: {:?}", event.payload());
            });
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("Failed to run Tauri");
}

emit有全局发送与特定窗口发送,还有emitTo的写法

  1. rust端发送
  • 全局事件
rust 复制代码
use tauri::Manager;

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            // 发送全局事件(所有前端窗口都能接收)
            app.emit_all("rust-to-frontend", "Hello from Rust").unwrap();
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("Failed to run Tauri");
}
  • 定向窗口发送
rust 复制代码
use tauri::Window;

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            // 获取指定窗口(假设窗口标签为 "main")
            let main_window = app.get_window("main").unwrap();
            // 发送到特定窗口
            main_window.emit("rust-to-specific-window", "Data for main window").unwrap();
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("Failed to run Tauri");
}
  • 发送复杂数据
rust 复制代码
use serde::Serialize;

#[derive(Serialize)]
struct CustomData {
    message: String,
    count: i32,
}

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            let data = CustomData {
                message: "Dynamic data".into(),
                count: 42,
            };
            app.emit_all("structured-event", &data).unwrap();
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("Failed to run Tauri");
}
  1. 前端监听事件
  • 全局监听
javascript 复制代码
import { listen } from '@tauri-apps/api/event';
import { onMounted } from 'vue';

onMounted(() => {
  // 监听全局事件
  listen('rust-to-frontend', (event) => {
    console.log('Received:', event.payload); // 输出: "Hello from Rust"
  });
});
  • 定向窗口监听
javascript 复制代码
import { getCurrent } from '@tauri-apps/api/window';
import { onMounted } from 'vue';

const currentWindow = getCurrent();

onMounted(() => {
  // 监听当前窗口的事件
  currentWindow.listen('rust-to-specific-window', (event) => {
    console.log('Window-specific data:', event.payload);
  });
});
  • 监听Json数据
javascript 复制代码
import { listen } from '@tauri-apps/api/event';

listen('structured-event', (event) => {
  console.log('Message:', event.payload.message); // "Dynamic data"
  console.log('Count:', event.payload.count);    // 42
});

六、Http请求

使用http请求,需要先配置tarui.conf.json,把能访问的网址加入白名单

此举让软件安全性提高很多,对比electron,就很有优势


七、文件操作

  • tauri需要先配置tarui.conf.json,包括文件的操作权限和操作目录
  • 前端才能操作文件,但是前端没有绝对目录的操作能力;想操作绝对目录,需要用rust编写
  • 另外tarui要配置下资源目录,这样打包的时候,资源目录才会打包在一起
  • 通过引入
javascript 复制代码
import { readBinaryFile, BaseDirectory } from '@tauri-apps/api/fs';

实现文件的操作

在一代api里有相关资料,在二代的插件里也有相关资料

https://tauri.app/zh-cn/plugin/file-system/


八、本地文件的Url获取

  • 需要进行安全策略配置,在tauri.conf.json中,配置安全策略的头格式
  • 需要配置允许的目录
  • 前端写法
  • 获取assetUrl的正确路径
  • 最后把这个变量赋给img的src属性就可以了

九、dialog对话框

  • 这里调用的是系统的对话框,有5种
  • 需要在tauri.conf.json里配置api开放,教程里设置了全部开发
  • 前端
  • 选择文件夹

以上的一些API,可能需要进入到tauri1里面去看


十、自定义窗口的配置

https://tauri.app/zh-cn/learn/window-customization/

  • 上面的地址,可以在前端,通过css、html,模拟一个标题栏目

https://v1.tauri.app/v1/api/config#windowsconfig

  • 这个地址可以配置tauri.config.json来设置窗口的大小

十一、系统托盘

  • 通过配置,配置系统托盘

https://tauri.app/zh-cn/learn/system-tray/

  • 关于系统托盘的说明,制作托盘有Js前端定义,和Rust后端定义2种类型
  • 看我们的功能是在后端比较多,还是前端比较多

十二、开屏界面

https://tauri.app/zh-cn/learn/splashscreen/

  • 教程通过增加一个窗口,并把主窗口隐藏,在rust里写了隐藏开屏窗口和打开主窗口的函数,通过前端,调用此函数来实现
  • 窗口的html文件,放在public里面
  • 窗口可以通过label来得到

十三、多窗口

  • 可以通过前端,来新建,设置新窗口的各项属性
  • 也可以在tarui.conf.json里把窗口先定义好,通过前端显示此窗口
  • 教程提示,vue的路径使用,可能需要加#好

十四、导出

  • 运行npm run tauri build,过程中出现需要下载的文件
  • 教程里会让放在C:/用户.../AppData 下面
  • 另外一种方式是通过注册表
bash 复制代码
配置系统变量
TAURI_NSIS_DIR
D:\TauriSDK\NSIS

配置系统变量
变量名:WIX
变量值:解压目录的路径(例如:C:\wix)
同时,将解压目录中的bin文件夹添加到PATH环境变量中:
在系统变量中找到Path,点击编辑。
添加一个新的条目:%WIX%\bin(或者直接写绝对路径,如C:\wix\bin)