Tauri 开发实践 — Tauri 原生能力

简介: 本文介绍了如何使用 Tauri 框架构建桌面应用,并详细解释了 Tauri 提供的原生能力,包括文件系统访问、系统托盘、本地消息通知等。文章通过一个具体的文件下载示例展示了如何配置 Tauri 来使用文件系统相关的原生能力,并提供了完整的代码实现。最后,文章还提供了 Github 源码链接,方便读者进一步学习和参考。

本文首发微信公众号:前端徐徐。

原生能力简介

Tauri 是一个用于构建安全的小型桌面应用程序的框架,它结合了 Web 前端和系统后端技术。Tauri 提供了一些原生能力,让您的 Web 应用程序能够访问本地系统资源和 API,主要包括以下几个方面:

  1. 文件系统访问 Tauri 允许你的 Web 应用程序读取、写入和监视本地文件系统中的文件和目录。这对于处理用户文档、保存应用程序数据等场景非常有用。
  2. 系统托盘 Tauri 支持在系统托盘区显示应用程序图标,并提供自定义的上下文菜单,让您可以构建类似于本机桌面应用程序的用户体验。
  3. 本地消息通知 您可以使用 Tauri 在桌面系统上显示本地通知,让用户获得关于应用程序状态或重要事件的反馈。
  4. 剪贴板访问 Tauri 允许您读取和写入系统剪贴板中的文本和图像数据。
  5. 对话框和文件选择器 使用 Tauri,您可以在应用程序中调用本地对话框,如打开文件、保存文件和显示消息框等,提高与用户的交互体验。
  6. 命令行参数 Tauri 使您能够访问用于启动应用程序的命令行参数。
  7. 全局捷径 您可以注册全局键盘快捷键,以便在应用程序运行时响应特定的键盘输入。
  8. 系统信息 Tauri 提供对系统信息的访问,包括 CPU、内存、网络等,允许您构建跨平台的系统监视工具。
  9. 更新检查 使用 Tauri,您可以检查应用程序的更新并提示用户进行更新。

通过利用这些原生能力,您可以构建功能强大且与本地桌面应用程序体验无缝集成的 Web 应用程序。Tauri 的目标是最大限度地减少 Web 和本机之间的鸿沟,同时保持了 Web 开发的高效性和可移植性。

我们这里以一个文件系统访问的场景来实现一下相应的能力,这里会涉及到一些配置以及Tauri的API的基本使用。

实战应用场景

在实现Tauri文件存储相关的功能之前,需要把相应的页面完成。大概效果如下,一个切割图片的工具,可上传图片,然后下载切割的图片,在这个场景里就会涉及到原生能力的调用,主要是文件相关的原生能力。

在这个场景中,我们常规的在浏览器的下载模式和方法是这样的。利用了浏览器提供的 <a> 元素的 download 和 href 属性,创建了一个临时的链接,并触发了点击事件,从而实现了文件下载的功能。它可以下载来自 URL 或者 Blob 对象的文件。

const downloadSlice = (sliceData: any, fileName: string) => {
    const link = document.createElement("a");
    link.download = fileName;
    link.href = sliceData;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
};

但是在Tauri中我们就不能这样做了,我们需要使用 Tauri的原生能力,主要是这三个模块:path模块,dialog模块,fs模块。path模块获取文件路径,dialog模块让用户选择文件对话框,fs模块存储文件。因为Tauri在使用相应的模块的时候是需要配置相应的权限的,否则无法在代码中使用相关方法,下面就具体讲解一下如何在Tauri实现文件下载的功能。

Tauri实现文件下载

修改配置

上面已经提到了,在Tauri中使用相应的原生模块的时候是需要配置相应的权限的,下面我们就来配置一下相关的权限,然后讲解一下相关的配置项。

首先是path的配置

名称

类型

默认值

描述

all

boolean

false

使用此标志启用所有路径 API 功能。

所以如果要启用路径API的话,需要设置其为true

"path": {
  "all": true
}

然后再是dialog的配置

名称

类型

默认值

描述

all

boolean

false

使用此标志启用所有对话框 API 功能。

open

boolean

false

允许 API 打开对话框窗口来选择文件。

save

boolean

false

允许 API 打开一个对话框窗口来选择保存文件的位置。

message

boolean

false

允许 API 显示消息对话框窗口。

ask

boolean

false

允许 API 显示带有是/否按钮的对话框窗口。

confirm

boolean

false

允许 API 显示带有“确定”/“取消”按钮的对话框窗口。

