Electron 集成 Vue & Vuetify 开发应用
Electron 集成 Vue & Vuetify 开发应用
由于electron能够用 Nodejs 编写跨平台系统的应用软件,目标系统包括 windows、MacOs、Linux 这三大主流操作系统,因此能够省去大量的跨端开发工作。更因为能够重用 Vue 组件,因此可以编写出与 WEB 端媲美的漂亮界面,而且组件的重用更是大大的提高了开发的效率。
VS code 作为优秀的跨平台编辑器也是前端开发不可或缺的,本次开发演示的主力编辑器。
一、项目初始化
要electron支持Vue开发,需要做不少繁琐的配置工作,好在vue-cli的出现,使得我们可以使用现成的模板进行项目骨架的搭建。
这里使用的是 simulatedgreg/electron-vue 这个项目模板。该项目模板的文档位于https://simulatedgreg.gitbooks.io/electron-vue/content/cn/getting_started.html。
在终端窗口输入如下命令进行项目初始化
vue init simulatedgreg/electron-vue admin
注意:如果你使用的是 vue-cli 3 的话,需要全局安装 vue-init 才行。
yarn global add @vue/cli vue-init
二、安装依赖包
进入项目目录
cd admin
在终端窗口输入如下命令进行项目初始化
yarn
在安装依赖包的时候,因为要下载的electron依赖包较大,因此需要使用国内的镜像源,否则会因为国外站点太慢而卡在那里不动! 使用淘宝上ELECTRON_MIRROR进行依赖包的安装。 因此在 MacOs 上的依赖包安装命令如下:
ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron/ yarn
此时工程已经初始化完成。
三、运行工程
在工程文件夹内执行如下命令运行
yarn dev
在 MacBook 上本地运行,程序的截图如下:
四、使用 Vuetify 定制界面
Vue 界面组件Vuetify作为Material Design的实现对各个终端具有良好的兼容性。 本文以 Vuetify 为例,其过程与方法同样适用于ElementUI等前端框架。
1. 引入 Vuetify
在终端窗口使用如下命令添加 Vuetify 的依赖,也可以参照Vuetify 快速开始:
yarn add vuetify
使用 VS Code 打开工程文件夹根目录,项目目录结构如下图所示:
打开 src/main.js 添加 Vuetify 的引用
import Vue from "vue";
import axios from "axios";
import App from "./App";
import router from "./router";
import store from "./store";
//引入Vuetify及样式
import "vuetify/dist/vuetify.min.css";
import Vuetify from "vuetify";
Vue.use(Vuetify);
//
if (!process.env.IS_WEB) Vue.use(require("vue-electron"));
Vue.http = Vue.prototype.$http = axios;
Vue.config.productionTip = false;
打开src/renderer/components/LandingPage.vue
将 template 部分修改成如下:
<template>
<div>
<v-toolbar dark color="primary">
<v-toolbar-side-icon></v-toolbar-side-icon>
<v-toolbar-title class="white--text">Vuetify Adminstrator</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon>
<v-icon>search</v-icon>
</v-btn>
<v-btn icon>
<v-icon>apps</v-icon>
</v-btn>
<v-btn icon>
<v-icon>refresh</v-icon>
</v-btn>
<v-btn icon>
<v-icon>more_vert</v-icon>
</v-btn>
</v-toolbar>
<main>
<v-layout row>
<v-flex xs12 sm6>
<v-card>
<v-toolbar color="cyan" dark>
<v-toolbar-side-icon></v-toolbar-side-icon>
<v-toolbar-title>Inbox</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon>
<v-icon>search</v-icon>
</v-btn>
</v-toolbar>
<v-list two-line>
<template v-for="(item, index) in items">
<v-subheader v-if="item.header" :key="item.header"> {{ item.header }} </v-subheader>
<v-divider v-else-if="item.divider" :inset="item.inset" :key="index"></v-divider>
<v-list-tile v-else :key="item.title" avatar>
<v-list-tile-avatar>
<img :src="item.avatar" />
</v-list-tile-avatar>
<v-list-tile-content>
<v-list-tile-title v-html="item.title"></v-list-tile-title>
<v-list-tile-sub-title v-html="item.subtitle"></v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
</template>
</v-list>
</v-card>
</v-flex>
</v-layout>
</main>
</div>
</template>
<script>
import SystemInformation from "./LandingPage/SystemInformation";
export default {
name: "landing-page",
components: { SystemInformation },
data() {
return {
items: [
{ header: "Today" },
{
avatar: "https://cdn.vuetifyjs.com/images/lists/1.jpg",
title: "Brunch this weekend?",
subtitle:
"<span class='text--primary'>Ali Connors</span> — I'll be in your neighborhood doing errands this weekend. Do you want to hang out?",
},
{ divider: true, inset: true },
{
avatar: "https://cdn.vuetifyjs.com/images/lists/2.jpg",
title: 'Summer BBQ <span class="grey--text text--lighten-1">4</span>',
subtitle: "<span class='text--primary'>to Alex, Scott, Jennifer</span> — Wish I could come, but I'm out of town this weekend.",
},
{ divider: true, inset: true },
{
avatar: "https://cdn.vuetifyjs.com/images/lists/3.jpg",
title: "Oui oui",
subtitle: "<span class='text--primary'>Sandra Adams</span> — Do you have Paris recommendations? Have you ever been?",
},
],
};
},
methods: {
open(link) {
this.$electron.shell.openExternal(link);
},
},
};
</script>
<style>
@import url("https://fonts.cat.net/css?family=Roboto:100,300,400,500,700,900|Material+Icons");
#wrapper {
height: 100vh;
padding: 60px 80px;
width: 100vw;
}
#logo {
height: auto;
margin: 20px;
width: 420px;
}
</style>
2.修正运行时脚本错误
运行后发现调试控制台有 javascript 脚本错误发生,并且看起来界面有些错乱。
[Vuetify] Multiple instances of Vue
如下图所示:
经查得知是 electron 与 vuetify 集成时由于 electron 安全机制的原因导致没有正确引入 Vuetify 的 js 文件。参见:https://github.com/vuetifyjs/vuetify/issues/4068 ,相应的解决办法是:https://github.com/appurist/electrify/blob/master/.electron-vue/webpack.renderer.config.js#L21,即将.electron-vue/webpack.renderer.config.js
的第 22 行的
//原来的引入模块白名单列表内只有vue
//let whiteListedModules = ['vue']
//将Vuetify加入引入模块的白名单后
let whiteListedModules = ["vue", "vuetify"];
重新运行应用,成功得到想要的漂亮界面!
五、安装 Vue-DevTools 调试插件
默认情况下在 MacOs 中,你需要先在 Chrome 中安装 Vue-DevTools 插件。其默认的安装位置在:
/Users/**CurrentUsername**/Library/Application Support/Google/Chrome/Default/Extensions/nhdogjmejiglipccpnnnanhbledajbpd
我使用的是 4.1.5,故而实际路径为:
/Users/demo-user/Library/Application Support/Google/Chrome/Default/Extensions/nhdogjmejiglipccpnnnanhbledajbpd/4.1.5_0
将如下代码添加到 src/main/index.js 的 createWindow 函数中
if (process.env.NODE_ENV === "development") {
let chromeDir = "/Users/demo-user/Library/Application Support/Google/Chrome/Default";
let location = `${chromeDir}/Extensions/nhdogjmejiglipccpnnnanhbledajbpd/4.1.5_0`;
BrowserWindow.addDevToolsExtension(location);
}
完整的函数代码如下:
function createWindow() {
/**
* Initial window options
*/
if (process.env.NODE_ENV === "development") {
let chromeDir = "/Users/demo-user/Library/Application Support/Google/Chrome/Default";
let location = `${chromeDir}/Extensions/nhdogjmejiglipccpnnnanhbledajbpd/4.1.5_0`;
BrowserWindow.addDevToolsExtension(location);
}
mainWindow = new BrowserWindow({
height: 563,
useContentSize: true,
width: 1000,
webPreferences: {},
});
mainWindow.loadURL(winURL);
mainWindow.on("closed", () => {
mainWindow = null;
});
}
重新运行程序,即可看到 Vue-DevTools 已经可用了。
至此在 MacBookPro 上的 Electron 集成 Vue & Vuetify Demo 开发初步完成!