微信号:frontshow

介绍:InfoQ大前端技术社群:囊括前端、移动、Node全栈一线技术,紧跟业界发展步伐。

基于Vue+Electron构建桌面应用程序实践

2018-10-21 17:28 前端之巅
作者|Natalia Tepluhina
译者|姚佳灵
我在之前的一篇文章中描述了使用 Vuido 的 Vue 框架构建桌面应用。 Vuido是个很棒的库,可以创建具有原生平台组件的快速小型的桌面应用程序,但是,它也有自己的不足之处,例如没有 CSS 样式或图像支持。现在,是时候来试试用 Electron 构建桌面应用程序了。

Electron 是由 GitHub 开发的开源库,用于构建拥有 HTML、CSS 和 JavaScript 的跨平台桌面应用程序。Electron 通过把 Chromium 和 Node.js 组合到一个运行时来实现这一点,并且可以为 Mac、Windows 和 Linux 打包应用程序 。

为了快速入门,我使用了 Greg Holguin 的 electron-vue 样板。它给开发人员提供了 vue-cli scanffolding、常见的 Vue 插件、打包器、测试、开发工具和其他功能。

我们要构建什么?

我们要构建一个跟上一篇文章中所述的一样的应用程序,基于 OpenWeatherMap API 的该应用程序用来查看用户所选择城市的天气情况。

如果只想查看 Electron 支持的应用程序最终代码,请点击这里:

https://github.com/NataliaTepluhina/Vue-Desktop-App/tree/electron

安装

Electron-vue 样板是作为 VueCLI 2.x 的模板构建的,包括自定义应用程序的选项。因此,需要进行全局安装:

npm install -g vue-cli

如果喜欢用 VueCLI 的最新版本,就需要安装全局网桥:

npm install -g @vue/cli @vue/cli-init

然后,初始化你的项目:

vue init simulatedgreg/electron-vue weather-app

这将启动一个安装项目,其中包括需要你做出的几个选择。

其中很酷的是,如果需要一些常用的插件和库,比如 axios,可以在安装过程中选择它们。

几乎所有的选择都很明确,但是有一个问题:

我决定搜索一下,在 StackOverflow 上找到了一个有用的线索。根据这个线索,看起来 electron 构建器(electron-builder)更适合我,因此,我就改用它了。

设置项目后,需要打开应用程序所在的文件夹,运行 npm install 或 yarn install,现在我们准备好了。

了解应用程序结构

安装完成后,可以在 src 中看到两个文件夹 main 和 renderer,Electron 主进程需要用到第一个。

根据 electron-vue 的文档,在 Electron 中运行 package.json 主脚本的进程被称为主进程。在主进程中运行的脚本可以通过创建 web 页面来显示 GUI。

在 main 文件夹中有两个文件:index.js 和 index.dev.js。第一个是你的应用程序的主文件,是 electron 启动用的文件。它也被用做 webpack 的生产入口文件。所有主要的流程工作都应该从这里开始。

而 index.dev.jsis 专门用于开发,因为它安装了 electron-debug 和 vue-devtools。在开发应用程序时,可以不用理睬它。

另外,渲染器(renderer)进程需要 renderer 文件夹。

由于 Electron 使用 Chromium 来显示 web 页面,因此也用到了 Chromium 的多进程架构。Electron 中的每个 web 页面都在自己的进程中运行,这些进程被称为渲染器进程。

正如你可能注意到的是,它是个“正常的”Vue 应用程序结构,拥有 assets 和 components 文件夹:main.js 和 App.vue 文件。这是后者的结构:

<template>
  <div id="app">
    <landing-page></landing-page>
  </div>
</template>

<script>
  import LandingPage from '@/components/LandingPage'

  export default {
    name: 'weather-app',
    components: {
      LandingPage
    }
  }
</script>

<style>
  /* CSS */
</style>

如果尝试运行 dev 任务,将会得到以下结果:

因此,这里有一个登录页面(landing-page)组件,也开启了开发工具(devtools)。现在,我们可以改变它了。

快速构建(scaffolding)应用程序

与 Vuido 不同,Electron 支持的应用程序是用 HTML 标签而不是用本机组件构建的。因此,我们将创建一个与通常的 web 应用程序类似的结构,并用 CSS 来进行样式设计。