直接全部设置为true,感觉每个都需要

"dialog": {
    "all": true,
    "ask": true,
    "confirm": true,
    "message": true,
    "open": true,
    "save": true
}

最后是file的配置

名称

类型

默认值

描述

scope

FsAllowlistScope

[]

文件系统 API 的访问范围。

all

boolean

false

使用此标志启用所有文件系统 API 功能。

readFile

boolean

false

从本地文件系统读取文件。

writeFile

boolean

false

将文件写入本地文件系统。

readDir

boolean

false

从本地文件系统读取目录。

copyFile

boolean

false

从本地文件系统复制文件。

createDir

boolean

false

从本地文件系统创建目录。

removeDir

boolean

false

从本地文件删除目录。

removeFile

boolean

false

删除文件

renameFile

boolean

false

重命名文件

exists

boolean

false

检测是否存在文件

我们直接设置如下

"fs":{
  "all":true,
  "scope": ["**"] // 代表所有文件都可以访问
}

到这里,我们前期的配置就完成了,可以用tauri 实现文件下载了。

下载实现

我们因为要实现浏览器环境和tauri环境的下载,所以呢我们需要区分环境,区分环境可以使用

if (window.__TAURI__){
  // tauri环境
} else {
  // 浏览器环境
}

另外我们的应用场景是下载多张切割图片,所以需要做ZIP打包压缩处理。

整体思路如下

具体代码如下

