资讯专栏INFORMATION COLUMN

【easy-invoices】electron-vue、sqlite3 项目初探

wpw / 2046人阅读

摘要:远程读取会有许多限制,防止引起不必要的安全隐患。比较时可以把点去掉转为数字类型比较脚本执行完毕下载前可以拿到更新日志时间版本号和包大小,下载时可以拿到速度。然后开启该项目的构建。将第一步生成的填至项目环境变量,参数名为。

父母都是做出纳相关的工作,希望我能给他们做个简单的进销存,在上班的时候使用。开发一个不需要花钱买服务器,不需要依赖网络(更新除外),单机版的程序,对于前端出身的我来说,那么electron或nwjs是最好的选择。
electron官网对electron与nwjs的比较
这里我选择了electron,因为很熟悉vue,就使用国人集成的electron-vue进行快速开发。本地数据库采用轻量嵌入型数据库sqlite3,不二之选。UI组件为iview。

本次项目【easy-invoices】github地址:https://github.com/CaanDoll/easy-invoices (求一波star~)

软件下载(目前只构建了windows版本):https://github.com/CaanDoll/easy-invoices/releases

electron官网:https://electronjs.org/

electron-vue官网:https://electron.org.cn/vue/index.html

界面预览:

物品管理

进出明细

一、环境准备

安装python2.7 和 Visual Studio 2015

二、安装vue-cli脚手架,初始化electron-vue目录
$ npm install -g vue-cli
$ vue init simulatedgreg/electron-vue easy-invoices

打包选择electron-builder。builder可以打包成具体文件,也可以是exe安装程序,而packager只能打包具体文件。下面会具体说明打包。
该命令会生成一个easy-invoices文件夹,大致目录如下(有细微变动)

.electron-vue:主要是webpack配置,还有一些封装好了的命令行的输出,供开发、打包调试用。可以自行添加一些配置,如在webpack.render.config.js里添加less-loader和eslint-loader。

build:打包需要的素材,例如icon。打包后的默认目录也在于此

src:源码,main是主进程部分,render是渲染进程部分,下文会讲到这两个概念。index.ejs会被编译为html的入口。

static:静态资源

有一些文件是我后来加上去的,比如eslint相关(.eslintrc.js,.eslintignore),与commit信息校验相关(verify_commmit_msg.js)等

.travis.yml为linux构建平台的配置,appveyor.yml为windows构建平台的配置。之后也会详细提到自动化构建。

三、sqlite3集成

nodejs中使用c++模块会涉及到编译问题,该编译常常会导致一些问题发生。
详细的操作请见我的另外一篇文章《electron项目中使用sqlite3的编译问题(windows)》

四、开始开发

在使用electron开发之前,我们需要注意以下几点

electron的运行依托于nodejs环境,渲染界面使用chromium。因此,我们开发界面实则编写html,并且在开发的过程中,可以使用nodejs原生模块,比如fs文件模块、os系统模块等。这使得我们的程序有更多的权限和功能,可以非常强大。但在强大的同时,开发者需要担起自身的责任,需要更多的去注意安全问题。

在electron里,最核心的两个概念就是主进程和渲染进程。主进程负责整个程序的调度,控制一些功能,只有一个。而渲染进程负责界面的渲染。他们之间可以相互通信。

electron加载html有两种方式,一种通过本地路径读取,一种通过http远程读取。远程读取会有许多限制,防止引起不必要的安全隐患。electron-vue封装好了开发模式和生产模式,开发模式启动webpack-dev-server,渲染进程远程读取,生产模式打包至本地,渲染进程本地路径读取。

electron-vue将vue与webpack集成进来快速开发。前端界面使用vue去开发,并使用vue-router做单窗口路由控制。webpack进行模块打包与开发时的监听。electron-vue脚手架提供了vue-electron,并已经封装了这个方法,当运行环境为electron的时候,会将electron挂载在Vue.prototype上。electron对象上有许多api,详情请参考文档。

// vue入口文件
// src/renderer/main.js
if (!process.env.IS_WEB) Vue.use(require("vue-electron"));

...

1.主进程与渲染进程通信

主进程向渲染进程发送消息:

// src/main/index.js
import { BrowserWindow } from "electron";
const mainWindow = new BrowserWindow();
mainWindow.webContents.send("messageOne", "haha");

// 某vue组件

7. 打包

前文提到,我采用的是electron-builder进行打包。electron-builder官方文档
打包的主要配置在package.json里:

{
    "scripts":{
        "build": "node .electron-vue/build.js && electron-builder",
        "build:dir": "node .electron-vue/build.js && electron-builder --dir"
    },
    "build": {
        "productName": "easy-invoices",
        "copyright": "caandoll",
        "appId": "org.caandoll.easy-invoices",
        "directories": {
          "output": "build"
        },
        "files": [
          "dist/electron/**/*"
        ],
        "dmg": {
          "contents": [
            {
              "x": 410,
              "y": 150,
              "type": "link",
              "path": "/Applications"
            },
            {
              "x": 130,
              "y": 150,
              "type": "file"
            }
          ]
        },
        "mac": {
          "icon": "build/icons/icon.png"
        },
        "win": {
          "icon": "build/icons/icon.png"
        },
        "linux": {
          "icon": "build/icons/icon.png"
        },
        "nsis": {
          "oneClick": false,
          "allowToChangeInstallationDirectory": true
        }
    }
}

