Створення десктопного застосунку з Vue: Electron

11 хв. читання
16 листопада 2018

Створимо застосунок для перевірки погоди у місті за вибором користувача на основі API OpenWeatherMap.

Інструментарій:

Щоб швидко розпочати, використаємо electron-vue – шаблон, що надає vue-cli, базові Vue плагіни, пакувальник, тестування, інструменти розробника й інші функції.

Встановлення

Шаблон 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

Це запустить встановлення проекту з декількома опціями, між якими необхідно обрати:

Створення десктопного застосунку з Vue: Electron

Крутіше всього те, що якщо вам потрібні якісь розповсюджені плагіни та бібліотеки, такі як axios, ви можете вибрати їх під час встановлення.

Практично всі вибори були зрозумілі, окрім одного:

Створення десктопного застосунку з Vue: Electron

Згідно цього треду, схоже, що electron-builder виявився кращим вибором, тому оберемо його.

Після встановлення вам потрібно перейти до теки проекту й запустити npm install або yarn install. Ми готові розпочати

Розуміння структури застосунку

Одразу після встановлення всередині src ви можете помітити дві теки: main та renderer. Перша є необхідною для головного процесу Electron.

Згідно з документацією electron-vue, процес, що запускає головний скрипт package.json, називається головним процесом. Скрипт, який запускається в головному процесі, може відображати GUI, створюючи веб-сторінки.

У теці main є два файли: index.js та index.dev.js. Перший — головний файл вашого застосунку, в якому завантажується electron. Він також використовується як вхідний файл webpack для продакшена. Вся робота головного процесу має починатися тут.

index.dev.js використовується спеціально і тільки для розробки, оскільки він встановлює electron-debug та vue-devtools. Вам не потрібно взаємодіяти з ним під час розробки застосунку.

Тека renderer необхідна для процесу renderer.

Оскільки Electron використовує Chromium для відображення веб-сторінок, також використовується його мультипроцесорна архітектура. Кожна веб-сторінка в Electron працює у власному процесі, який називається процесом рендерингу.

Як можна помітити, це «нормальна» структура 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>

І якщо ми спробуємо виконати npm run dev, то отримаємо наступний результат:

Створення десктопного застосунку з Vue: Electron

Таким чином, є компонент landing-page, а також інструменти розробника. Тепер можна почати його змінювати!

Каркас застосунку

На відміну від Vuido, застосунок на основі Electron побудований на основі HTML-тегів, а не нативних компонентів. Тому ми створимо структуру, подібну до звичайного веб-застосунку й використаємо для стилів CSS.

Примітка: ніякі CSS фреймворки або бібліотеки компонентів не застосовуються. Єдина бібліотека, яка використовується — axios.

Спершу позбавимося компоненту landing-page. А потім додамо просте поле вводу й кнопку:

<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>

Тепер наш застосунок виглядає наступним чином:

Створення десктопного застосунку з Vue: Electron

У нас в даних є властивість 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 в екземплярі компоненту. Єдина річ, яку ми тут додамо — базова URL для викликів API:

axios.defaults.baseURL = 'https://web.archive.org/web/20230608175930/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: '',
    };
},

Створімо також метод для вилучення наших даних:

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>

Тепер якщо ви введете текст у поле вводу й натиснете кнопку, то побачите виклик API у вкладці Network:

Створення десктопного застосунку з Vue: Electron

Відображення погодних даних

Додамо ці дані у шаблон:

<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}}°C
        </div>
      </div>
      <div class="weather-result__details">
        <p>Min: {{tempMin}}°C</p>
        <p>Max: {{tempMax}}°C</p>
        <p>Humidity: {{humidity}}%</p>
      </div>
    </section>
  </main>
</template>

Вигляд нашого застосунку:

Створення десктопного застосунку з Vue: Electron

Чудово, ми можемо бачити поточну погоду. Але все виглядає так, наче це 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>

І нарешті у нас є хороший повнофункціональний застосунок:

Створення десктопного застосунку з Vue: Electron

Останнє, що потрібно зробити перед пакуванням — зменшити розмір вікна. Якщо ми переглянемо файл src/main/index.js, то знайдемо в ньому налаштування для вікна:

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

Змінімо ширину на 450 й висоту на 250.

Пакування

Чудові новини: ви можете зробити свій застосунок веб-застосунком. Якщо ви запустите задачу build:web, то знайдете збірку веб-застосунку у теці dist.

Але повернімося до нашого десктопного застосунку й запустімо задачу build. В результаті ви матимете теку, названу як ваша платформа, всередині теки build (наприклад, mac) й файл застосунку у ній. А її розмір складає аж 133 Мб!

Створення десктопного застосунку з Vue: Electron

Остаточний вигляд:

Створення десктопного застосунку з Vue: Electron

Висновки

Плюси:

  • легко розпочати;
  • хороша документація;
  • надає можливість створення веб-застосунку;
  • може бути кастомізований за допомогою CSS.

Мінуси:

  • дуже великий розмір пакету;
  • повільніший за застосунок, створений за допомогою нативних компонентів GUI;

Electron-vue — хороший варіант, якщо ваш застосунок потребує унікального вигляду й вас мало хвилює розмір пакету й продуктивність.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.6K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація