vue和Electron框架 webview技术实践

最近团队把桌面客户端项目的分摊给我,于是着手学研究electron逻辑了。

我的架构

原来的项目,代码管理混乱,要加一点内容可能会影响到其他内容,代码冗余,一个 main.js 写了全部代码,于是我创建了自己的架构。

Main Process模块

Main Process 分为以下模块,查找文本、更新、系统托盘、socket 通信、小红点、dock、菜单、快捷键模块,每个模块都是独立模块,通过 config 配置文件就可以直接启用或关闭某个模块。

js 复制代码
const index = {
    /**
     * 模式 window/iframe/webview
     */
    mode: "webview",

    /**
     * 是否启用证书认证
     */
    certificate: false,

    /**
     * 是否启用查找文本
     */
    findText: true,

    /**
     * 是否启用更新
     */
    updateApp: true,

    /**
     * 系统托盘
     */
    tray: true,

    /**
     * 系统托盘是否闪烁
     */
    trayFlash: true,

    /**
     * 是否启用 socket 通信
     */
    socket: false,

    /**
     * 应用菜单栏
     */
    applicationMenu: true,

    /**
     * 应用更新路径
     */
    updateUrl: '',

    /**
     * 外部项目地址
     */
    url: '',
    name: '测试项目',
};

module.exports = index;

Render Process 模块

同时也把 Render Process 改成了 vue3 项目,只不过我这里没有用脚手架,当然你可以使用任何框架。

目录

我的目录结构如下图,目前现这样,可以在细分优化

难点

更新

由于应用没有签名,所以在 windows 上使用 electron-updater 自动更新是没有问题的,但是 mac就无法更新,所以 mac 需要用户手动安装项目。 我们的更新流程是这样的,

  1. 在主进程调用更新的方法
  2. 使用 electronnet 模块去请求 updateUrl 链接
  3. 判断远程版本是否大于本地版本,小于等于则什么都不做,大于则进入步骤 4
  4. 弹出检测到新版提示窗口
  5. 用户点击立即更新后
  6. 判断是 windows/mac,是 mac 走步骤 7, 是windows 走步骤 11
  7. 选择下载位置
  8. 进行下载,弹出下载进度窗口
  9. 下载完成后,点击立即安装
  10. 自动弹出安装界面
  11. 触发 electron-updater 相关方法
  12. 弹出下载进度窗口
  13. 下载完成后,点击立即安装就立即安装,否则下载启动是自动安装

主进程和 webview 通信

如果只是 iframe,那么直接用 postMessage 就行了,但是当你的 Render Process中使用了 web-view 标签时,主进程想和webview 这个外部项目通信时,使用了网上的各种办法都不行,都无法直接获取到 electron里的方法,后来就直接使用 socket实现双方通信。于是封装了 socket 相关代码,最后使用者只需要在 electron/socket/api.js文件中写相关代码就行,如何连接的就不用关心了。

js 复制代码
const sockets = {
  prdListMounted(socket, data) {
    socket.emit('welcome', `欢迎${socket.id}连接1`)
  },
  exportExcel(socket, data) {
    console.log('点击了导出商品');
  },
};

module.exports = sockets;

我外部项目使用的是 vue2,所以需要使用 npm 安装两个包 vue-socket.iosocket.io-client

创建 socket/index.js

js 复制代码
import Vue from 'vue';

import VueSocketIO from 'vue-socket.io';
import socketIO from 'socket.io-client';
import store from '@/store';

const PORT = 31596;
const URL = '127.0.0.1';

const isElectron = navigator.userAgent.includes('Electron');

// 只有是 Electron 的时候才能进行 socket 通信
if (isElectron) {
  let Socket = new VueSocketIO({
    debug: true, // true开启
    connection: socketIO(`ws://${URL}:${PORT}`), // 里面写socket服务器地址
    // 使用vuex
    vuex: {
      store,
      // 定义vuex函数的时候,用来区分普通函数还是socket函数。
      actionPrefix: 'SOCKET_',
      mutationPrefix: 'SOCKET_',
    },
    options: {
      autoConnect: false, // 关闭自动连接,一般是在用户登录过后才进行手动连接
    },
  });
  Vue.use(Socket);
}

创建 socket/emit.js,这个文件用来做个兼容

js 复制代码
import Vue from 'vue';

const defaultData = {
  emit() {},
};

let socket = Vue.prototype.$socket || defaultData;

const emit = (name, data) => {
  socket.emit(name, data);
};
export default emit;

创建 socket/api.js

js 复制代码
import emit from './emit';

// 在 prdList 页面 Mounted 的时候调用这个方法
export function prdListMounted(data = {}) {
  emit('prdListMounted', data);
}

// 点击 导出表格按钮 调用这个方法
export function exportExcel(data = {}) {
  emit('exportExcel', data);
}

prdList页面 demo

html 复制代码
<template>
  <div>
    <el-button @click="click">export</el-button>
  </div>
</template>

<script>
import { prdListMounted, exportExcel } from '@/utils/socket/api';

export default {
  mounted() {
    prdListMounted('我 mounted')
  },
  // 此处为接收 electron 主进程数据的地方
  sockets: {
    welcome(data) {
      console.log('welcome data', data);
    },
  },
  methods: {
    click() {
        exportExcel({
            a: 1,
            b: 2,
        })
    }
  },
};
</script>
相关推荐
今天也想MK代码3 天前
在Swift开发中简化应用程序发布与权限管理的解决方案——SparkleEasy
前端·javascript·chrome·macos·electron·swiftui
yqcoder3 天前
electron 中 ipcRenderer 的常用方法有哪些?
前端·javascript·electron
yqcoder3 天前
electron 中 ipcRenderer 作用
前端·javascript·electron
伍嘉源4 天前
关于electron进程管理的一些认识
前端·javascript·electron
yqcoder4 天前
electron 设置最小窗口缩放
前端·javascript·electron
yqcoder5 天前
区分 electron 全屏和最大化
前端·javascript·electron
li.siyuan6 天前
electron + vue 打包完成后,运行提示 electrion-updater 不存在
前端·vue.js·electron
努力挣钱的小鑫6 天前
【客户端开发】electron 中无法使用 js-cookie 的问题
前端·javascript·electron
蓝胖子不是胖子6 天前
尝鲜electron --将已有vue/react项目转换为桌面应用
vue.js·react.js·electron
非晓为骁6 天前
windows 下 electron-builder ERR_ELECTRON_BUILDER_CANNOT_EXECUTE 报错处理
javascript·windows·electron