electron+vite+vue3+typescript实现的桌面客户端应用

193 阅读2分钟

AdbClient一个使用adb管理手机设备的工具应用

项目环境

  • 1.vue3 + vite + typescript
  • 2.electron
  • 3.node:14.18.2+
  • 4.依赖管理使用:yarn

参考文档:搭建第一个 electron-vite 项目

项目介绍

按照electron项目的特性分为:main主进程,preload中间层,render渲染层

实现的效果 adb-devices.png

一、main主进程介绍

index.ts入口文件里面有一个createWindow()方法是创建应用窗口的方法。

其他的adb.tszip.ts文件里面是给主进程注册的一些方法放在了class类里面方便管理和编写, 在代码最后会创建对应类的对象(主要为了执行类的构造方法)。

index.ts入口文件中引入上面的adb.tszip.ts文件后就相当于执行了对象的构造方法即给主进程注册了一些方法。

Adb命令实现文档

src/main/adb.ts代码介绍:

import {app, dialog, ipcMain} from 'electron'
const util = require("util");
const execPromise = util.promisify(require("child_process").exec);

class AdbPlugin {
  adb_path: string | undefined;

  # 在vue页面中需要先调用checkAdbValidMain方法再调用其他方法,设置并检查adb路径没问题再执行其他方法
  constructor() {
    //注册main进程的事件
    ipcMain.handle('checkAdbValidMain', () => this.checkAdbValidMain())
    ipcMain.handle('runAdbCommandMain', (event, para) => this.runAdbCommandMain(para))
  }

  //检查adb环境是否正确
  async checkAdbValidMain() {
    console.log("\n\ncheckAdbValidMain==")
    const isBuild = process.env.NODE_ENV === 'production';
    let adb_path_dev = path.resolve(process.cwd(), 'doc', 'adb_win32', 'adb.exe')
    let adb_path_prod = path.resolve(process.cwd(), 'resources', 'adb_win32', 'adb.exe')
    this.adb_path = isBuild ? adb_path_prod : adb_path_dev
    ...
    return {platform, adbValid, adb_path: this.adb_path, adb_version};
  }

  async runAdbCommandMain(para) {
    return await this._runAdb(para)
  }

  //执行adb命令
  _runAdb(args) {
    let adbPath = localConfig.getItem('adbPath')
    args = `"${adbPath}" ${args}`;
    console.warn(`run: ${args}`);
    return execPromise(args);
  }
}

const adbPlugin = new AdbPlugin()

二、preload中间层介绍

在入口文件index.ts中会给window定义一些属性。

adbApi.tszipApi.ts文件中定义了adbApi对象及一些方法,主要是使用ipcRenderer调用main进程的方法。

index.ts文件中引入上面的文件,并将adbApi对象和zipApi对象挂载到window

src/preload/adbAPi.ts代码介绍:

import {ipcRenderer} from 'electron';

// Custom APIs for renderer
export const adbApi = {

  async checkAdbValidPreload() {
    return await ipcRenderer.invoke('checkAdbValidMain')
  },

  async listDevicesPreload() {
    return await ipcRenderer.invoke('listDevicesMain')
  },
}

三、render渲染层介绍

1.将所有需要调用preload中间层的方法都放在一个公共的文件src/renderer/src/utils/plugin.ts里面,方便方法参数的定义和使用等。

Adb组件实现介绍

src/render/src/utils/plugin.ts代码介绍:

//adb功能
export const adbPlugin = new class {
  async checkAdbValidRender() {
    // @ts-ignore (define in dts)
    return await window.adbApi.checkAdbValidPreload()
  }
  async listDevicesRender() {
    // @ts-ignore (define in dts)
    return await window.adbApi.listDevicesPreload()
  }
}
...

2.具体在页面中调用的时候:

src/renderer/src/components/adb/DeviceList.vue代码介绍

const listDevices = async () => {
  ...
  let deviceList = await adbPlugin.listDevicesRender()
  console.log("listDevices=>", deviceList)
  state.deviceList = deviceList
}