scripts:

build:打包成exe安装程序

build:dir:打包成文件形式

build:

productName:项目名

copyright:版权

directories:打包目录

win: windows配置。icon为程序图标目录,windows图标至少需要320 x 320,否则报错

nsis:windows安装程序exe配置,如果不配置,那么一键安装至C盘User一个local app目录下,不符合程序使用要求,这里我设置了oneClick:false和allowToChangeInstallationDirectory:true,就是不让程序一键安装,让用户去选择安装目录。

其他如appId,dmg,linux、mac都是macOS和linux系统配置,没有仔细研究

8. CI自动构建发布

travis和appveyor是开源的两个自动化构建平台,免费服务于github等开源项目(不开源项目貌似要给钱)。如果你是在其他这两个CI平台不支持的仓库,可使用其他构建工具,原理相同。

①. 在https://github.com/settings/tokens Generate new token,写上描述,勾上发布权限,生成token。该token只可见一次,注意保存

②. https://www.appveyor.com/注册用户,使用github登录。然后开启该项目的构建。


③. 将第一步生成的token填至项目环境变量,参数名为GH_TOKEN。发布的时候会自动使用GH_TOKEN进行github release api的调用。

④. package.json
{
    "repository": {
        "type": "git",
        "url": "https://github.com/CaanDoll/easy-invoices.git"
    },
    "scripts":{
        "build:ci": "node .electron-vue/build.js && electron-builder --publish always"
    },
}

build:ci:执行后,不仅打包,还会将打包后程序上传,发布成github的release草稿,手动编辑后即可发布。

⑥. appveyor.yml
version: 0.0.{build}

branches:
  only:
    - master

image: Visual Studio 2017
platform:
  - x64

cache:
  - node_modules
  - "%APPDATA%
pm-cache"
  - "%USERPROFILE%.electron"
  - "%USERPROFILE%AppDataLocalYarncache"

init:
  - git config --global core.autocrlf input

install:
  - ps: Install-Product node 8 x64
  - yarn

build_script:
  - yarn build:ci

test: off

version:为构建的版本号,会自增,这个和程序的版本号没有关系

branches:指定在哪个分支进行构建

image:基础镜像,windows程序构建会用到vs

platform:系统位数:如x86(32位),x64(64位)

cache:npm缓存目录

init:初始执行命令,将所有代码换行符改为CRLF模式

install:安装包

build_script:执行命令

接下来提交在github master分支或者merge到master分支(申请merge之后也会触发)就可以触发构建了,在appveyor平台上可以看到。

五、其他一些细节 1.打开系统默认浏览器对应链接或者打开我的电脑对应文件目录

如果使用一般的a标签,会直接将程序的界面跳转至这个链接,因为本身就是浏览器内核。加上target:_blank的话更会没有反应了。这个时候需要调用electron.shell。上面的openExternal(url)方法就是打开浏览器,openItem(path)打开文件目录。

// vue入口文件
// src/renderer/main.js
if (!process.env.IS_WEB) Vue.use(require("vue-electron"));

// 某页面组件xxx.vue
2.导出excel(下载文件)

如果在服务端进行导出,有两个步骤,第一步是将数据填充并生成excel,第二步是将文件发送出去。使用electron本地进行导出也不例外,但因为不是调用http接口,会有一些差异。
nodejs生成excel在这里就不多描述,以后我会补充相应的文章。在这里先推荐这两个库,如果生成的excel比较简单,横行数列并没有任何样式的,可以使用node-xlsx。如果需要生成较为复杂的excel,比如有样式要求,有合并单元格的需求,可以使用ejsExcel。
假设我们已经导出了一个名为test.xlsx的excel在系统临时目录(os.tmpdir()):C:UsersusernameAppDataLocalTempappnametest.xlsx

// src/main/index.js
import { ipcMain } from "electron";
// mainWindow来自new BrowserWindow
ipcMain.on("download", (event, downloadPath) => {
  mainWindow.webContents.downloadURL(downloadPath);// 这个时候会弹出让用户选择下载目录
  mainWindow.webContents.session.once("will-download", (event, item) => {
    item.once("done", (event, state) => {
      // 成功的话 state为completed 取消的话 state为cancelled
      mainWindow.webContents.send("downstate", state);
    });
  });
});

