前言

今天来说一说 Tauri 的多窗口。

Tauri 中的窗口分为静态窗口和动态窗口。

静态窗口

默认生成的 app 只有一个窗口,可以在 tauri.conf.json 中找到,如下所示

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "windows": [
    {
      "fullscreen": false,
      "resizable": true,
      "title": "tauri",
      "width": 800,
      "height": 600
    }
  ]
}

windows 是个数组,意味着可以创建多个窗口。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
  "tauri": {
    "windows": [
      {
        "label": "page1"
        "fullscreen": false,
        "resizable": true,
        "title": "tauri",
        "width": 800,
        "height": 600
      },
      {
        "label": "page2",
        "title": "Tauri",
        "url": "page2.html"
      }
    ]
  }
}

当有多个的时候,我们要指定 label ,指定之后可以通过 label 来定位到具体的窗口。

label 需要唯一,不能重复。

上面的属性只列了一部分,更详细的可以查看Configuration | Tauri Apps

动态窗口

动态窗口指的是在运行时创建的,通过 WindowBuilder 来创建

1
2
3
4
5
6
7
8
9
tauri::Builder::default()
  .setup(|app| {
    let tauri_window = tauri::WindowBuilder::new(
      app,
      "Tauri", /* the unique window label */
      tauri::WindowUrl::External("https://tauri.app/".parse().unwrap())
    ).build()?;
    Ok(())
  })

运行起来后就会有两个窗口,一个是默认的,另一个指向了 Tauri 官网。

除了使用 App 创建窗口外,还能使用 AppHandle 创建窗口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
tauri::Builder::default()
  .setup(|app| {
      let handle = app.handle();
      let local_window = tauri::WindowBuilder::new(
          &handle,
          "Home",
          tauri::WindowUrl::App("index.html".into())
      ).build()?;
      Ok(())
  });

或者

1
2
3
4
5
6
7
8
#[tauri::command]
async fn new_window(handle: tauri::AppHandle) {
    let docs_window = tauri::WindowBuilder::new(
        &handle,
        "Home",
        tauri::WindowUrl::App("index.html".into())
    ).build().unwrap();
}

JS 中创建窗口

上面说的都是使用 Rust 创建窗口,有时我们希望在 JS 中也能创建窗口,这时候就需要使用 WebViewWindow 了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { WebviewWindow } from '@tauri-apps/api/window'
const webview = new WebviewWindow('Home', {
  url: 'index.html',
})
webview.once('tauri://created', function () {
    console.log("success");
})
webview.once('tauri://error', function (e) {
    console.log("error:", e);
})

仅仅做上面的操作是不行的,会报错,告诉你没有权限

1
window > create' not in the allowlist (https://tauri.app/docs/api/config#tauri.allowlist)

虽然文档上没有写要怎么做,但是在错误里倒是给了一个提示,靠着经验猜了一下,发现可行,如下所示 tauri.conf.json

1
2
3
4
5
6
7
8
9
{
  "tauri": {
    "allowlist": {
      "window": {
        "create": true
      }
    }
  }
}

学了那么久的 Tauri ,发现了一个文档上没有的规律,凡是从 JS 中调用的某些 API 要权限的,在 Rust 中调用就不要权限。

运行时获取窗口

1
2
3
4
5
6
use tauri::Manager;
tauri::Builder::default()
  .setup(|app| {
    let main_window = app.get_window("main").unwrap();
    Ok(())
  })

或者

1
2
3
4
#[tauri::command]
fn get_window(handle: tauri::AppHandle) {
    let main = handle.get_window("main").unwrap();
}

又或者

1
2
3
4
#[tauri::command]
fn get_window(window: tauri::Window) {
    let main = handle.get_window("main").unwrap();
}

其它

作用 rust js
获取当前活动窗口 get_focused_window getCurrent
获取所有窗口 windows getAll

总结

今天说了如何创建静态窗口和动态窗口,以及窗口的其它操作。

参考

多窗口 | Tauri Apps Configuration | Tauri Apps