🎉使用Tauri+vite+koa2+mysql开发了一款待办效率应用

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
应用实时监控服务ARMS - 应用监控,每月50GB免费额度
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 这是一个基于tauri+vite的应用,它采用了一些最新的前端技术,包括 Tauri、Vue3、Vite5、koa2 和 mysql。它提供了丰富的效率管理工具。

🎉使用Tauri+vite+koa2+mysql开发了一款待办效率应用


## 📝项目概述


这是一个基于tauri+vite的应用,它采用了一些最新的前端技术,包括 Tauri、Vue3、Vite5、koa2 和 mysql。它提供了丰富的效率管理工具。


应用地址:https://kestrel-task.cn


喜欢的可以试试哦,🙏🙏🙏


## 🏆项目预览


![](https://files.mdnice.com/user/1378/751284ec-d4ab-4f7d-be24-9ef68fcd6c7e.png)


![](https://files.mdnice.com/user/1378/865aa7fe-8bc8-4a80-8456-71621e6349fb.png)


![](https://files.mdnice.com/user/1378/1d5ee010-6b62-4194-8697-fe10da4b9aa3.png)


![](https://files.mdnice.com/user/1378/429f947d-afe6-48e4-8f2e-77aaf80fb0f4.png)


![](https://files.mdnice.com/user/1378/377a053c-43e0-4d08-b8a3-308bade71ab4.png)


![](https://files.mdnice.com/user/1378/dfdd94ed-6ecc-4806-8c78-eb998bb15e03.png)


![](https://files.mdnice.com/user/1378/20b13b32-ff27-48db-9c9c-5ff4ee4525be.png)


![](https://files.mdnice.com/user/1378/bb8bc480-6cca-41dc-9782-4cc49d722f14.png)


![](https://files.mdnice.com/user/1378/7817598e-7213-4b2c-91ef-51c01079e218.png)


## 💻技术栈

- **Tauri**: Tauri是一个用于构建现代桌面应用程序的工具,结合了Rust、Vue.js和Web技术,提供了强大的跨平台能力。

- **Vue3**: Vue3是流行的JavaScript框架Vue.js的最新版本,具有更好的性能、更好的TypeScript支持和更多的特性。

- **Vite5**: Vite是一个现代化的构建工具,Vite5是其最新版本,具有快速的冷启动、热模块替换和原生ES模块支持。

- **Koa2**: Koa2是一个基于Node.js的轻量级Web框架,使用异步函数处理中间件,提供了简洁而强大的Web开发体验。

- **MySQL**: MySQL是一个流行的关系型数据库管理系统,具有高性能、可靠性和广泛的应用领域,适用于各种规模的应用程序。


主要包括的功能点实现


## 🔔图标生成

在项目根目录,放上图片为 app-icon.png的图片

然后执行。就能看到图标已经生成了。

```json

npm run tauri icon

```


## 📢配置应用系统托盘

### 新建tray.rs,编写托盘事件。内容如下。

```rust

use tauri::{

   AppHandle, CustomMenuItem, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem

};

use tauri::Manager;


// 托盘菜单

pub fn menu() -> SystemTray {

   let quit = CustomMenuItem::new("quit".to_string(), "退出");

   let show = CustomMenuItem::new("show".to_string(), "显示");

   let hide = CustomMenuItem::new("hide".to_string(), "隐藏");

   let tray_menu = SystemTrayMenu::new()

       .add_native_item(SystemTrayMenuItem::Separator)

       .add_item(hide)

       .add_item(show)

       .add_native_item(SystemTrayMenuItem::Separator)

       .add_item(quit);


   SystemTray::new().with_menu(tray_menu)

}


// 托盘事件

pub fn handler(app: &AppHandle, event: SystemTrayEvent) {

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

   match event {

       SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {

           "quit" => {

               std::process::exit(0);

           }

           "show" => {

               window.show().unwrap();

           }

           "hide" => {

               window.hide().unwrap();

           }

           _ => {}

       },

       _ => {}

   }

}


```


### 在main.rs中使用

```rust

use std::{thread,time};

mod tray;


fn main() {

   let context = tauri::generate_context!();

   tauri::Builder::default()

       // .menu(tauri::Menu::os_default(&context.package_info().name)) //配置界面菜单

       .system_tray(tray::menu()) // ✅ 将 `tauri.conf.json` 上配置的图标添加到系统托盘

       .on_system_tray_event(tray::handler) // ✅ 注册系统托盘事件处理程序

       .invoke_handler(tauri::generate_handler![my_custom_command, init_process,close_splashscreen])

       .run(context)

       .expect("error while running tauri application");

}

```



## 🎛️ 接口封装请求

Tauri 是一个框架,它允许开发者使用 Rust 语言来构建轻量级的桌面应用程序,Tauri 提供了一套 API,其中包括了用于处理 HTTP 请求的 http 模块。

tauri.conf.json 文件中进行配置:

```json

{

 "tauri": {

   "allowlist": {

     "http": {

       "all": true,

       "request": true,

       "scope":[

         "http://**",

         "https://**"

       ]

     }

   }

 }

}

```

## 🎵基于API的封装

```js

// http.js


import { fetch, ResponseType, Body } from '@tauri-apps/api/http'


// https://tauri.app/zh-cn/v1/api/js/http#fetch

export const http = (opts = {}) => {

 return new Promise((resolve, reject) => {

   const { url, method, query, data, headers, callback } = opts

   fetch(url, {

     method: method || 'GET',

     headers: {

       'content-type': 'application/json',

       ...headers,

     },

     responseType: ResponseType.JSON,

     timeout: 60000,

     query: query,

     body: Body.json({

       ...data,

     }),

   })

   .then((res) => {

     callback && callback(res)

     resolve(res)

   })

   .catch((e) => {

     reject(e)

   })

 })

}

```


## 😄获取版本号

这个函数通常用于获取应用程序的版本信息

```js

import { getVersion } from '@tauri-apps/api/app'

```

```js

onMounted(async () => {

 appVersion.value = await getVersion()

 getNewVersions()

})

```


## 🙂检查版本更新

这段代码的作用是导入 Tauri 中的更新模块 @tauri-apps/api/updater 中的 checkUpdate 和 installUpdate 函数。checkUpdate 用于检查是否有可用的应用程序更新,而 installUpdate 用于安装应用程序更新。


![](https://files.mdnice.com/user/1378/129e7a70-4520-4219-8629-81f934da8165.png)



```js

import { checkUpdate, installUpdate } from '@tauri-apps/api/updater'

```

```js

 checkUpdate().then(async (res) => {

   const { shouldUpdate, manifest } = res

   if (shouldUpdate) {

     confirm(`发现新版本:${manifest?.version},是否升级?`, { title: '版本更新', type: 'success' }).then(async (res) => {

       try {

         ElMessage.success({

           message: '正在下载更新...',

           duration: 3000,

         })

         installUpdate()

           .then(async (res) => {

             await relaunch()

           })

           .catch((e) => {

           })

       } catch (e) {

         ElMessage.error({

           message: '下载更新失败',

           description: e.toString() || '',

         })

       }

     })

   } else {

    await confirm(`当前版本,已经是最新版本`, { title: '检查更新', type: 'success' ,okLabel: '确定',cancelLabel: '取消'})

   }

 })

```

## 🙃窗口操作

窗口禁用最大化和最小化功能

```json

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

```

## 🥰禁用最大化和取消禁用


![](https://files.mdnice.com/user/1378/3383c156-d04b-41af-a4d4-fcf4fda9cfa2.png)


```js

appWindow.setMaximizable(true) //禁用

appWindow.setMaximizable(false) //取消禁用

```

```js

appWindow.setMinimized(true) //禁用

appWindow.setMinimized(false) //取消禁用

```

## 🥰消息提示

### Ask弹窗


![](https://files.mdnice.com/user/1378/a28ccf9c-bee8-4700-aff1-a5f2f3a346aa.png)


![](https://files.mdnice.com/user/1378/0abc8f2b-0afe-4e94-b30b-261a345621cd.png)



![](https://files.mdnice.com/user/1378/0abc8f2b-0afe-4e94-b30b-261a345621cd.png)


```js

import { ask } from '@tauri-apps/api/dialog';

const yes = await ask('确定更新该版本?', '发现新版本');

const yes2 = await ask('确定更新该版本?', { title: '发现新版本', type: 'warning' });

```

如果想要修改按钮的文本,可以使用,okLabel: '确定',cancelLabel: '取消'。


## 😊confirm弹窗


![](https://files.mdnice.com/user/1378/e40ca1d1-1524-4acf-9a47-01d8eaa93607.png)


![](https://files.mdnice.com/user/1378/1e55b937-0f50-4f73-9434-85dcc083450b.png)


```json

import { confirm } from '@tauri-apps/api/dialog';

const confirmed = await confirm('确定更新该版本?', '发现新版本');

const confirmed2 = await confirm('确定更新该版本?', { title: '发现新版本', type: 'warning',okLabel: '确定',cancelLabel: '取消' });

```


## 😝message提示框


![](https://files.mdnice.com/user/1378/fb895d27-9c31-4d02-ae42-13b45e3c4042.png)


![](https://files.mdnice.com/user/1378/b31d92fe-11ba-4971-b6eb-affca3ed7572.png)



```js

import { message } from '@tauri-apps/api/dialog';

await message('确定更新该版本', '发现新版本');

await message('确定更新该版本', { title: '发现新版本', type: 'error',okLabel: '确定',cancelLabel: '取消' });

```


## 🤗open 选择文件弹窗


![](https://files.mdnice.com/user/1378/3a394be3-4732-4664-90ba-3a71285a60cd.png)


```js

import { open } from '@tauri-apps/api/dialog';

// Open a selection dialog for image files

const selected = await open({

 multiple: true,

 filters: [{

   name: 'Image',

   extensions: ['png', 'jpeg']

 }]

});

if (Array.isArray(selected)) {

 // user selected multiple files

} else if (selected === null) {

 // user cancelled the selection

} else {

 // user selected a single file

}

```


## 😐save文件保存弹窗


![](https://files.mdnice.com/user/1378/a64b89b9-5b8c-475e-9531-ac4a9236520f.png)


```js

import { save } from '@tauri-apps/api/dialog';

const filePath = await save({

 filters: [{

   name: 'Image',

   extensions: ['png', 'jpeg']

 }]

});


```

## 😁splashscreen页设置

为什么要设置这个呢,因为`splashscreen` 页面通常用于在应用程序启动时显示一个启动画面或加载动画,以提供用户友好的界面体验。这个页面可以包含应用程序的标志、名称或其他相关信息,帮助用户确认应用程序正在加载。一旦应用程序加载完成,通常会自动关闭 `splashscreen` 页面并显示应用程序的主界面。


#### 🫠tauri.conf.json配置

```json

   "windows": [

     {

       "fullscreen": false,

       "resizable": true,

       "title": "微芒计划",

       "width": 1100,

       "height": 680,

       "minHeight": 600,

       "minWidth": 900,

       "visible": false

     },

     {

       "width": 800,

       "height": 500,

       "minHeight": 500,

       "minWidth": 800,

       "decorations": false,

       "url": "splashscreen.html",

       "label": "splashscreen",

       "resizable": true,

       "fullscreen": false

     }

   ]

```

splashscreen.html要放到public下面,为一个html文件,里面可以写开屏的图片动画或者界面。


### 🙂main.rs编写关闭splashscreen 页面的功能

```rust

// Create the command:

// This command must be async so that it doesn't run on the main thread.

#[tauri::command]

async fn close_splashscreen(window: Window) {

 // Close splashscreen

 window.get_window("splashscreen").expect("no window labeled 'splashscreen' found").close().unwrap();

 // Show main window

 window.get_window("main").expect("no window labeled 'main' found").show().unwrap();

}

```


### 🙃main入口提供给前端使用

```rust

fn main() {

   let context = tauri::generate_context!();

   tauri::Builder::default()

       // .menu(tauri::Menu::os_default(&context.package_info().name)) //配置界面菜单

       .system_tray(tray::menu()) // ✅ 将 `tauri.conf.json` 上配置的图标添加到系统托盘

       .on_system_tray_event(tray::handler) // ✅ 注册系统托盘事件处理程序

       .invoke_handler(tauri::generate_handler![my_custom_command, init_process,close_splashscreen])

       .run(context)

       .expect("error while running tauri application");

}

```


### 🙃在前端调用splashscreen页面

界面加载完成后,关掉

```rust

import { onMounted } from 'vue'

import { invoke } from '@tauri-apps/api/tauri'

onMounted(() => {

 // window.addEventListener('contextmenu', (e) => e.preventDefault(), false)

 document.addEventListener('DOMContentLoaded', () => {

   // This will wait for the window to load, but you could

   // run this function on whatever trigger you want

   setTimeout(() => {

     invoke('close_splashscreen')

   }, 1000)

 })

})

```


🎉结语

感兴趣的可以试试,有不清楚的问题,关于tauri开发方面的问题,也可以一起交流。欢迎加我:zhan_1337608148。一起成长,一起进步。















相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
14天前
|
关系型数据库 MySQL Serverless
Serverless 应用引擎产品使用合集之在SAE2.0上的应用如何访问云原生数据库PolarDB MySQL版集群
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
20天前
|
SQL Java 数据库连接
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
26 2
|
20天前
|
关系型数据库 MySQL 数据库
MySQL企业级开发重点之事物和索引
MySQL企业级开发重点之事物和索引
19 2
|
20天前
|
关系型数据库 MySQL 数据库
关系型数据库MySQL开发要点之多表查询2024详解
关系型数据库MySQL开发要点之多表查询2024详解
20 2
|
20天前
|
关系型数据库 MySQL 数据库
关系型数据库MySQL开发要点之多表设计案例详解代码实现
关系型数据库MySQL开发要点之多表设计案例详解代码实现
30 2
|
20天前
|
关系型数据库 MySQL 数据库
MySQL数据库开发之多表查询数据准备及案例实操
MySQL数据库开发之多表查询数据准备及案例实操
24 1
|
29天前
|
SQL 存储 关系型数据库
精通MySQL:从基础到高级应用与最佳实践
第一章:MySQL基础入门 1.1 MySQL概述 介绍MySQL的历史、发展、优势以及应用领域
|
17天前
|
关系型数据库 MySQL 程序员
老程序员分享:MySQL数据库企业级应用实践
老程序员分享:MySQL数据库企业级应用实践
|
18天前
|
存储 关系型数据库 MySQL
深入探索MySQL的虚拟列:发展、原理与应用
深入探索MySQL的虚拟列:发展、原理与应用
|
18天前
|
存储 JSON 关系型数据库
MySQL JSON 类型:功能与应用
MySQL JSON 类型:功能与应用