请注意:我没有特意安装任何 CSS 框架或组件库:我希望在没有添加任何不同的依赖项的情况下,比较一下包的大小。在两个项目中唯一用到的库是 axios。

第一步是去掉登录页面组件。然后我添加了一个简单的输入字段和一个按钮:

<div id="app">
    <p>Enter the city name to check current weather in it</p>
    <section class="weather-input">
      <input type="text" v-model="query">
      <button :disabled="!query.length">Check</button>
    </section>
</div>

我们在数据中有个查询(query)属性来处理用户输入,我们将把该查询作为参数,进行 API 调用。

进行 API 调用

我使用了 OpenWeatherMap 当前天气 API。它提供很多不同的信息,可以点击这里查看 JSON 响应的示例。

在安装过程中,我们已经将 axios 包含在我们的应用程序中。我们来看看 src/renderer/main.js:

import Vue from 'vue';
import axios from 'axios';
import App from './App';

if (!process.env.IS_WEB) Vue.use(require('vue-electron'));
Vue.http = Vue.prototype.$http = axios;
Vue.config.productionTip = false;

因此,我们可以在组件实例中把 axios 方式用作 this.$http。在这里,我们将只为我们的 API 调用添加一个基本 URL:

axios.defaults.baseURL = 'http://api.openweathermap.org/data/2.5';

现在,在 App.vue 中,我们将创建一组数据属性来显示不同的天气数据:

data() {
    return {
      query: '',
      error: false,
      city: '',
      country: '',
      weatherDescription: '',
      temp: null,
      tempMin: null,
      tempMax: null,
      humidity: null,
      icon: '',
    };
},

与 Vuido 版本相比,我添加了一个额外属性,它是个图标。API 提供天气图标,但是我们无法在 Vuido 应用程序中使用,因为目前不支持显示图像。

我们还创建了一种方法来获取数据:

methods: {
  showWeather() {
    this.$http
      .get(`/weather?q=${this.query}&units=metric&&appid=${API_KEY}`)
      .then(response => {
        this.city = response.data.name;
        this.country = response.data.sys.country;
        this.weatherDescription = response.data.weather[0].description;
        this.temp = response.data.main.temp;
        this.tempMin = response.data.main.temp_min;
        this.tempMax = response.data.main.temp_max;
        this.humidity = response.data.main.humidity;
        this.icon = `http://openweathermap.org/img/w/${
          response.data.weather[0].icon
        }.png`;
        this.error = false;
      })
      .catch(() => {
        this.error = true;
        this.city = '';
      });
  },
},

并把它添加到按钮的单击回调中:

<button :disabled="!query.length" @click="showWeather">Check</button>

现在,如果在输入字段输入文本,单击按钮,就可以在“网络(Network)” 选项卡上观察 API 调用:

显示天气数据

我们把这些数据添加到模板上:

<template>
  <main id="app">
    <p>Enter the city name to check current weather in it</p>
    <section class="weather-input">
      <input type="text" v-model="query">
      <button :disabled="!query.length" @click="showWeather">Check</button>
    </section>
    <section v-if="error" class="weather-error">
      There is no such city in the database
    </section>
    <section v-if="city.length" class="weather-result">
      <h1>{{city}}, {{country}}</h1>
      <p><em>{{weatherDescription}}</em></p>
      <div class="weather-result__main">
        <img :src="icon" alt="Weather icon">
        <div class="weather-result__temp">
          {{temp}}&deg;C
        </div>
      </div>
      <div class="weather-result__details">
        <p>Min: {{tempMin}}&deg;C</p>
        <p>Max: {{tempMax}}&deg;C</p>
        <p>Humidity: {{humidity}}%</p>
      </div>
    </section>
  </main>
</template>

我们的应用程序视图:

太棒了,我们能看到真实的天气状况了!但是,它看起来像是 1999 年的……我们给它添加点 CSS 魔法吧(事实上,是很多 CSS 魔法)!

<style lang="scss">
* {
  margin: 0;
  padding: 0;
}
html,
body,
#app {
  height: 100%;
}

