Кажется, дождь собирается. Пишем приложение для отслеживания прогноза погоды

59cqnoqz_vihyggn8jz8xijhfz8.jpeg


В статье рассмотрим, как сделать простое приложение погоды без дизайн-макета‎. Поработаем с HTML, CSS, JavaScript, Vue, Vite, подключением API, а также развернем проект на облачном сервере. Подробности под катом!

Используйте навигацию, если не хотите читать текст полностью:

→ Начало работы с Vite
→ Верстка приложения
→ Подготовка фреймворка Vue
→ Деплой проекта
→ Заключение

Начало работы с Vite


В качестве инструмента сборки будем использовать Vite. С его помощью мы легко запустим любой JavaScript-фреймворк.

Первым шагом установим Vite. Создаем папку на компьютере, которая будет сохранять данные проекта, и переносим ее в редактор кода VS Code. Далее открываем терминал и вводим код, чтобы создать проект из шаблона:

npm create vite@latest


Теперь добавим в проект необходимые пакеты. Для этого нужно дать согласие системе — пишем «y» и нажимаем Enter.

В ответ получаем конфигурационные файлы и строку Project name. В ней указываем имя будущего проекта. У меня — weather, но можно назвать по-другому. Нажимаем Enter, чтобы продолжить установку.

Далее выбираем необходимый фреймворк и язык программирования. В нашем случае — Vue и JavaScript.

6b911fd748be451c6a6a74feeaea68b5.png


be0c3c71edc6cf208ddcc9914859bf2d.png


После — вводим в терминал три команды, чтобы начать работу над проектом:

cd weather
npm install
npm run dev


В результате получаем ссылку localhost. Переходим по ней и видим стандартную страницу:

48a06da65562e0a06a5f31f9fc23f40d.png


nblot_ve1t3hcw5bluwc_-did08.png

Верстка приложения


На странице Vite и Vue нужно убрать все лишнее, заполнить ее разметкой и стилями будущего проекта. Это поможет понять, как он будет выглядеть и с какими элементами нам придется работать.

Сейчас проект состоит из следующих файлов и папок:

1a7b77e3517820ac26f71f5977de18bd.png


Обратите внимание на папку src — именно с ней мы будем работать. При этом все изменения данных будут отражаться в браузере в момент разработки.

Внутри src есть две папки — assets и components. Поскольку мы делаем простое приложение, предлагаю удалить последнюю папку и ее содержимое. На реальных проектах этого делать не рекомендую, но в нашем случае она ни на что не повлияет. В assets удаляем лишнее изображение формата svg. Саму папку не трогаем.

Далее открываем файл App.vue, в котором отражены ошибки. Они появились из-за того, что мы удалили папку components. Нам внутреннее содержимое файла не потребуется, поэтому просто удалим его. В результате файл должен быть пустым.

Теперь переходим к созданию разметки. Указываем основные теги template, внутрь добавляем div с классом weather и ниже размещаем скрипт:





В div добавляем класс с контейнером, чтобы разместить поисковую строку, кнопку и информацию о погоде. Ниже — класс weather-bg для хранения изображений.



Заранее сохраняем картинку, которая будет отображаться при загрузке приложения. Для остальных описываем разные состояния погоды. За основу возьмем overcats (пасмурно), partly cloudy (переменная облачность) и sunny (солнечно). Подходящие фоны можно найти на любом сервисе стоковых изображений.

Все изображения переносим в папку assets. В файл style.css добавляем основные стили. Подключаем шрифт, прописываем переменные и указываем стандартные сбросы.

@import url('https://fonts.googleapis.com/css2?family=Karla:ital,wght@0,200..800;1,200..800&display=swap');

:root {
 --font: "Karla", sans-serif;

 --accent: #12C0DD;
 --accent-rgb: 18, 192, 221;
 --light: #FFFFFF;

 --border-radius: 10px;
 --width-line: 2px;
 --tr: .3s;
}

* {
 margin: 0;
 padding: 0;
}

body, html {
 height: 100vh;
}

body {
 font-family: var(--font);
 height: 100%;
}

input, button {
 font-family: var(--font);
}

#app {
 height: 100%;
}


Далее стилизуем блок с контентом. Центрируем его посередине экрана, указываем возможность изменения фона и прописываем функцию добавления классов, чтобы они могли меняться в зависимости от типа погоды.

Основные стили:

