vue3+tauri 创建多开窗口桌面应用

最近一直在体验 Tarui 结合 Vue3 开发桌面端exe应用。之前也开发了几个 Electron 桌面应用。相较于 Electron 构建慢、打包后程序体积大,Tauri 构建的程序则具有更小、更快、更安全的优势。

vue3+tauri 创建多开窗口桌面应用_第1张图片

在github上面star已经达到了53K。

vue3+tauri 创建多开窗口桌面应用_第2张图片

https://github.com/tauri-apps/tauri

使用 tauri 和 electron 构建同样的一个 Test 程序。

electron打包体积 53 M,tauri打包体积才只有 3 M

由于 electron 使用了体积庞大的 Chromium 内核和Nodejs,所以每次构建新开应用,打开非常慢。

vue3+tauri 创建多开窗口桌面应用_第3张图片

如下图:tauri构建应用还提供了很多前端初始化框架模板。

vue3+tauri 创建多开窗口桌面应用_第4张图片

开发准备

在开发之前,首先您需要安装 Rust 及其他系统依赖。

  • “C++ 生成工具” 和 Windows 10 SDK。
  • Tauri 需要 WebView2 才能在 Windows 上呈现网页内容,所以您必须先安装 WebView2。
  • Rust

大家可以请前往 https://tauri.app/zh/v1/guides/getting-started/prerequisites 来查看详细操作步骤。

vue3+tauri 创建多开窗口桌面应用_第5张图片

tauri创建初始化项目

npm create tauri-app

vue3+tauri 创建多开窗口桌面应用_第6张图片

开发/打包构建

tauri dev
tauri build

vue3+tauri 创建多开窗口桌面应用_第7张图片

官网提供了多种构建多窗口方式,具体的操作大家可以去查看。
https://tauri.app/zh/v1/guides/features/multiwindow

接下来给大家分享tauri封装多窗口,调用方式如下:

createWin({
    label: 'Home',
    title: '主页',
    url: '/home',
    width: 800,
    height: 600,
})

url就是vue-router创建的path路径,这样就能快速创建一个新窗口。

vue3+tauri 创建多开窗口桌面应用_第8张图片

index.js文件

/**
 * @desc    封装多开窗口
 * @author: YXY  Q:282310962
 * @time    2022.10
 */

import { WebviewWindow, appWindow, getAll, getCurrent } from '@tauri-apps/api/window'
import { relaunch, exit } from '@tauri-apps/api/process'
import { emit, listen } from '@tauri-apps/api/event'

import { setWin } from './actions'

// 系统参数配置
export const windowConfig = {
    label: null,            // 窗口唯一label
    title: '',              // 窗口标题
    url: '',                // 路由地址url
    width: 900,             // 窗口宽度
    height: 640,            // 窗口高度
    minWidth: null,         // 窗口最小宽度
    minHeight: null,        // 窗口最小高度
    x: null,                // 窗口相对于屏幕左侧坐标
    y: null,                // 窗口相对于屏幕顶端坐标
    center: true,           // 窗口居中显示
    resizable: true,        // 是否支持缩放
    maximized: false,       // 最大化窗口
    decorations: false,     // 窗口是否无边框及导航条
    alwaysOnTop: false,     // 置顶窗口
}

class Windows {
    constructor() {
        this.mainWin = null
    }

    // 获取窗口
    getWin(label) {
        return WebviewWindow.getByLabel(label)
    }

    // 获取全部窗口
    getAllWin() {
        return getAll()
    }

    // 创建新窗口
    async createWin(options) {
        const args = Object.assign({}, windowConfig, options)

        // 判断窗口是否存在
        const existWin = getAll().find(w => w.label == args.label)
        if(existWin) {
            if(existWin.label.indexOf('main') == -1) {
                await existWin?.unminimize()
                await existWin?.setFocus()
                return
            }
            await existWin?.close()
        }

        // 创建窗口对象
        let win = new WebviewWindow(args.label, args)
        
        // 是否最大化
        if(args.maximized && args.resizable) {
            win.maximize()
        }

        // 窗口创建完毕/失败
        win.once('tauri://created', async() => {
            console.log('window create success!')
            ...
        })

        win.once('tauri://error', async() => {
            console.log('window create error!')
        })
    }

    // 开启主进程监听事件
    async listen() {
        // 创建新窗体
        await listen('win-create', (event) => {
            console.log(event)
            this.createWin(JSON.parse(event.payload))
        })

        // 显示窗体
        await listen('win-show', async(event) => {
            if(appWindow.label.indexOf('main') == -1) return
            await appWindow.show()
            await appWindow.unminimize()
            await appWindow.setFocus()
        })

        // 隐藏窗体
        await listen('win-hide', async(event) => {
            if(appWindow.label.indexOf('main') == -1) return
            await appWindow.hide()
        })

        // 退出应用
        await listen('win-exit', async(event) => {
            setWin('logout')
            await exit()
        })

        // 重启应用
        await listen('win-relaunch', async(event) => {
            await relaunch()
        })

        // 主/渲染进程传参
        await listen('win-setdata', async(event) => {
            await emit('win-postdata', JSON.parse(event.payload))
        })
    }
}

export default Windows

actions.js文件

/**
 * 处理渲染器进程到主进程的异步通信
 */

import { WebviewWindow } from '@tauri-apps/api/window'
import { emit } from '@tauri-apps/api/event'

/**
 * @desc 创建新窗口
 */
export async function createWin(args) {
    await emit('win-create', args)
}

/**
 * @desc 获取窗口
 * @param args {string}
 */
export async function getWin(label) {
    return await WebviewWindow.getByLabel(label)
}

/**
 * @desc 设置窗口
 * @param type {string} 'show'|'hide'|'close'|'min'|'max'|'max2min'|'exit'|'relaunch'
 */
export async function setWin(type) {
    await emit('win-' + type)
}

/**
 * @desc 登录窗口
 */
export async function loginWin() {
    await createWin({
        label: 'Login',
        title: '登录',
        url: '/login',
        width: 320,
        height: 420,
        resizable: false,
        alwaysOnTop: true,
    })
}

// ...

在需要创建新窗口的.vue页面,引入 actions.js 文件。

import { loginWin, createWin } from '@/windows/actions'

const manageWin = () => {
    createWin({
        label: 'Manage',
        title: '管理页面',
        url: '/manage',
        width: 600,
        height: 450,
        minWidth: 300,
        minHeight: 200
    })
}

const aboutWin = () => {
    createWin({
        label: 'About',
        title: '关于页面',
        url: '/about',
        width: 500,
        height: 500,
        resizable: false,
        alwaysOnTop: true
    })
}

这样就能愉快随意的创建多窗口了,大家还可以在此基础上优化一些功能。

好了,今天的分享就先到这里吧,后续还会分享一些tauri实例项目,到时也会进行一些技术分享。

最后附上几个 electron+vue3 实例项目

vue3+electron开发仿QQ桌面应用程序

vite2+electron+elementPlus仿macOs桌面框架

vue3+tauri 创建多开窗口桌面应用_第9张图片

你可能感兴趣的:(tauri+vue3,rust+webview2,tauri多窗口,tauri+vite3,tauri多开窗体)