#app {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 16px;
  padding: 10px;
  background: rgb(212, 228, 239);
  background: -moz-radial-gradient(
    center,
    ellipse cover,
    rgba(212, 228, 239, 1) 0%,
    rgba(134, 174, 204, 1) 100%
  );
  background: -webkit-radial-gradient(
    center,
    ellipse cover,
    rgba(212, 228, 239, 1) 0%,
    rgba(134, 174, 204, 1) 100%
  );
  background: radial-gradient(
    ellipse at center,
    rgba(212, 228, 239, 1) 0%,
    rgba(134, 174, 204, 1) 100%
  );
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d4e4ef', endColorstr='#86aecc',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
}

.weather-input {
  display: flex;
  align-items: center;
  padding: 20px 0;
}

.weather-result {
  text-align: center;
  &__main {
    display: flex;
    align-items: center;
    justify-content: center;
    padding-top: 5px;
    font-size: 1.3rem;
    font-weight: bold;
  }
  &__details {
    display: flex;
    align-items: center;
    justify-content: space-around;
    color: dimgray;
  }
}

.weather-error {
  color: red;
  font-weight: bold;
}

input {
  width: 75%;
  outline: none;
  height: 20px;
  font-size: 0.8rem;
}

button {
  display: block;
  width: 25%;
  height: 25px;
  outline: none;
  border-radius: 5px;
  white-space: nowrap;
  margin: 0 10px;
  font-size: 0.8rem;
}
</style>

最终,我们拥有了这个美妙的全功能应用程序:

在打包之前,最后要做的事是把它的尺寸缩小到窗口大小。如果我们查看一下 src/main/index.js 文件,可以找到它的设置选项:

mainWindow = new BrowserWindow({
    height: 563,
    useContentSize: true,
    width: 1000
})

我们把宽度改为 450,高度改为 250。

 打 包 

你可以把你的应用程序构建为 web 应用程序了!如果运行 build:web 任务,可以在 dist 文件夹中找到构建 web 应用程序。

但是,让我们回到我们的桌面应用程序并运行构建任务。结果,你在构建文件夹中会有一个文件夹,该文件夹的名字是根据你的平台命名的(对我而言是 mac),里面有一个应用程序文件。它的大小是 133Mb!

对于这么小的应用程序来说,这文件太大了。另外,如果运行一下,你就会注意到,它的启动比 Vuido 支持的应用程序慢。

最终的样子:

结  论

优点:

  • 容易上手;

  • 出色的文档;

  • 提供 web 应用程序构建;

  • 可以通过 CSS 样式自定义。

缺点:

  • 打包后的文件超大;

  • 比用本机 GUI 组件构建的应用程序速度慢;

  • 如果你的应用程序需要独特的外观,并且你不在乎;

  • 打包后的文件大小和性能,那么,Electron-vue 是个不错的选择。

更新

如果你的 web 应用程序是用 Vue CLI 3 构建的,则可以用 Vue CLI 插件 Electron Builder 把它简化成桌面应用程序。你只需在项目根文件夹中运行以下命令:

vue add electron-builder

运行结束后,你将会拥有两个额外的 npm 任务:serve:electron 和 build:electron,与桌面应用程序一起工作。

 英文原文

https://dev.to/vuevixens/building-a-desktop-app-with-vue-electron-3pl?utm_source=mybridge&utm_medium=blog&utm_campaign=read_more

 活动推荐

今年12 月 7-8 日在北京国际会议中心举办的 ArchSummit 全球架构师技术峰会邀请了超过百位的国内外专业讲师,并设置了前端技术专题,分享他们的最新黑科技和研发经验。

目前大会 8 折优惠购票火热进行中,扫描以下图片二维码或点击“阅读原文”了解更多详情!

如有疑问欢迎咨询票务经理灰灰:17326843116(微信同号)


 
前端之巅 更多文章 每个Web开发者都应该知道的SOLID原则 Angular 7.0发布,带来CLI Prompts、虚拟滚动和拖放等特性 ECMAScript 2016\/2017\/2018新特性详解 Chrome 70正式版发布:Windows端将支持PWA Mozilla是如何提升JS和WASM之间的调用速度的?
猜您喜欢 编写更好的CSS代码 大数据全栈式开发语言 – Python 在一起,梦飞扬,共建开发者云生态 MBH数据标定平台业务——金融数据清洗 极客帮创投创始合伙人王峰:每选择一次新活法 就更靠近自由