Electron25 integra Vue3 para crear nuevas ventanas múltiples | vite4 + administrador de formularios electrónicos

Tras el último intercambio de integración de electron24+vite4 para crear una aplicación de ventana de escritorio. Esta vez, en base a esto, compartiré el administrador de ventanas múltiples empaquetado ElectronVite-MultiWin.

https://blog.csdn.net/yanxinyun1990/article/details/130944508

Insertar descripción de la imagen aquí

A partir de ahora, la última versión estable de Electron es la 25.

Insertar descripción de la imagen aquí
Las rápidas actualizaciones iterativas de Electron y la eficiente velocidad de construcción y ejecución de Vite se combinan para crear ventanas independientes que se abren muy rápidamente.

Insertar descripción de la imagen aquí
El módulo de proceso principal de electrones BrowserWindow se utiliza para crear un nuevo formulario simple.

https://www.electronjs.org/docs/latest/api/browser-window

// In the main process.
const {
    
     BrowserWindow } = require('electron')

const win = new BrowserWindow({
    
     width: 800, height: 600 })

// Load a remote URL
win.loadURL('https://github.com')

// Or load a local HTML file
win.loadFile('index.html')

Para poder llamarlo varias veces, el método BrowserWindow ahora está encapsulado. Para que pueda llamarse simplemente así:

createWin({
    
    
    title: '关于About.vue',
    route: '/about',
    width: 600,
    height: 400,
    background: '#fafffa',
    resize: true
})

Insertar descripción de la imagen aquí
windows/index.js

/**
 * 封装多窗口管理器
 * @author YXY  Q:282310962
 */

const {
    
     app, BrowserWindow, ipcMain } = require('electron')
const {
    
     join } = require('path')

process.env.ROOT = join(__dirname, '../../')

const isDevelopment = process.env.NODE_ENV == 'development'
// const winURL = isDevelopment ? 'http://localhost:3000/' : join(__dirname, 'dist/index.html')
const winURL = isDevelopment ? process.env.VITE_DEV_SERVER_URL : join(process.env.ROOT, 'dist/index.html')

// 配置参数
const defaultConfig = {
    
    
    id: null,               // 窗口唯一id
    background: '#fff',     // 背景色
    route: '',              // 路由地址url
    title: '',              // 标题
    data: null,             // 传入数据参数
    width: '',              // 窗口宽度
    height: '',             // 窗口高度
    minWidth: '',           // 窗口最小宽度
    minHeight: '',          // 窗口最小高度
    x: '',                  // 窗口相对于屏幕左侧坐标
    y: '',                  // 窗口相对于屏幕顶端坐标
    resize: true,           // 是否支持缩放
    maximize: false,        // 最大化窗口
    isMultiWin: false,      // 是否支持多开窗口
    isMainWin: false,       // 是否主窗口
    parent: '',             // 父窗口(需传入父窗口id)
    modal: false,           // 模态窗口(模态窗口是浮于父窗口上,禁用父窗口)
    alwaysOnTop: false      // 置顶窗口
}

class MultiWindows {
    
    
    constructor() {
    
    
        // 主窗口
        this.mainWin = null
        // 窗口组
        this.winLs = {
    
    }

        // ...
    }

    winOpts() {
    
    
        return {
    
    
            // 窗口图标
            icon: join(process.env.ROOT, 'resource/shortcut.ico'),
            backgroundColor: '#fff',
            autoHideMenuBar: true,
            titleBarStyle: 'hidden',
            width: 1000,
            height: 640,
            resizable: true,
            minimizable: true,
            maximizable: true,
            frame: false,
            show: false,
            webPreferences: {
    
    
                contextIsolation: true, // 启用上下文隔离(为了安全性)(默认true)
                // nodeIntegration: false, // 启用Node集成(默认false)
                preload: join(process.env.ROOT, 'resource/preload.js'),
                // devTools: true,
                // webSecurity: false
            }
        }
    }

