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

news2024/11/16 7:45:36

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

📝项目概述

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

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

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

🏆项目预览

💻技术栈

  • 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的图片
然后执行。就能看到图标已经生成了。

npm run tauri icon

📢配置应用系统托盘

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

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中使用

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 文件中进行配置:

{
  "tauri": {
    "allowlist": {
      "http": {
        "all": true,
        "request": true,
        "scope":[
          "http://**",
          "https://**"
        ]
      }
    }
  }
}

🎵基于API的封装

// 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)
    })
  })
}

😄获取版本号

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

import { getVersion } from '@tauri-apps/api/app'
onMounted(async () => {
  appVersion.value = await getVersion()
  getNewVersions()
})

🙂检查版本更新

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

import { checkUpdate, installUpdate } from '@tauri-apps/api/updater'
  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: '取消'})
    }
  })

🙃窗口操作

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

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

🥰禁用最大化和取消禁用

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

🥰消息提示

Ask弹窗

import { ask } from '@tauri-apps/api/dialog';
const yes = await ask('确定更新该版本?', '发现新版本');
const yes2 = await ask('确定更新该版本?', { title: '发现新版本', type: 'warning' });

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

😊confirm弹窗

import { confirm } from '@tauri-apps/api/dialog';
const confirmed = await confirm('确定更新该版本?', '发现新版本');
const confirmed2 = await confirm('确定更新该版本?', { title: '发现新版本', type: 'warning',okLabel: '确定',cancelLabel: '取消' });

😝message提示框

import { message } from '@tauri-apps/api/dialog';
await message('确定更新该版本', '发现新版本');
await message('确定更新该版本', { title: '发现新版本', type: 'error',okLabel: '确定',cancelLabel: '取消' });

🤗open 选择文件弹窗

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文件保存弹窗

import { save } from '@tauri-apps/api/dialog';
const filePath = await save({
  filters: [{
    name: 'Image',
    extensions: ['png', 'jpeg']
  }]
});

😁splashscreen页设置

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

🫠tauri.conf.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 页面的功能

// 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入口提供给前端使用

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页面

界面加载完成后,关掉

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。一起成长,一起进步。

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

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

相关文章

excel字符串列的文本合并

excel表有两列,第一列是“姓名”,第二列是“诊断”,有高血压、糖尿病等。我想出一个统计表,统计“姓名”,把某一个姓名的诊断不重复的用、拼接起来,比如“张三”的诊断为“点高血压”、糖尿病。我们可以用T…

轻量级SEO分析工具网站源码去授权

轻量级SEO分析工具网站全新去授权发布,这款工具将助您轻松生成直观、简洁、易于理解的SEO报告,为您的网页排名和表现提供有力支持。 测试环境: Apache PHP 8.0 MySQL 5.7 更新日志 v12.0 – 2024年2月20日 新增功能: 正常运行…

LabVIEW在核磁共振实验室的应用

​核磁共振(NMR)实验室在进行复杂的核磁共振实验时,需要一个高效、灵活且易于操作的实验控制和数据采集系统。传统的NMR实验系统往往使用专门的硬件和软件,存在系统封闭、扩展性差、维护成本高等问题。为了解决这些问题&#xff0…

【JavaEE】Spring Boot 统一功能处理

一.拦截器使用. 1.什么是拦截器? 拦截器是Spring框架提供的核心功能之⼀, 主要用来拦截用户的请求, 在指定方法前后, 根据业务需要执行预先设定的代码 也就是说, 允许开发人员提前预定义一些逻辑, 在用户的请求响应前后执行. 也可以在用户请求前阻止其执行. 在拦截器当中&am…

Flutter 像素编辑器#05 | 缩放与平移

theme: cyanosis 本系列,将通过 Flutter 实现一个全平台的像素编辑器应用。源码见开源项目 【pix_editor】。在前三篇中,我们已经完成了一个简易的图像编辑器,并且简单引入了图层的概念,支持切换图层显示不同的像素画面。 《Flutt…

Web服务器与Apache(LAMP架构+搭建论坛)

一、Web基础 1.HTML概述 HTML&#xff08;Hypertext Markup Language&#xff09;是一种标记语音,用于创建和组织Web页面的结构和内容&#xff0c;HTML是构建Web页面的基础&#xff0c;定义了页面的结构和内容&#xff0c;通过标记和元素来实现 2.HTML文件结构 <html>…

抖音电商618国货数据:洗护、服饰等受欢迎,活力28环比增长40%

发布 | 大力财经 6月21日&#xff0c;抖音电商发布“抖音商城618好物节”消费数据报告&#xff08;下称“报告”&#xff09;&#xff0c;披露618期间平台全域经营情况及大众消费趋势&#xff0c;其中国货表现亮眼。 本次大促恰逢传统节日端午节&#xff0c;报告显示&#xf…