.weather {
 width: 100%;
 height: 100%;
 display: flex;
 flex-direction: column;
 align-items: center;
 justify-content: center;
 position: relative;
 overflow: hidden;
}

.weather-bg {
 position: absolute;
 left: 0;
 right: 0;
 top: 0;
 margin: 0 auto;
 width: 100%;
 height: 100%;
 z-index: -1;
}

.weather-bg > div {
 width: 100%;
 height: 100%;
 position: relative;
 overflow: hidden;
}


Основные стили для изображений:

.weather-bg__img {
 width: 100%;
 height: 100%;
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
 object-fit: cover;
 opacity: 0;
 transition: var(--tr) ease-in-out;
}


Стиль для основного фона:

.weather .weather-bg__img.bg {
 opacity: 1;
}


Стиль для разных типов погоды. Для примера рассмотрим солнечную (sunny), но вы можете установить несколько вариантов и подобрать несколько состояний — вместо sunny нужно будет записать другие варианты:

.weather.sunny .weather-bg__img:not(.sunny) {
 opacity: 0;
}

.weather.sunny .weather-bg__img.sunny {
 opacity: 1;
}
.container {
 width: 100%;
 max-width: 1000px;
 margin: 0 auto;
 padding-left: 15px;
 padding-right: 15px;
 display: grid;
 grid-template-columns: 1fr 100px 200px;
 gap: 20px;
 box-sizing: border-box;
}

.card {
 background-color: var(--light);
 border-radius: var(--border-radius);
 padding: 20px 30px;
 box-sizing: border-box;
}

.weather-form {
 display: flex;
 align-items: stretch;
 gap: 20px;
}
.weather-form__input {
 flex-grow: 1;
 font-size: 20px;
 border: var(--width-line) solid rgba(var(--accent-rgb), .3);
 border-radius: var(--border-radius);
 padding: 10px 15px;
 box-sizing: border-box;
 transition: var(--tr);
}

.weather-form__input:focus {
 outline: none;
 border-color: var(--accent);
}

.weather-form__btn {
 flex-basis: 180px;
 font-size: 20px;
 background-color: rgba(var(--accent-rgb), .3);
 border: none;
 border-radius: var(--border-radius);
 padding: 10px 15px;
 box-sizing: border-box;
 cursor: pointer;
 transition: var(--tr);
}

.weather-form__btn:hover {
 background-color: var(--accent);
}
.weather-form,
.weather-load,
.weather-info {
 grid-column: 1 / 4;
}

.weather-load {
 display: flex;
 align-items: center;
 height: 87px;
}

.weather-info__text {
 display: grid;
 grid-template-columns: 1fr auto auto;
 gap: 20px;
 font-size: 40px;
}


Подготовка фреймворка Vue


Ранее мы запустили инструмент сборки Vite. Вся структура приложения уже подготовлена за нас. Осталось внести изменения в разметку и дописать скрипты.

Информацию о погоде будем получать из реальных источников. Для этого воспользуемся любым бесплатным API. В нашем случае — Weather API.

Переходим на сайт и авторизируемся, чтобы получить ключ для работы с API. Открываем файл App.vue. Нас интересует блок:



В нем прописываем основную структуру кода.

  • В data будем управлять полученными данными.
  • В computed пропишем изменения фона приложений, в зависимости от типа погоды.
  • В methods подключим API и изменения в работе приложения.


Чтобы передавать приложению погодные характеристики из API, нужно открыть доступ к изменению данных. Для этого используем интерполяцию. В div указываем названия необходимых значений, а в script добавляем функцию, которая возвращает их в объект данных, data ().

{{ location }}

{{ temperature }}°C

{{ description }}

data() {
   return {
     location: '',
     temperature: 0,
     description: '',
   };
 }


Указываем в элементах интерфейса input и button связь функций. В директиву v-model добавляем переменную searchQuery.




data() {
   return {
     location: '',
     temperature: 0,
     description: '',
     searchQuery: '',
   };
 }


Подключаем API для сбора данных о погоде и добавляем два условия. Сначала необходимо обработать поисковый запрос, затем — сбросить введенную фразу из .

methods: {
   weatherSearch() {
     this.loading = true;
     this.error = false;
     fetch(`https://api.weatherapi.com/v1/current.json?key=69ed7b91ab4b4d4f9f282327242604&q=${this.searchQuery}`)
       .then(response => response.json())
       .then(data => {
         this.loading = false;
         this.location = data.location.name;
         this.temperature = data.current.temp_c;
         this.description = data.current.condition.text;
         this.resetSearchQuery();
       })
       .catch(error => {
         this.loading = false;
         this.error = true;
         console.error(error);
       });
   },
   resetSearchQuery() {
     this.searchQuery = '';
   }
 }