    // 创建新窗口
    createWin(options) {
    
    
        const args = Object.assign({
    
    }, defaultConfig, options)
        console.log(args)

        // 判断窗口是否存在
        for(let i in this.winLs) {
    
    
            if(this.getWin(i) && this.winLs[i].route === args.route && !this.winLs[i].isMultiWin) {
    
    
                this.getWin(i).focus()
                return
            }
        }

        let opt = this.winOpts()
        if(args.parent) {
    
    
            opt.parent = this.getWin(args.parent)
        }

        if(typeof args.modal === 'boolean') opt.modal = args.modal
        if(typeof args.resize === 'boolean') opt.resizable = args.resize
        if(typeof args.alwaysOnTop === 'boolean') opt.alwaysOnTop = args.alwaysOnTop
        if(args.background) opt.backgroundColor = args.background
        if(args.width) opt.width = args.width
        if(args.height) opt.height = args.height
        if(args.minWidth) opt.minWidth = args.minWidth
        if(args.minHeight) opt.minHeight = args.minHeight
        if(args.x) opt.x = args.x
        if(args.y) opt.y = args.y

        console.log(opt)

        // 创建窗口对象
        let win = new BrowserWindow(opt)
        // 是否最大化
        if(args.maximize && args.resize) {
    
    
            win.maximize()
        }
        this.winLs[win.id] = {
    
    
            route: args.route, isMultiWin: args.isMultiWin
        }
        args.id = win.id


        // 加载页面
        let $url
        if(!args.route) {
    
    
            if(process.env.VITE_DEV_SERVER_URL) {
    
    
                // 打开开发者调试工具
                // win.webContents.openDevTools()
    
                $url = process.env.VITE_DEV_SERVER_URL
            }else {
    
    
                $url = winURL
            }
        }else {
    
    
            $url = `${
      
      winURL}#${
      
      args.route}`
        }
        win.loadURL($url)
        /*if(process.env.VITE_DEV_SERVER_URL) {
            win.loadURL($url)
        }else {
            win.loadFile($url)
        }*/
        win.webContents.openDevTools()

        win.once('ready-to-show', () => {
    
    
            win.show()
        })

        win.on('close', () => win.setOpacity(0))

        // 初始化渲染进程
        win.webContents.on('did-finish-load', () => {
    
    
            // win.webContents.send('win-loaded', '加载完成~!')
            win.webContents.send('win-loaded', args)
        })
    }

    // 获取窗口
    getWin(id) {
    
    
        return BrowserWindow.fromId(Number(id))
    }

    // 获取全部窗口
    getAllWin() {
    
    
        return BrowserWindow.getAllWindows()
    }

    // 关闭全部窗口
    closeAllWin() {
    
    
        try {
    
    
            for(let i in this.winLs) {
    
    
                if(this.getWin(i)) {
    
    
                    this.getWin(i).close()
                }else {
    
    
                    app.quit()
                }
            }
        } catch (error) {
    
    
            console.log(error)
        }
    }

    // 开启主进程监听
    ipcMainListen() {
    
    
        // 设置标题
        ipcMain.on('set-title', (e, data) => {
    
    
            const webContents = e.sender
            const wins = BrowserWindow.fromWebContents(webContents)
            wins.setTitle(data)
        })
        // 是否最大化
        ipcMain.handle('isMaximized', (e) => {
    
    
            const win = BrowserWindow.getFocusedWindow()
            return win.isMaximized()
        })

        ipcMain.on('min', e => {
    
    
            const win = BrowserWindow.getFocusedWindow()
            win.minimize()
        })
        ipcMain.handle('max2min', e => {
    
    
            const win = BrowserWindow.getFocusedWindow()
            if(win.isMaximized()) {
    
    
                win.unmaximize()
                return false
            }else {
    
    
                win.maximize()
                return true
            }
        })
        ipcMain.on('close', (e, data) => {
    
    
            // const wins = BrowserWindow.getFocusedWindow()
            // wins.close()
            this.closeAllWin()
        })

        // ...
    }
}

module.exports = MultiWindows

Luego inicialice la ventana en el archivo background.js del proceso principal.

const {
    
     app, BrowserWindow, ipcMain } = require('electron')
const {
    
     join } = require('path')

const MultiWindows = require('./src/windows')

// 屏蔽安全警告
// ectron Security Warning (Insecure Content-Security-Policy)
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'

const createWindow = () => {
    
    
    let window = new MultiWindows()

    window.createWin({
    
    isMainWin: true})
    window.ipcMainListen()
}

