Tauri 的基本使用笔记

news2024/10/6 18:30:42

文章目录

  • 前言
  • 如何将 Tauri 集成到前端项目?
  • 进程间通信(命令)
    • const invoke = window.__TAURI__.invoke;
  • 进程间通信(事件)
    • 前端 ⇒ Rust
    • Rust ⇒ 前端
    • 我的疑问
  • 开发时的一些技巧
    • 用代码打开前端的开发者工具
    • 让 Tauri 不要监听文件
    • Rust 格式化输出
    • Rust 读写文件
    • Rust 推荐教程
  • 生成应用图标
    • Windows 重建图标缓存
  • 修改安装包的语言
    • 打包报错:Error You must change the bundle identifier in `tauri.conf.json > tauri > bundle > identifier`. The default value `com.tauri.dev` is not allowed as it must be unique across applications.
    • 两种打包方式的区别
    • 打包后的应用打开会弹出命令行窗口
  • 代码
    • 进程间通信


前言

记录一下 Tauri 的基本操作


如何将 Tauri 集成到前端项目?

我们先创建一个普通的前端项目,这里我用 Vite + Vue3 创建一个空项目

在这里插入图片描述

然后启动检查一下,没啥问题:

在这里插入图片描述

之后引入 Tauri 的脚手架,我们可以看一下官网的说明

 pnpm add -D @tauri-apps/cli

在这里插入图片描述
然后 pnpm tauri init ,通过脚手架 init 一些配置

在这里插入图片描述

导入之后可以看一下代码结构,新增了 src-tauri 文件夹!

在这里插入图片描述

然后 pnpm tauri dev 启动一下,可以看到我启动花了四分钟,真的是挺慢的了,不过还是启动了!!

在这里插入图片描述

这里插一嘴,如果卡 blocking 的话,稍微等一下吧,太久了就检查一下代理,然后重复上述步骤

在这里插入图片描述


进程间通信(命令)

前端如何调用 Rust 指令呢?

我们把前端精简一下,就剩一个组件,然后写一个按钮,用来触发命令

在这里插入图片描述

想要前端调用 Rust,还需要安装一个 @tauri-apps/api,具体可以看 官网:调用指令,安装完运行 tauri dev

在这里插入图片描述
我们就按照官网给的例子,写好 Rust 的代码

在这里插入图片描述
之后来测试一下

在这里插入图片描述

const invoke = window.TAURI.invoke;

这里的 invoke 也可以挂载到 window 上,只需要在 tauri.conf.json 中配置一下,默认是 false

在这里插入图片描述


进程间通信(事件)

官网上也有基于事件的进程间通信(非命令),不过我感觉命令的使用场景会多一些吧,更像是前后端通信

事件的话,感兴趣的话可以看看,这里简单使用一下

前端 ⇒ Rust

这里前端使用 emit() 传递,Rustapp.listen_global 接收

在这里插入图片描述

Rust ⇒ 前端

这里用了一下克隆

let callback_app_handle = app.app_handle().clone();

以及 move 关键字,如果不用move 的话会报错,这里问了一下 GPT 的回答:

在这里插入图片描述

还有 JSON 的转化,整体代码如下

在这里插入图片描述

整体的代码放到文章下面了

我的疑问

官网上给的例子,Rust 传递到前端没跑通,不知道是什么原因…点我跳转到官网的例子

我本来想的是 Rust 启动之后立马发消息给前端,但是实现不出来

给我的感觉像是时机的问题,可能是前端监听的晚了…用点击事件就能触发
在这里插入图片描述


开发时的一些技巧

用代码打开前端的开发者工具

每次启动的时候,前端控制台默认是不打开的,每次修改 Rust 之后,窗口都会重新启动,并且不会打开控制台,调试的话很麻烦

那么让代码帮我们打开控制台

在这里插入图片描述
在 setup 中添加这两句,拿到窗口,打开开发者工具

let window = app.get_window("main").unwrap();
window.open_devtools();

让 Tauri 不要监听文件

Rust 启动会监听 src-tauri 下的文件变化,如果有变化,就会重新编译,重启窗口,有时候并不希望这样

在这里插入图片描述

那我们可以在src-tauri 文件夹下新建 .taurignore 文件,然后输入 * 保存,这就代表所有文件的变化都不监听了