Поскольку в catch указаны значения loading и error, их также необходимо добавить в ветку data (). Это позволит отображать строку загрузки и планировать вывод ошибок на случай, если API перестанет обрабатывать данные через поиск.

data() {
   return {
     location: '',
     temperature: 0,
     description: '',
     searchQuery: '',
     loading: false,
     error: false,
   };
 }
...
...
...


Для изменения фона добавим : class в div, куда установлен класс weather.


Далее пишем функцию, после которой появятся дополнительные классы напротив div. И это только в том случае, если в {{ description }} отображается соответствующее описание.

Напомню, что мы описывали только три состояния погоды, но таких значений может быть больше. Не забудьте подготовить фоны для каждого нового состояния.

computed: {
   weatherClass() {
     if (this.description.includes('Sunny')) {
       return 'sunny';
     } else if (this.description.includes('Overcast')) {
       return 'overcast';
     } else if (this.description.includes('Partly cloudy')) {
       return 'partly-cloudy';
     } else {
       return '';
     }
   }
 },


Финальный шаг — создаем приложение:

npm run build


Готово, мы сделали простое приложение по прогнозу погоды с нуля!

Деплой проекта


Сейчас готовый результат не увидит никто, кроме нас. Чтобы это исправить, перенесем его на облачный сервер Selectel.

В файле vite.config.js добавляем строку base: './' внутри export default defineConfig ({ … }). Это позволит в build проекта отразить верные пути файлов.

eddd06dfd87ca1bb843446a8cece1ec1.png


Вводим в терминале команду npm run build, после которой появится папка dist. В ней будут формироваться итоговые данные проекта. Файлы оттуда выгрузим на облачный сервер.

В панели управления нужно создать аккаунт или авторизоваться, если у вас уже есть учетная запись. Внутри выбираем Облачная платформа и нажимаем Создать сервер.

7b8923545e051de0a2d2bab1acdabed5.png


В настройках указываем имя проекта и устанавливаем минимальную конфигурацию. Для работы нашего приложения много мощностей не нужно.

e2b3cccf5dacedf7c1cd8f46ba6503c9.png


9695027aaa534d8e47e24d1ab085cdf4.png


eb71197b17d6a4f9da58729a74db37f7.png


После установки конфигурации спускаемся вниз и нажимаем Создать.

Возвращаемся в панель управления и переходим в консоль созданного сервера. Для входа нужен логин (root) и пароль. Нажимаем ЛКМ по иконке Горячие клавиши и добавляем сгенерированный пароль.

1e672dcd7b77980ba2a32c062343841e.png


В терминале вводим набор команд, чтобы загружать файлы на облачный сервер по FTP-протоколу.

1. Устанавливаем FTP-сервер (vsftpd):

sudo apt update
sudo apt install vsftpd


2. Настраиваем доступ. Для этого редактируем файл конфигурации FTP-сервера:

sudo nano /etc/vsftpd.conf


3. Проверяем параметры конфигурации. Они должны быть установлены или раскомментированы и иметь указанные значения:

anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES


4. Перезапускаем сервис:

sudo systemctl restart vsftpd


5. Открываем порты в файрволе, если необходимо:

sudo ufw allow ftp


6. Проверяем статус сервиса:

sudo systemctl status vsftpd


С помощью IP-адреса, имени пользователя и пароля вы можете войти в FTP-клиент, чтобы подключить приложение к FTP-серверу. Остается только перенести туда готовые файлы из папки dist.

Готово! Сайт доступен по адресу 46.148.229.29:

48e5b68279b2c3ae110e6b76285df930.png


Заключение


В инструкции наглядно показали, как создать простое приложение для мониторинга погоды. Не бойтесь с ним экспериментировать — добавлять новые функции и улучшать дизайн. Это поможет прокачать навыки и пополнить портфолио новыми проектами.

А чтобы снизить затраты на обслуживание приложения, советуем присмотреться к виртуальной машине из линейки Shared Line. Оплата производится только за потребленные мощности по модели pay-as-you-go.

Автор: Анна Блок, автор YouTube-канала.

Habrahabr.ru прочитано 3097 раз