app.whenReady().then(() => {
    
    
    createWindow()
    app.on('activate', () => {
    
    
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})

app.on('window-all-closed', () => {
    
    
    if (process.platform !== 'darwin') app.quit()
})

Cree un oyente ipcMain para una ventana independiente

ipcMain.on('win-create', (event, args) => this.createWin(args))

Insertar descripción de la imagen aquí

/**
 * 创建新窗口
 * @param {object} args | {width: 640, height: 480, route: '/home'}
 */
export function createWin(args) {
    
    
    window.electronAPI.send('win-create', args)
}

/**
 * 设置窗口
 * @param {string} type | 'show'/'hide'/'close'/'min'/'max'/'max2min'/'restore'/'reload'
 * @param {number} id
 */
export function setWin(type, id) {
    
    
    window.electronAPI.send('win-' + type, id)
}

/**
 * 创建登录窗口
 */
export function loginWin() {
    
    
    createWin({
    
    
        isMainWin: true,
        title: '登录',
        route: '/login',
        width: 550,
        height: 320,
        resize: false,
        alwaysOnTop: true,
    })
}

Insertar descripción de la imagen aquí

Cree una nueva página vue y practique la creación de métodos de ventanas múltiples.

<template>
    <div class="home">
        ...

        <Button type="success" @click="openWin">打开Manage窗口(设置parent)</Button>
        <Button type="success" @click="openWin1">打开Me窗口(设置resizable/isMultiWin)</Button>
        <Button type="success" @click="openWin2">打开User窗口</Button>
    </div>
</template>

<script>
import {
    
     winCfg, createWin } from '@/windows/action'

export default {
    
    
    name: 'Home',
    setup() {
    
    
        const openWin = () => {
    
    
            MessageBox.confirm('提示', '确定打开Manage页面吗? 【设置parent属性】', {
    
    
                callback: action => {
    
    
                    if(action == 'confirm') {
    
    
                        createWin({
    
    
                            title: 'Manage.vue',
                            route: '/manage',
                            width: 600,
                            height: 400,
                            background: '#09f',
                            parent: winCfg.window.id,
                            // modal: true
                        })
                    }else if(action == 'cancel') {
    
    
                        Message.info('您已取消!')
                    }
                }
            })
        }

        const openWin1 = () => {
    
    
            // 左上角
            // let posX = 0
            // let posY = 0

            // 右下角
            let posX = window.screen.availWidth - 850
            let posY = window.screen.availHeight - 600
            MessageBox.confirm('提示', '确定打开Me页面吗?', {
    
    
                callback: action => {
    
    
                    if(action == 'confirm') {
    
    
                        createWin({
    
    
                            title: 'Me.vue',
                            route: '/me?name=Andy',
                            width: 850,
                            height: 600,
                            x: posX,
                            y: posY,
                            background: 'yellow',
                            resize: false,
                            isMultiWin: true,
                            maximize: true
                        })
                    }else if(action == 'cancel') {
    
    
                        Message.info('您已取消!')
                    }
                }
            })
        }

        const openWin2 = () => {
    
    
            MessageBox.confirm('提示', '确定打开User页面吗?', {
    
    
                callback: action => {
    
    
                    if(action == 'confirm') {
    
    
                        createWin({
    
    
                            title: 'User.vue',
                            route: '/user',
                            width: 700,
                            height: 550,
                            minWidth: 300,
                            minHeight: 300,
                            data: {
    
    
                                name: 'Andy',
                                age: 20
                            },
                            background: 'green',
                            isMultiWin: true
                        })
                    }else if(action == 'cancel') {
    
    
                        Message.info('您已取消!')
                    }
                }
            })
        }

        // ...

        return {
    
    
            openWin,
            openWin1,
            openWin2,

            // ...
        }
    }
}
</script>

Lo anterior es un intercambio de la última versión de electron + vite4 para crear múltiples ventanas. Espero que sea útil para todos ~~

https://blog.csdn.net/yanxinyun1990/article/details/130816346

https://blog.csdn.net/yanxinyun1990/article/details/130144212

Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/yanxinyun1990/article/details/130977430
Recomendado
Clasificación