首页 / Tauri 2 入门教程 / 集成 Vue 3

Tauri 2 入门教程

集成 Vue 3

本教程共 48 篇 · 第 16 篇 · 更新于 2026-08-09 · 约 7 分钟阅读

TauriVue3Vite前端集成

本节目标:学完能用官方脚手架生成一个 Vue 3 模板,理解 Vite 开发端口为什么要「锁死」,并能在 Vue 组件里正确调用 Tauri 的 invoke

当界面变复杂,原生三件套就显得吃力了。Vue 3 是目前最流行的渐进式前端框架之一,组件化、响应式数据用起来很顺手。好消息是:Tauri 和 Vue 的集成,本质上和上一章的原生前端没有区别——底层依旧是 WebView 加载页面、依旧靠 invoke 调 Rust。变了的只是前端代码的组织方式。本章只讲「集成机制」和「调用方式」,不带着做一个完整产品。

用脚手架生成 Vue 3 模板

Tauri 官方提供了一个交互式脚手架 create-tauri-app,它能帮你把前端和 Rust 两端一次性搭好,并内置了 Vue 3 模板。运行命令(版本以官方最新为准):

npm create tauri-app@latest

命令会问你几个问题:项目名、前端包管理器,以及最关键的——「选哪个前端模板」。在列表里选 Vue(TypeScript)Vue(JavaScript) 即可(带 TypeScript 的模板类型提示更好,推荐新手选它)。脚手架会自动做三件事:创建 src/ 作为 Vue 前端、创建 src-tauri/ 作为 Rust 后端、并装好 @tauri-apps/api@tauri-apps/cli 这两个包。

生成完毕后,目录结构大致是:

my-vue-app/
├── src/                 # Vue 前端源码
│   ├── App.vue          # 根组件
│   ├── main.ts          # 入口,挂载 Vue 应用
│   └── vite.config.ts   # Vite 配置
├── src-tauri/           # Rust 后端
│   ├── tauri.conf.json
│   └── src/lib.rs
└── package.json

你平时写界面都在 src/ 里,Rust 相关的事都在 src-tauri/ 里,两者通过配置和 IPC 连起来。启动开发用 npm run tauri dev,构建发布用 npm run tauri build

关键配置:锁死 Vite 端口

Vue 模板默认用 Vite 做开发服务器和打包工具。这里有个集成时的「必设点」:Tauri 在开发模式下要靠一个固定的网址(devUrl)找到你的前端,而 Vite 默认端口是「占到哪个算哪个」,还可能因为端口被占用自动换到 5174、5175。一旦端口飘了,Tauri 就接不上了。

解决办法是在 src/vite.config.ts 里把端口固定,并开启 strictPort(端口被占用就直接报错,而不是换端口):

// src/vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  clearScreen: false,
  server: {
    port: 5173,
    strictPort: true,
  },
});

对应的,tauri.conf.json 里的 build 配置要和这个端口对齐:

{
  "build": {
    "beforeDevCommand": "npm run dev",
    "beforeBuildCommand": "npm run build",
    "devUrl": "http://localhost:5173",
    "frontendDist": "../dist"
  }
}
Tip

clearScreen: false 是 Vue 模板的常见写法,它能防止 Vite 清屏,让 Tauri 的 Rust 编译日志和 Vite 的日志互不覆盖,调试时看得更清楚。它不影响功能,但建议保留。

在 Vue 组件里调用 Tauri API

集成机制讲完,剩下的就是「在 Vue 里怎么写那句 invoke」。答案和原生前端完全一样:从 @tauri-apps/api/core 引入 invoke。区别只是它现在写在 Vue 的 <script setup> 里。

<!-- src/App.vue -->
<script setup lang="ts">
import { ref } from 'vue';
import { invoke } from '@tauri-apps/api/core';

const name = ref('');
const reply = ref('');

async function greet() {
  // 调用 Rust 端的 greet 命令,参数用对象传
  reply.value = await invoke('greet', { name: name.value });
}
</script>

<template>
  <h1>Vue 3 + Tauri</h1>
  <input v-model="name" placeholder="输入你的名字" />
  <button @click="greet">打招呼</button>
  <p>{{ reply }}</p>
</template>

后端 src-tauri/src/lib.rs 里,greet 命令的定义和前面章节一致:

#[tauri::command]
fn greet(name: String) -> String {
    format!("你好,{}!来自 Rust 的问候。", name)
}

invoke 返回的是 Promise,所以在 Vue 的 async 函数里用 await 取值,再赋给 ref 驱动的响应式变量,界面就自动更新了。这就是 Vue 响应式 + Tauri 原生能力的标准配合方式。

Note

别忘了第 14 章提过的安全模型:这个 greet 命令需要在 src-tauri/capabilities/ 的能力文件里被授权,前端才能调得通。脚手架生成的 Vue 模板已经把默认命令和 core:default 权限配好了,你新增命令时记得补上权限,否则会收到权限错误。

不止 invoke:其它 API 模块

@tauri-apps/api 不止有 core。在 Vue 组件里,你同样可以按模块引入其它能力,比如操作当前窗口:

import { getCurrentWindow } from '@tauri-apps/api/window';

// 隐藏当前窗口
await getCurrentWindow().hide();

再比如收发事件(对应第 14 章的「事件」通道):

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

await listen('progress', (event) => {
  console.log(event.payload);
});

这些 API 的引入方式和 invoke 一模一样,都是标准 ES 模块导入,在 <script setup> 里直接 import 即可。需要注意:部分能力(如文件系统、进程、对话框)属于独立插件,除了 import,还要在 Rust 端 .plugin(...) 注册、并在能力文件里授权——这属于插件章节的内容,这里先知道「API 按模块引入」这个统一规律即可。

小结

Vue 3 与 Tauri 的集成可以浓缩成三句话:用 create-tauri-app 选 Vue 模板一键生成;在 vite.config.ts 里把端口 strictPort 锁死,并和 tauri.conf.jsondevUrl 对齐;在 Vue 组件里 import { invoke } from '@tauri-apps/api/core' 调用 Rust。其余所有「原生能力」,都只是换个文件、换个模块名去 import,底层机制始终不变。

至此,你已经走完了从「概念」到「能构建一个安装包、理解前后端如何说话、并接入两种前端」的完整基础链路。后续章节会继续深入窗口、托盘、插件、安全等主题。