在这里插入图片描述

Rust 格式化输出

Rust 中如何像前端一样 console.log() 一些变量呢?

在这里插入图片描述

println!("{:?}", 变量);
println!("{:#?}", 变量);

Rust 读写文件

因为 Rust 的基础数据类型比较少,所以这里我用 String 来传递文件,就是先将文件转换成 Base64 ,然后传给 Rust 来处理。

在这里插入图片描述

可以看到Rust 中的变量自动帮我们解包了,并且还是小写加下划线的形式,为什么这么设计呢,不理解,看一下GPT怎么说的吧

在这里插入图片描述

没关系,反正会如何使用就行

我们拿到 base64 之后就可以写文件了

接着我们写一下 Rust,需要导入一些模块,可以看到下面的 base64 飘红了

cargo add

需要 cdsrc-tauri 里然后,用 cargo add base64 命令安装模块
在这里插入图片描述
之后再来运行一下

在这里插入图片描述
可以看到文件已经放到 src-tauri 目录下了

这就是一个简单的文件读写

<script setup>
const { invoke } = window.__TAURI__;
function sendFile() {
  const input = document.getElementById('input');
  const [file] = input.files;

  const reader = new FileReader();
  reader.onloadend = async (e) => {
    console.log(e.target.result);
    const rst = e.target.result;
    const base64 = rst.split('base64,')[1];
    await invoke('send_file', { fileContent: base64, fileName: file.name });
  };
  reader.readAsDataURL(file);
}
</script>

<template>
  <input type="file" id="input">
  <button @click="sendFile">发送文件</button>
</template>

// main.rs
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use tauri::Manager;
use base64::{engine::general_purpose, Engine as _};
use std::fs::File;
use std::io::Write;

#[tauri::command]
fn send_file(file_content: String, file_name: String) {
    println!("{:?}", file_content);
    println!("{:?}", file_name);

    let file_bytes = general_purpose::STANDARD.decode(file_content).unwrap();
    let mut file = File::create(file_name).expect("创建文件失败");
    file.write_all(&file_bytes).expect("写入文件失败");
}

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            let window = app.get_window("main").unwrap();
            window.open_devtools();
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![send_file])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Rust 推荐教程

b站杨哥的视频,教程比较干净,适合速学


生成应用图标

Tauri 可以通过命令来生成各种尺寸的图标

我们现在网上找一个尺寸比较大的,可以去 iconfont 上面找

然后放到项目根目录下,执行命令 pnpm tauri icon

在这里插入图片描述
修改后的图标可能不生效,有可能的原因有

  • 图标太小了
  • 存在缓存

Windows 重建图标缓存

把下面的代码复制到 txt 中,然后修改为 bat 执行文件,然后执行

rem 关闭Windows外壳程序explorer

taskkill /f /im explorer.exe

rem 清理系统图标缓存数据库

attrib -h -s -r "%userprofile%\AppData\Local\IconCache.db"

del /f "%userprofile%\AppData\Local\IconCache.db"

attrib /s /d -h -s -r "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\*"

del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_32.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_96.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_102.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_1024.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_idx.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_sr.db"

rem 清理 系统托盘记忆的图标

echo y|reg delete "HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v IconStreams
echo y|reg delete "HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v PastIconsStream

rem 重启Windows外壳程序explorer

start explorer

生效的截图如下:

在这里插入图片描述

修改安装包的语言

默认是英语, 安装包默认是是两种方式,WixNSIS

我们在 tauri.conf.json 中声明打包语言,注意:路径是 tauri.bundle.windowswindows 好几个位置都有,别找错了

在这里插入图片描述

 "wix": {
   "language": "zh-CN"
 },
 "nsis": {
   "languages": ["SimpChinese"],
   "displayLanguageSelector": true
 }

打包报错:Error You must change the bundle identifier in tauri.conf.json > tauri > bundle > identifier. The default value com.tauri.dev is not allowed as it must be unique across applications.

在这里插入图片描述

两种打包方式的区别

因为我做的工具需要文件处理,Wix 打包后的应用需要管理员权限才能拿到文件,所以我更倾向于 NSIS 的安装包

第一次打包会有些慢,等一等就好了

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

打包后的应用打开会弹出命令行窗口

这是官网的解释

在这里插入图片描述


代码

进程间通信

