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 的潜力,构建出更加强大的桌面应用程序。

相关文章
|
2天前
|
Rust 前端开发 JavaScript
Tauri 开发实践 — Tauri 日志记录功能开发
本文介绍了如何为 Tauri 应用配置日志记录。Tauri 是一个利用 Web 技术构建桌面应用的框架。文章详细说明了如何在 Rust 和 JavaScript 代码中设置和集成日志记录,并控制日志输出。通过添加 `log` crate 和 Tauri 日志插件,可以轻松实现多平台日志记录,包括控制台输出、Webview 控制台和日志文件。文章还展示了如何调整日志级别以优化输出内容。配置完成后,日志记录功能将显著提升开发体验和程序稳定性。
11 1
Tauri 开发实践 — Tauri 日志记录功能开发
|
2天前
|
自然语言处理 JavaScript 前端开发
Tauri 开发实践 — Tauri 主题&多语言设置开发
本文首发于微信公众号「前端徐徐」,介绍了在 Tauri 应用中实现窗口主题设置与多语言支持的方法。主题设置包括静态和动态两种方式,前者在应用初始化时设定,后者允许运行时更改。文章详细描述了通过 tauri-plugin-theme 插件实现动态主题变更的过程,并提供了代码示例。对于多语言支持,文章介绍了使用 i18next 进行多语言文件初始化及切换的方法。最后,提供了完整的源码链接,帮助读者更好地理解和实践。
15 4
|
2天前
|
存储 Rust 前端开发
Tauri 开发实践 — Tauri 配置介绍
本文首发于微信公众号“前端徐徐”,主要讲解`package.json`、`Cargo.toml`及`tauri.conf.json`三个文件的配置。其中,`tauri.conf.json`最为复杂,涉及众多配置项。`package.json`用于配置前端依赖与脚本;`Cargo.toml`用于声明Rust应用依赖;`tauri.conf.json`则管理前端资源、API白名单等。这些配置对于Tauri应用的开发至关重要。
16 5
|
2天前
|
JSON 自然语言处理 数据格式
Tauri 开发实践 — Tauri 自定义多语言菜单开发
本文介绍了如何在 Tauri 应用中实现自定义菜单并支持多语言。首先,通过 `Translator` 类加载和解析多语言 JSON 文件,实现简单的翻译功能。接着,创建包含文件、编辑和窗口子菜单的基本菜单结构,并根据当前语言进行翻译。最后,在主函数中读取语言设置,创建菜单并处理菜单事件,确保应用的国际化和用户体验。源码可在 GitHub 上查看。
13 2
|
2天前
|
Rust 前端开发 JavaScript
Tauri 开发实践— Tauri 怎么样
Tauri 是一个用于构建高效、小型二进制文件的框架,适用于所有主流桌面及移动平台。开发人员可以利用任何可编译为 HTML、JavaScript 和 CSS 的前端框架构建应用,并借助 Rust、Swift 或 Kotlin 进行后端开发。Tauri 采用三层架构,包括 tauri-app、WRY(跨平台 Webview 库)和 TAO(跨平台窗口管理器)。相较于 Electron,Tauri 使用系统内置浏览器引擎执行 Web APP,具有更小的资源占用和更高性能。详情见:[Tauri 官网](https://tauri.app/)。
13 0
Tauri 开发实践— Tauri 怎么样
|
2天前
|
Rust 前端开发 关系型数据库
Tauri 开发实践 — Tauri 集成本地数据库
本文介绍了在 Tauri 框架中集成本地数据库的几种方案,包括直接绑定 SQLite、使用第三方数据库库和使用 tauri-plugin-sql-api 插件。最终选择了 tauri-plugin-sql-api,因为它集成简单、支持多种数据库类型,并且与 Tauri 框架深度整合,提升了开发效率和安全性。文章详细介绍了如何安装和使用该插件,以及如何编写核心代码实现数据库操作。
12 2
|
2天前
|
Rust 前端开发 iOS开发
Tauri 开发实践— Tauri 工程搭建
本文首发于微信公众号“前端徐徐”,介绍了在 macOS 环境下使用 Rust 和 Tauri 构建跨平台桌面应用的过程。首先需安装 Rust 及系统依赖,参考链接:[Rust 入门](https://www.rust-lang.org/zh-CN/learn/get-started) 和 [Tauri 前置条件](https://tauri.app/zh-cn/v1/guides/getting-started/prerequisites)。
13 0
Tauri 开发实践— Tauri 工程搭建
|
2月前
|
前端开发 JavaScript Android开发
React Native 快速入门简直太棒啦!构建跨平台移动应用的捷径,带你开启高效开发之旅!
【8月更文挑战第31天】React Native凭借其跨平台特性、丰富的生态系统及优异性能,成为移动应用开发的热门选择。它允许使用JavaScript和React语法编写一次代码即可在iOS和Android上运行,显著提升开发效率。此外,基于React框架的组件化开发模式使得代码更加易于维护与复用,加之活跃的社区支持与第三方库资源,加速了应用开发流程。尽管作为跨平台框架,React Native在性能上却不输原生应用,支持原生代码优化以实现高效渲染与功能定制。对于开发者而言,React Native简化了移动应用开发流程,是快速构建高质量应用的理想之选。
44 0
|
4月前
|
Rust 前端开发 JavaScript
Tauri框架:使用Rust构建轻量级桌面应用
Tauri是一个用Rust构建的开源框架,用于创建轻量、安全且高效的跨平台桌面应用,结合Rust与Web技术(HTML/CSS/JS)。它遵循最小权限原则,仅在必要时调用OS API。Tauri架构包括Rust后端、Web前端、Tauri API和包装器。通过`cargo tauri init`可创建新项目,Rust后端处理系统交互,前端负责UI,两者通过Tauri API通信。Tauri支持自定义API、集成前端框架、资源管理、自动更新、系统集成和安全配置。此外,Tauri拥有插件系统和丰富的扩展能力,提供调试和测试工具,并有性能优化建议。
270 4
|
5月前
|
开发框架 Android开发 开发者
构建未来:使用Flutter框架开发跨平台移动应用
【4月更文挑战第24天】 在移动应用的世界中,Android和iOS一直占据主导地位。然而,开发者经常面临一个难题:如何高效地为这两个平台构建和维护应用。传统的解决方案是分别为每个平台编写和维护独立的代码库,这不仅耗时且低效,还增加了开发成本。本文将深入探讨如何使用Google的Flutter框架来构建高性能、美观且能够在Android和iOS上无缝运行的跨平台移动应用。通过分析Flutter的架构、核心组件以及开发优势,我们将了解为何Flutter成为当今市场上最具潜力的跨平台解决方案。