import { writeBinaryFile } from '@tauri-apps/api/fs';
import { path, dialog } from '@tauri-apps/api';
import JSZip from 'jszip';
import dayJS from 'dayjs';
import { FileBase64List } from '@/type';
// 单个文件下载
export const downloadFileBase64 = async (data: any, fileName: string) => {
  if (window.__TAURI__){
    const binaryString = atob(data.split(',')[1]);
    const len = binaryString.length;
    const bytes = new Uint8Array(len);
    for (let i = 0; i < len; i++) {
      bytes[i] = binaryString.charCodeAt(i);
    }
    try {
      const basePath = await path.downloadDir();
      let selPath:any = await dialog.save({
        defaultPath: basePath,
      });
      selPath = selPath.replace(/Untitled$/, '');
      writeBinaryFile({ contents: bytes, path: `${selPath}${fileName}` });
    } catch (error) {
      console.error(error);
    }
  } else {
    const link = document.createElement("a");
    link.download = fileName;
    link.href = data;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
}
// tauri批量打包ZIP下载
export const downloadBase64FileWithZip =async (data:FileBase64List,callback:Function) => {
  const zip = new JSZip();
  data.forEach(item => {
    zip.file(item.name, item.data.replace(/^data:image\/(png|jpg);base64,/, ""), { base64: true });
  });
  const date = dayJS().format('YYYYMMDDHHmmss');
  const basePath = await path.downloadDir();
  let selPath:any = await dialog.save({
    defaultPath: basePath,
  });
  selPath = selPath.replace(/Untitled$/, '');
  zip.generateAsync({ type: 'blob' }).then((content) => {
    let file = new FileReader();
    file.readAsArrayBuffer(content);
    file.onload = function (e:any) {
      let fileU8A = new Uint8Array(e.target.result);
      writeBinaryFile({ contents: fileU8A, path: `${selPath}IMG_${date}.zip` });
      callback();
    };
  });
}
// 多个base64文件下载
export const downloadFileBase64List = async (data:FileBase64List,callback:Function) => {
  if (window.__TAURI__){
    downloadBase64FileWithZip(data,callback)
  } else {
    data.forEach(item => {
      downloadFileBase64(item.data, item.name)
    })
  }
}

源码链接

点击查看Github源码

总结

经过上面的步骤,我们基本上已经了解了 Tauri 原生能力的相关知识,并在一个实际案例中实现了利用这些能力实现文件下载的操作,掌握了整个原生能力对接的流程。不过,Tauri 原生能力的范围有一定限制,如果需要实现一些更加强大和复杂的功能,我们还需要使用到 Tauri 的进程通信机制以及原生能力扩展功能。在后续的章节中,我们将通过实例一步步带你了解这些更高级的特性,让你能够充分发挥 Tauri 的潜力,构建出更加强大的桌面应用程序。

相关文章
|
1天前
|
自然语言处理 JavaScript 前端开发
Tauri 开发实践 — Tauri 主题&多语言设置开发
本文首发于微信公众号「前端徐徐」,介绍了在 Tauri 应用中实现窗口主题设置与多语言支持的方法。主题设置包括静态和动态两种方式,前者在应用初始化时设定,后者允许运行时更改。文章详细描述了通过 tauri-plugin-theme 插件实现动态主题变更的过程,并提供了代码示例。对于多语言支持,文章介绍了使用 i18next 进行多语言文件初始化及切换的方法。最后,提供了完整的源码链接,帮助读者更好地理解和实践。
14 4
|
1月前
|
存储
CCF推荐A类会议和期刊总结:计算机体系结构/并行与分布计算/存储系统领域
中国计算机学会(CCF)2022年版推荐目录涵盖了计算机体系结构、并行与分布计算、存储系统领域的多个A类会议和期刊。本文汇总了这些顶级资源的全称、出版社、dblp网址及领域。包括《ACM计算机系统汇刊》、《ACM存储汇刊》等期刊,以及ACM PPoPP、USENIX FAST等会议,为研究人员提供了重要学术参考。
CCF推荐A类会议和期刊总结:计算机体系结构/并行与分布计算/存储系统领域
|
5天前
|
测试技术
软件测试区分:条件组合覆盖、语句覆盖、判定覆盖、条件覆盖、路径覆盖
本文解释了软件测试中的不同覆盖标准,包括语句覆盖、判定覆盖、条件覆盖、条件组合覆盖和路径覆盖,并讨论了每种覆盖标准的特点、优点和缺点。
121 62
|
1天前
|
Rust 前端开发 JavaScript
Tauri 开发实践 — Tauri 日志记录功能开发
本文介绍了如何为 Tauri 应用配置日志记录。Tauri 是一个利用 Web 技术构建桌面应用的框架。文章详细说明了如何在 Rust 和 JavaScript 代码中设置和集成日志记录,并控制日志输出。通过添加 `log` crate 和 Tauri 日志插件,可以轻松实现多平台日志记录,包括控制台输出、Webview 控制台和日志文件。文章还展示了如何调整日志级别以优化输出内容。配置完成后,日志记录功能将显著提升开发体验和程序稳定性。
10 1
Tauri 开发实践 — Tauri 日志记录功能开发
|
1天前
|
JSON 自然语言处理 数据格式
Tauri 开发实践 — Tauri 自定义多语言菜单开发
本文介绍了如何在 Tauri 应用中实现自定义菜单并支持多语言。首先,通过 `Translator` 类加载和解析多语言 JSON 文件,实现简单的翻译功能。接着,创建包含文件、编辑和窗口子菜单的基本菜单结构,并根据当前语言进行翻译。最后,在主函数中读取语言设置,创建菜单并处理菜单事件,确保应用的国际化和用户体验。源码可在 GitHub 上查看。
9 2
|
10天前
|
缓存 测试技术 API
构建高效后端API:实践与哲学
【9月更文挑战第36天】在数字世界的浪潮中,后端API成为了连接用户、数据和业务逻辑的桥梁。本文将深入探讨如何构建一个既高效又灵活的后端API,从设计理念到实际代码实现,带你一探究竟。我们将通过具体示例,展示如何在保证性能的同时,也不失安全性和可维护性。
|
10天前
|
SQL 安全 网络安全
云计算与网络安全:技术融合下的信息安全挑战与应对
【9月更文挑战第36天】在数字化浪潮的推动下,云计算已成为企业和个人不可或缺的技术支撑。然而,随着云服务的广泛应用,网络安全问题亦日益凸显。本文深入探讨了云计算环境下的网络安全挑战,并提出了相应的安全策略和技术解决方案。通过分析云服务的安全架构、网络攻击类型以及防御机制,旨在为读者提供一套完整的云计算网络安全指南。
|
安全 网络协议
最新可靠好用的DNS服务器地址汇总
如果修改DNS服务器地址就可以访问google等服务,你还等什么?使用免费DNS解析服务除了去掉了运营商的各种广告,还有个最大的好处就是不会重定向或者过滤用户所访问的地址,这样就防止了很多网站被电信、网通劫持,有利于提供访问一些国外网站的成功率 如googlecode,网友应该养成不使用默认DNS的习惯,笔者汇总了常用可靠的DNS服务器地址。
14676 0
|
5天前
|
数据可视化 JavaScript 图形学
Threejs实现音乐节奏表演
这篇文章详细介绍了如何使用Three.js结合音频频谱分析来创建一个随着音乐节奏变化的3D视觉表演,提供了实现音乐可视化效果的具体步骤和代码示例。
96 60
Threejs实现音乐节奏表演
|
21天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。