// Vue
<script setup>
import { ref, onMounted } from "vue";
import { emit, listen } from '@tauri-apps/api/event'

const greetMsg = ref("");
const name = ref("");

function greet() {
  emit("greet", { name: name.value });
}

onMounted(async () => {
  const unlisten = await listen('hello', (event) => {
    // event.payload 才是实际的结构体
    console.log(event)
    greetMsg.value = event.payload;
  });
})
</script>

<template>
  <div class="card">
    <input id="greet-input" v-model="name" placeholder="Enter a name..." />
    <button type="button" @click="greet()">Greet</button>
  </div>

  <p>{{ greetMsg }}</p>
</template>

// main.rs
use serde::{Deserialize, Serialize};
use tauri::Manager;

#[derive(Serialize, Deserialize, Debug)]
struct Greet {
    name: String,
}

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            let callback_app_handle = app.app_handle().clone();
            let _event_id = app.listen_global("greet", move |event| {
                let greet_msg: Greet = serde_json::from_str(&event.payload().unwrap()).unwrap();
                let msg = format!("Hello, {}! You've been greeted from Rust!", greet_msg.name);
                println!("{}", msg);
                let _ = &callback_app_handle.emit_all("hello", msg);
            });
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1438215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode 30天高效刷数据结构和算法 Day1 两数之和 —— 无序数组

两数之和 —— 无序数组 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现…

数据结构(C语言)代码实现(七)——一元多项式的表示与相加

目录 前言 参考资料格式 头文件LinkList.h LocateElem函数&#xff0c;定位查找 有序插入&#xff08;没测试&#xff09; 完整代码 头文件polynomial.h 测试函数&#xff08;主函数&#xff09; 测试结果 前言 寒假在家&#xff0c;有点学不下去&#xff0c;写文章的…

java中ArrayList类常用API

前言&#xff1a;在学习java的ArrayList类的时候&#xff0c;有很多的API需要了解&#xff0c;下面我将举出其中在新手学习时使用频率较大的几个API。 先大体看一下有哪几个&#xff1a;&#xff08;如图&#xff09; 目录 1.add&#xff08;&#xff09; 解释&#xff1a; …

CSS太极动态图

CSS太极动态图 1. 案例效果 我们今天学习用HTML和CSS实现动态的太极&#xff0c;看一下效果。 2. 分析思路 太极图是由两个旋转的圆组成&#xff0c;一个是黑圆&#xff0c;一个是白圆。实现现原理是使用CSS的动画和渐变背景属性。 首先&#xff0c;为所有元素设置默认值为0…

非精线搜索步长规则Armijo规则Goldstein规则Wolfe规则

文章目录 非精确线搜索步长规则Armijo规则Goldstein规则Wolfe规则C示例代码参考链接 非精确线搜索步长规则 在数值优化中&#xff0c;线搜索是一种寻找合适步长的策略&#xff0c;以确保在目标函数上获得足够的下降。如最速下降法&#xff0c;拟牛顿法这些常用的优化算法等&am…

异步解耦之RabbitMQ(三)_RabbitMQ队列

异步解耦之RabbitMQ(一) 异步解耦之RabbitMQ(二)_RabbitMQ架构及交换机 RabbitMQ提供了许多功能和选项&#xff0c;包括队列和消息的 TTL&#xff08;Time-To-Live&#xff0c;生存时间&#xff09;。在本篇博客中&#xff0c;我们将深入探讨 RabbitMQ 队列和消息的 TTL&…

Laykefu客服系统 任意文件上传

【产品介绍】 Laykefu 是一款基于workermangatawayworkerthinkphp5搭建的全功能webim客服系统&#xff0c;旨在帮助企业有效管理和提供优质的客户服务 【漏洞介绍】 Laykefu客服系统/admin/users/upavatar.html接口处存在文件上传漏洞 【资产测绘Query】 fofa语法&#xf…

IS-IS weight影响路由加表

拓扑图 配置 nexthop weight影响路由加入路由表 weight默认为255&#xff0c;取值1~255&#xff0c;值越小越优先 sysname R1 # isis 1is-level level-1cost-style widenetwork-entity 49.1234.0000.0000.0001.00log-peer-change topology # interface GigabitEthernet0/0/0…

freeRTOS总结(十四)任务通知

