无需WebView,Vue也能开发跨平台桌面应用
前言
一直以来,使用Vue开发桌面应用大部分都是使用基于webview的方案,如electron,tauri等。不依赖webview的,移动端倒有不少,如Weex,NativeScript等,桌面端寥寥无几。
最近,Deft框架完成了Vue3的适配,支持使用Vue+Rust开发跨平台应用,不依赖Webview,目前支持Linux,Windows,MacOS和Android等系统,后续计划将支持鸿蒙和iOS。
快速开始
开始前,系统需要先安装nodejs,Rust,clang14+,如果未安装,直接去官网下载安装即可。
执行下面命令,快速创建新工程,my-vue-app为新工程名称。
npm create deft@latest my-vue-app
可以根据自己的喜好选择语言和框架,这里,以TypeScript+Vue为例。
命令执行完后,会在当前目录下创建一个my-vue-app
项目,执行下面命令启动项目。
cd my-vue-app
npm install
npm run dev
启动成功后,会得到如下输出:
...
Rspack compiled successfully in 2.31 s
==============================================
Press r to run on this device
Press a to run on connected android device
Press q to quit
==============================================
按r
,即可开始构建预览应用。首次构建,需要下载依赖,所以耗时可能会比较长,可以配置cargo镜像提高下载速度。
构建成功后,就能看到预览窗口了,可以直接修改ui
目录下的JS/TS文件实时预览效果。
资源占用
在Win11下内存占用仅12M,应用体积包20M,压缩后仅9M。
系统接口调用
开发桌面应用的过程中,有时会遇到调用系统接口的需求,特别是开发本地工具类应用的时候。JS本身不提供系统调用的接口,但是Rust可以非常方便的进行系统接口调用,我们可以使用Rust编写系统调用逻辑,然后提供接口给JS调用,从而扩展JS的能力。
以获取系统和内存信息为例,不同系统提供的底层接口往往不一样,为了抹平不同系统之间的差异,我们可以借助sysinfo
库来简化我们的工作。
增加依赖
首先,在命令行切换到我们的工程目录,执行以下命令增加cargo依赖。
cargo add sysinfo serde
定义数据交换结构
然后,需要定义Rust和JS之间的通信数据结构,打开项目下的main.rs
,增加如下内容:
use deft::js_serialize;
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SysInfo {
pub mem_total: u64,
pub mem_free: u64,
pub mem_used: u64,
pub sys_name: Option<String>,
pub sys_kernel_version: Option<String>,
pub sys_os_version: Option<String>,
pub sys_hostname: Option<String>,
pub cpu_count: usize,
}
js_serialize!(SysInfo);
js_serialize宏在这里的作用是使SysInfo结构体能序列化为js对象,而#[serde(rename_all = "camelCase")]
可以将字段的下划线命名规则自动转换成小驼峰命名。
使用Rust编写接口
定义好结构体后,就可以使用Rust编写接口了。继续在main.rs
增加如下内容:
use deft::js_func;
use sysinfo::{CpuRefreshKind, MemoryRefreshKind, RefreshKind, System};
#[js_func]
pub async fn get_sys_info() -> SysInfo {
let mut sys = System::new_with_specifics(
RefreshKind::nothing()
.with_cpu(CpuRefreshKind::everything())
.with_memory(MemoryRefreshKind::everything()),
);
sys.refresh_all();
let mem_total = sys.total_memory();
let mem_used = sys.used_memory();
let mem_free = sys.free_memory();
let sys_name = System::name();
let sys_kernel_version = System::kernel_version();
let sys_os_version = System::os_version();
let sys_hostname = System::host_name();
let cpu_count = sys.cpus().len();
SysInfo {
mem_total,
mem_used,
mem_free,
sys_name,
sys_kernel_version,
sys_os_version,
sys_hostname,
cpu_count,
}
}
这里有两个点需要关注的:
- 函数使用
[js_func]
注解,表明这是一个可供js调用的函数。 - 函数前使用
async
关键字修饰,表明这是一个异步执行的函数,这样即使在函数里执行了耗时任务,也不会阻塞UI线程。如果需要在UI线程同步执行,则去掉async
即可。
注册接口
万事具备,只欠东风。最后,我们只需把我们定义的get_sys_info
方法注册到js引擎即可。找到main.rs
里的init_js_engine
方法,增加以下代码:
js_engine.add_global_func(get_sys_info::new());
修改UI
接口完成了,现在我们来修改一下我们的UI。
声明接口
如果使用了TS,需要我们声明一下我们使用Rust导出的函数,不然TS编译器会报错。打开deft-env.d.ts
文件(或者在项目中新建一个d.ts
文件),增加如下内容:
declare interface SysInfo {
cpuCount: number;
memTotal: number;
memFree: number;
memUsed: number;
sysName: string;
sysKernelVersion: string;
sysOsVersion: string;
sysHostname: string;
}
declare function get_sys_info(): Promise<SysInfo>
在JS调用Rust接口
现在我们可以在JS里调用Rust编写的get_sys_info
函数了。打开项目里的App.vue
文件,script部分修改为:
const sysInfo = ref({} as SysInfo);
let stopped = false;
async function updateInfoLoop() {
if (stopped) {
return;
}
sysInfo.value = await get_sys_info();
setTimeout(updateInfoLoop, 1000);
}
updateInfoLoop();
onUnmounted(() => {
stopped = true;
})
这里,使用计时器,不停的刷新数据。
最后,在template里把这个数据渲染出来即可。
<container :style="{
alignItems: 'flex-start',
justifyContent: 'center',
height: '100%',
width: '100%',
gap: 20,
padding: '0 20',
}">
<container :style="{width: '100%', gap: 30}">
<container>
<container>系统名称:{{sysInfo.sysName}}</container>
<container>系统版本:{{sysInfo.sysOsVersion}}</container>
<container>内核版本:{{sysInfo.sysKernelVersion}}</container>
<container>处理器数:{{sysInfo.cpuCount}}</container>
<container>总内存量:{{formatMem(sysInfo.memTotal)}}</container>
</container>
<container :style="{width: '100%', gap: 4}">
<container :style="{
width: '100%',
justifyContent: 'space-between',
flexDirection: 'row'
}">
<container>已用内存:{{ formatMem(sysInfo.memUsed) }}</container>
<container>可用内存:{{ formatMem(sysInfo.memTotal - sysInfo.memUsed) }}</container>
</container>
<container :style="{width: '100%', height: 10, background: '#333'}">
<container :style="{
width: Math.round(100 * sysInfo.memUsed / sysInfo.memTotal) + '%',
height: '100%',
background: '#375fac'
}"></container>
</container>
</container>
</container>
</container>
这里的container相当于h5里的div。目前所有元素只支持内联样式,不支持通过class等选择器设置样式。
最终运行效果:
打包
执行下面命令即可打包
npm run build
打包完成后,会在target/你的系统架构/release/
目录下生成一个单独的可执行二进制文件(包含编译后的JS代码),将其拷贝出来即可。
相关链接
Deft框架:https://github.com/deft-ui/deft
Deft文档:https://deft-ui.github.io/guides/what-is-deft/
本文代码:https://github.com/deft-ui/deft-vue-examples/tree/main/system-info
无需WebView,Vue也能开发跨平台桌面应用的更多相关文章
- Electron+Vue开发跨平台桌面应用
Electron+Vue开发跨平台桌面应用 xiangzhihong发布于 2019-12-23 虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求.受限于浏览器的沙盒限制,网页应用无法满足某 ...
- 使用XUL开发跨平台桌面应用
先上图: 现在使用html,css,js开发桌面的优势越来越明显了,硬件性能的不断提升,人力成本越发昂贵,用户对界面要求越来越高,全球化下企业间的竞争越发激烈. 桌面软件50%+的工作量都在界面开发这 ...
- Electron开发跨平台桌面程序入门教程
最近一直在学习 Electron 开发桌面应用程序,在尝试了 java swing 和 FXjava 后,感叹还是 Electron 开发桌面应用上手最快.我会在这一篇文章中实现一个HelloWord ...
- 快速了解Electron:新一代基于Web的跨平台桌面技术
本文引用了作者“ ConardLi”的<用JS开发跨平台桌面应用,从原理到实践>一文部分内容,原文链接:segmentfault.com/a/1190000019426512,感谢原作者的 ...
- nodegui 使用react开发跨平台应用试用
nodegui官方团队提供了基于react 应用开发方式,同时我们集成官方的packer 进行快速的应用打包 项目说明 项目使用了官方的计算机应用,我使用官方的react starter,同时添加了p ...
- 用HTML5+JS开发跨平台的桌面应用
通过Node.js和WebKit技术的融合,开发者可以用HTML5技术编写UI,同时又能利用Node.js平台上众多library访问本地OS的能力,最终达到用Web技术就可以编写桌面应用的目的. 选 ...
- 使用JavaScript开发跨平台的桌面应用
任何可以使用JavaScript来编写的应用,最终会由JavaScript编写.--Atwood定律 Atwood's Law是Jeff Atwood在2007年提出的:"any appli ...
- electron-vue:Vue.js 开发 Electron 桌面应用
相信很多同学都知道 Electron 可以帮助开发人员使用前端技术开发桌面客户端应用,今天介绍的 electron-vue 框架是一套基于 Vue.js 开发 Electron 桌面应用的脚手架,该项 ...
- 基于Vue.js的uni-app前端框架结合.net core开发跨平台project
一.由来 最近由于业务需要要开发一套公益的APP项目,因此结合所给出的需求最终采用uni-app这种跨平台前端框架以及.netcore快速搭建我们的项目,并且能做到一套代码跨多个平台. 当然在前期技术 ...
- 使用nodegui 开发高性能的跨平台桌面端应用
nodegui 是基于qt + nodejs 的跨平台桌面开发方案,官方同时也提供了很不错的文档 简单使用 使用官方的starter clone 代码 git clone https://github ...
随机推荐
- 安装Jenkins,并部署vue前端,java后台
Jenkins 安装方式为Docker或war包. Publish Over SSH 插件下架后,Docker部署加ssh远程执行目前没找到合适的替代方案. 我选择的方案为:jenkins和应用服务器 ...
- NoSQL和SQL的区别、使用场景与选型比较
什么是NoSQL NoSQL,指的是非关系型的数据库.NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称,它具有非关系型.分布式.不提供ACID的数 ...
- 轮播图,swiper使用
背景: 最近接到一个需求,重写首页,需要用到轮播图. 但是轮播图只用两张图,此为前提. 本想直接用ElementUI的走马灯,但是只用两张图的情况下,走马灯不能循环播放,只能来回播放,公司的UI小姐姐 ...
- DCT实现水印嵌入与提取(带攻击)
问题: 想要用DCT技术,在Matlib上实现水印的隐藏和提取(带GUI界面),且加上一些攻击(噪声.旋转.裁剪),以及用NC值评判! 流程 选择载体 [filename,pathname]=uige ...
- Windows下使用Bat拷贝远程共享目录下文件
哈喽 我又来了 客户昨天提出了一个要求,这次的update里要用bat脚本去拷贝远程共享目录下的文件到各自的本地C盘目录下,于是乎,从昨天下午开始研究 到了今天中午,写写删删,乱改一气,总算弄出来 ...
- CBAM注意力模型介绍
本文分享自天翼云开发者社区<CBAM注意力模型介绍>,作者:Liuzijia 近年来,注意力机制在各项深度学习任务中表现出色.研究表明,人类视觉感知过程中,注意力机制发挥了积极的效果,可以 ...
- 将VSCode设置为中文(汉化)
1.VSCode安装好后默认语言为英文,此汉化过程的VSCode版本为1.42.1,如下图所示: 2.下载安装完成后,打开VSCode,使用快捷键Ctrl+Shift+P,然后在出现的输入框中输入co ...
- Sdcb Chats 重磅更新:深度集成 DeepSeek-R1,思维链让 AI 更透明!
Sdcb Chats 是一个强大且易于部署的 ChatGPT 前端,旨在帮助用户轻松接入和管理各种主流的大语言模型. Sdcb Chats 主要特性: 广泛的大模型支持: 已支持 15 种不同的大语言 ...
- mac安装nodejs、npm包设置
一.安装nodejs 1.下载自己系统的nodejs,我选择18.20版本 https://nodejs.cn/download/ 二.设置 1.设置镜像源: npm config set regis ...
- 【由技及道】量子构建交响曲:Jenkinsfile流水线的十一维编程艺术【人工智障AI2077的开发日志008】
摘要:当代码提交触发时空涟漪,当构建流水线穿越量子维度--欢迎来到自动化构建的终极形态.本文将揭示如何用Jenkinsfile编写量子构建乐章,让每次代码提交都成为跨维度交响乐的音符. 动机:构建系统 ...