// 渲染进程
ipcRenderer.send("download", "C:UsersusernameAppDataLocalTempappname	est.xlsx");
ipcRenderer.once("downstate", (event, arg) => {
  if (arg === "completed") {
    console.log("下载成功");
  } else if (arg === "cancelled"){
    console.log("下载取消");
  } else {
    console.log("下载失败")
  }
3.窗口相关
① 窗口栏

原生的窗口栏不是那么美观,我们可以去掉原生窗口栏,自己写一个。
主进程

// src/main/index.js
import { BrowserWindow、ipcMain } from "electron";
// 创建窗口时配置
const mainWindow = new BrowserWindow({
    frame: false, // 去掉原生窗口栏
    ...
});

// 主进程监听事件进行窗口最小化、最大化、关闭  
// 窗口最小化
ipcMain.on("min-window", () => {
  mainWindow.minimize();
});
// 窗口最大化
ipcMain.on("max-window", () => {
  if (mainWindow.isMaximized()) {
    mainWindow.restore();
  } else {
    mainWindow.maximize();
  }
});
// 关闭
ipcMain.on("close-window", () => {
  mainWindow.close();
});

头部组件或其他组件,这样就可以在自己定义的元素上去执行窗口操作了

css设置拖拽区域,拖拽区域会自动有双击最大化的功能,注意:拖拽区域内的点击、移入移出等事件将无效,需要将拖拽区域内的按钮等元素设为非拖拽区域即可

    header {
        -webkit-app-region: drag; // 拖拽区域
        .version {
            .ivu-tooltip {
                -webkit-app-region: no-drag; // 非拖拽区域
            }
        }
        .right {
            a {
                -webkit-app-region: no-drag; // 非拖拽区域
            }
        }
    }
② 启动时窗口白屏

程序启动时,界面渲染需要一定时间,导致白屏一下,体验不好。解决方案一种是将程序的背景色设为html的背景色,另外一种就是等界面加载完毕之后再显示窗口,代码如下:
主进程中

// src/main/index.js
import { BrowserWindow} from "electron";
const mainWindow = new BrowserWindow({
    show: false,
    ...
 });
// 加载好html再呈现window,避免白屏
mainWindow.on("ready-to-show", () => {
    mainWindow.show();
    mainWindow.focus();
});
结语

electron非常好玩,它解放了我们在浏览器中开发界面的束缚。C/S架构也有很多不同于功能点需要多多考虑。第一次写比较长的文章,个中可能会有手误或者知识错误,顺序也不是最理想的。欢迎讨论,也请各路大牛多多指教,指出不正!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98829.html

相关文章

  • 【PPic】基于Electron+Vue+iView的图床应用设计

    摘要:其实这个应用并不是那么的特别需求,一来本人写越来越少,二来开发工作也是越做越少,再者目前的编辑器几乎都支持直接剪切板上传图片,使图床应用的场景越来越少。 其实这个应用并不是那么的特别需求,一来本人写blog越来越少,二来开发工作也是越做越少,再者目前的编辑器几乎都支持直接剪切板上传图片,使图床应用的场景越来越少。不过本人本着不想丢弃技术的内心想法,以及锻炼自己写一个完整项目,还是开启了...

    call_me_R 评论0 收藏0
  • 使用 electron-vue 构建你的桌面应用

    摘要:翻译一下它是一个运行时,可以像一样这样执行也是一个使用构建跨平台原生桌面应用的框架。具有两个进程,分别是主进程,以及渲染进程。 什么是 electron 官网里这么说:Electron提供了一个Nodejs的运行时,专注于构建桌面应用,同时使用web页面来作为应用的GUI,你可以将其看作是一个由JavaScript控制的迷你版的Chromium浏览器。 翻译一下:它是一个运行时,可以像...

    qieangel2013 评论0 收藏0
  • vuejs&electron-vue----朝花夕拾.

    摘要:推荐使用使用指定打包位。开发环境跨域代理设置如果是接口,需要配置这个参数如果接口跨域,需要进行这个参数配置通过新窗口打开项目内页面 ————仅以此文记录个人使用vuejs开发项目对一些需求的处理方法,不定期更新... 加载favicon.ico图标 //index.html // build/webpack.dev.conf.js new HtmlWebpackPlugin({ ...

    Awbeci 评论0 收藏0
  • electron-vue静默打印2019最新解决方案(含源码)

    摘要:项目环境代码完成时间废话不多说,先放源码安装依赖运行项目打包项目目录结构先在主进程引入在方法里添加以下代码,获取打印机列表在主线程下,通过对象监听渲染线程传过来的事件在主线程中获取打印机列表通过发送事件到渲染线程,同时将 项目环境 node 10.15.3yarn 1.15.2win10代码完成时间2019-4-18 废话不多说,先放源码 GitHub https://github....

    xzavier 评论0 收藏0
  • K3s初探:Rancher架构师带你尝鲜史上最轻量Kubernetes发行版

    摘要:发布不到两天,上数已近,这个业界大热的史上最轻量的开源发行版,你试过了没资深架构师来教你走出尝鲜第一步使用教程在此前言昨天,正式发布了一款史上最轻量的开源发行版。大小只有,极简,轻便,易于使用。 发布不到两天,GitHub上Star数已近3000,这个业界大热的、史上最轻量的开源Kubernetes发行版,你试过了没? Rancher资深架构师来教你走出尝鲜第一步!使用教程在此! sh...

    neuSnail 评论0 收藏0

发表评论

0条评论

wpw

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<