实验08 软件设计模式及应用

目录 实验目的实验内容一、能播放各种声音的软件产品Sound.javaDog.javaViolin.javaSimulator.javaApplication.java运行结果 二、简单工厂模式--女娲造人。Human.javaWhiteHuman.javaYellowHuman.javaBlackHuman.javaHumanFactory.javaNvWa.java运行结果 三、工厂方法模式--女…

React 扩展

文章目录 PureComponent1. 使用 React.Component&#xff0c;不会进行浅比较2. 使用 shouldComponentUpdate 生命周期钩子&#xff0c;手动比较3. 使用 React.PureComponent&#xff0c;自动进行浅比较 Render Props1. 使用 Children props&#xff08;通过组件标签体传入结构&…

nginx负载均衡案例,缓存知识----补充

负载均衡案例 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near great all on wordpress.* to wp172.16.1.% indentified by 1 at line 1 MariaDB [(none)]>…

iptables(5)常用扩展模块iprange、string、time、connlimit、limit

简介 之前我们已经介绍过扩展模块的简单使用,比如使用-m tcp/udp ,-m multiport参数通过--dports,--sports可以设置连续和非连续的端口范围。那么我们如何匹配其他的一些参数呢,比如源地址范围,目的地址范围,时间范围等,这就是我们这篇文章介绍的内容。 iprange扩展模块…

Jmeter插件管理器,websocket协议,Jmeter连接数据库,测试报告的查看

目录 1、Jmeter插件管理器 1、Jmeter插件管理器用处&#xff1a;Jmeter发展并产生大量优秀的插件&#xff0c;比如取样器、性能监控的插件工具等。但要安装这些优秀的插件&#xff0c;需要先安装插件管理器。 2、插件的下载&#xff0c;从Availabale Plugins中选择&#xff…

服务器(Linux系统的使用)——自学习梳理

root表示用户名 后是机器的名字 ~表示文件夹&#xff0c;刚上来是默认的用户目录 ls -a 可以显示出隐藏的文件 蓝色的表示文件夹 白色的是文件 ll -a 查看详细信息 total表示所占磁盘总大小 一般以KB为单位 d开头表示文件夹 -代表文件 后面得三组rwx分别对应管理员用户-组…

VSCode创建并运行html页面(使用Live Server插件)

目录 一、参考博客二、安装Live Server插件三、新建html页面3.1 选择文件夹3.2 新建html文件3.3 快速生成html骨架 四、运行html页面 一、参考博客 https://blog.csdn.net/zhuiqiuzhuoyue583/article/details/126610162 https://blog.csdn.net/m0_74014525/article/details/13…

设计模式5-策略模式(Strategy)

设计模式5-策略模式 简介目的定义结构策略模式的结构要点 举例说明1. 策略接口2. 具体策略类3. 上下文类4. 客户端代码 策略模式的反例没有使用策略模式的代码 对比分析 简介 策略模式也是属于组件协作模式一种。现代软件专业分工之后的第一个结果是框架语音应用程序的划分。组…

MATLAB-振动问题:单自由度无阻尼振动系统受迫振动

一、基本理论 二、MATLAB实现 令式&#xff08;1.3&#xff09;中A0 2&#xff0c;omega0 30&#xff0c;omega 40&#xff0c;matlab程序如下&#xff1a; clear; clc; close all;A0 2; omega0 30; omega 40; t 0:0.02:5; y A0 * sin( (omega0 - omega) * t /2) .* s…

【源码+文档+调试讲解】牙科就诊管理系统

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本牙科就诊管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

计算机网络 访问控制列表以及NAT

一、理论知识 1. 单臂路由 单臂路由是一种在路由器上配置多个子接口的方法&#xff0c;每个子接口代表不同的 VLAN&#xff0c;用于在一个物理接口上支持多 VLAN 通信。此方法使得不同 VLAN 之间可以通过路由器进行通信。 2. NAT (网络地址转换) NAT 是一种在私有网络和公共…

vue+three.js渲染3D模型

安装three.js: npm install three 页面部分代码&#xff1a; <div style"width: 100%; height: 300px; position: relative;"><div style"height: 200px; background-color: white; width: 100%; position: absolute; top: 0;"><div id&…

小阿轩yx-MySQL数据库管理

小阿轩yx-MySQL数据库管理 使用 MySQL 数据库 在服务器运维工作中不可或缺的 SQL &#xff08;结构化查询语句&#xff09;的四种类型 数据定义语言&#xff08;DDL&#xff09;&#xff1a;DROP&#xff08;删除&#xff09;、CREATE&#xff08;创建&#xff09;、ALTER&…