1、任务通知 任务通知&#xff1a; 用来通知任务的&#xff0c;任务控制块中的结构体成员变量ulNotifiedValue就是这个通知值 使用队列、信号量、事件标志组时都需另外创建一个结构体&#xff0c;通过中间的结构体进行间接通信&#xff01; 使用任务通知时&#xff0c;任务结…

C#上位机与三菱PLC的通信02--MC协议介绍

1、协议介绍 三菱 PLC MC 协议是一种用于三菱 PLC 与上位机之间进行数据通信的协议&#xff0c;也称为 Mitsubishi Communication Protocol。该协议支持串口、以太网等多种通讯方式&#xff0c;可实现实时数据的采集和交换。三菱PLC的MC协议是一种数据通信协议&#xff0c;它用…

跟着pink老师前端入门教程-day21

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

【Mybatis】从0学习Mybatis(1)

前言 本篇文章是从0学习Mybatis的第一篇文章&#xff0c;由于篇幅太长CSDN会限流&#xff0c;因此我打算分开三期来写&#xff0c;这是第一期&#xff01; 1.怎么理解MyBatis是一个框架&#xff1f; 温馨提示&#xff1a;接下来的你不一定能看懂&#xff01; MyBatis是一个J…

1Panel面板如何安装并结合内网穿透实现远程访问本地管理界面

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

照片去除水印的方法有哪些?这些方法快收藏保存起来

当你踏破铁鞋无觅处&#xff0c;在茫茫网海中寻得心仪的头像或壁纸美图&#xff0c;却发现那完美的画面上赫然带着平台水印&#xff0c;是不是感觉如鲠在喉&#xff1f;但又不知道照片去除水印的方法有哪些而束手无策&#xff1f;别担心&#xff0c;今天我就为你带来几招去水印…

Instagram SEO如何优化?10个技巧

Instagram SEO 是优化 Instagram 内容以使其在平台搜索结果中被发现的做法。如果你希望你可以更快的让你的Ins获得流量&#xff0c;做好SEO就成功了一半。Instagram 搜索结果包括相关内容、帐户、音频、主题标签和地点&#xff0c;下面为你总结10个策略技巧&#xff01; 一、In…

Windows 安装 MySQL 最新最简教程

Windows 安装 MySQL 最新最简教程 官网地址 https://dev.mysql.com/downloads/mysql/下载 MySQL zip 文件 配置 MySQL1、解压文件 2、进入 bin 目录 搜索栏输入 cmd 回车进入命令行 C:\Users\zhong\Desktop\MySQL\mysql-8.3.0-winx64\mysql-8.3.0-winx64\bin 注意这里是你自己…

windows下ngnix自启动(借助工具winSw)

文章目录 前言一、winsw工具二、使用步骤下载 windsw-x86.exe同级目录创建一个xml文件以管理员权限打开cmd 运行设置自启动 总结 前言 在windows下安装nginx后&#xff0c;不想每次都手动启动。本文记录下windows下ngnix自启动&#xff08;借助工具winSw&#xff09;的操作流程…

Pandas数据处理技能大全:索引标签修改函数全攻略【第65篇—python:索引标签】

文章目录 Pandas数据处理技能大全&#xff1a;索引标签修改函数全攻略1. rename函数参数说明&#xff1a;代码实例&#xff1a; 2. set_index函数参数说明&#xff1a;代码实例&#xff1a; 3. reset_index函数参数说明&#xff1a;代码实例&#xff1a; 4. reindex函数参数说明…

Spring Web Body 转化常见错误

在 Spring 中&#xff0c;对于 Body 的处理很多是借助第三方编解码器来完成的。例如常见的 JSON 解析&#xff0c;Spring 都是借助于 Jackson、Gson 等常见工具来完成。所以在 Body 处理中&#xff0c;我们遇到的很多错误都是第三方工具使用中的一些问题。 真正对于 Spring 而…

学习Spring的第十六天

AOP底层两种生成Proxy的方式 我来解释这两种方式 1 目标类有接口 , 调用JDK的动态代理实现 2 目标类没有接口 , 用Cglib实现 , 即生成目标类的子类 , 来实现动态代理 , 所以要求目标类不能时final修饰的 . (若有接口 , 也可用Cglib方式实现 , 需要手动配置<aop: config pr…