Игра Яндекс Практикума
Игра Яндекс Практикума
Игра Яндекс Практикума

Приложение для прогноза погоды на Vue JS

В данной статье описывается созданный Vue JS проект для извлечения данных о погоде на основе местоположения, которое задает пользователь.

1К открытий6К показов

Первоначальная настройка приложенияя

Ознакомление с созданным приложением предполагает наличие предварительных знаний о фреймворке Vue.js.

Сайт прогноза погоды создавался с помощью использования фреймворка Vue 3. Предварительно устанавливается Vue CLI, который позволяет быстро создать шаблон нового проекта. Среда разработки - Visual Studio Code.

Данные о погоде получаются с помощью API сервиса OpenWeatherMap, который позволяет использовать некоторый функционал бесплатно. Для того, чтобы показать на карте местоположение, подключается OpenStreetMap – бесплатная карта всего мира.

Интерфейс пользователя

Интерфейс пользователя состоит из: текстового поля поиска местоположения, визуальной карты, где показывается найденный город и в правой части экрана данные о прогнозе погоды. Прогноз погоды можно увидеть на данный момент, на сегодня и на ближайшие 5 дней.

Приложение для прогноза погоды на Vue JS 1
Основной интерфейс

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

Приложение для прогноза погоды на Vue JS 2
Фильтр поиска местоположения

Структура проекта

После открытия данного проекта с помощью редактора кода, будет видна следующая структура:

Приложение для прогноза погоды на Vue JS 3
Структура Vue проекта

Пояснение к наиболее важным файлам и папкам:

  • src – основной код проекта
  • папка js – javascript – файлы, содержащие повторяющиеся функции, методы и миксины в проекте
  • node_modules – исходный код, подключенных библиотек и сервисов проекта

Основные файлы папки src:

  • App.vue – корневой компонент интерфейса, в нем отображаются все остальные компоненты и страницы
  • main.js – файл, который монтирует и собирает приложение
  • components – папка, где находятся компоненты для создания пользовательского интерфейса
  • pages – здесь содержатся компоненты маршрутизации, к которым происходит навигация
  • router – содержит файл router.js, который описывает правила построения маршрутов к компонентам в папке pages

Сторонние библиотеки, ресурсы, используемые в приложении

Получение списка стран, городов, населенных пунктов

В Интернете существует множество различных сервисов для получения списка стран и городов мира, большинство из них являются платными. В данном проекте создан CSV-файл с населёнными пунктами на основе списка ООН для экономической торговли.

Список ООН можно найти по ссылке https://unece.org/trade/uncefact/unlocode. Здесь можно получить список в различных форматах: csv, txt, mdb. Данные в этих файлах представлены в формате UN/LOCODE — международной системе классификации географических объектов. Необходимые данные из этих файлов для проекта: коды стран согласно ISO 3166-1 alpha-2, наименование населенного пункта и координаты.

Столбец географических координат местоположения содержит широту/долготу, если таковые имеются. Используется следующее стандартное представление:  0000lat 00000long (lat - широта: N или S ; long - долгота: W или E)

Библиотека Papa Parse

Для обработки полученных данных из CSV-файла городов и стран, в проекте используется библиотека Papa Parse, доступная по ссылке https://www.papaparse.com/. Данная библиотека позволяет как считывать и обрабатывать данные из CSV, так и преобразовывать информацию к CSV-формату. Ее можно установить с помощью следующей команды npm:

			npm install papaparse
		

Пример асинхронной функции получения данных из CSV в компоненте CountriesCodes.vue:

			async parseCSV(fileCSV) {
    return new Promise(resolve => {
        Papa.parse(fileCSV, {
            header: false,
            download: true,
            complete: (results) => {
                resolve(results.data);
            }
        });
    });
}

		

Сервис OpenWeatherMap

OpenWeatherMap – интернет сервис для предоставления API получения данных о погоде. В основном сервис платный, но есть и ограниченный бесплатный функционал.

Чтобы начать пользоваться API, необходимо перейти по ссылке https://openweathermap.org/, создать учетную запись и получить свой API-ключ. Согласно документации, бесплатно можно получить прогноз на текущий момент и прогноз на 5 дней в 3-х часовом формате.

Получить географические координаты для прогноза возможно, используя следующие подходы: вызов API по географическим координатам – широте и долготе, вызов API по идентификатору города.

Вызов API: https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}. Возвращаемые данные можно получить в XML или JSON формате.

Документация по вызову API

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

Пример геокодирования: api.openweathermap.org/data/2.5/forecast?q={city name}&appid={API key}

Пример подключения к OpenWeatherMap и получения данных можно найти в основном компоненте App.vue:

			async isFoundLocation(place, code) {
    if (place != '' && code != '') {
        // forecast type for today and 5 days
        let openWeatherType = '';
        if (this.forecastType == this.forecastTypes.now) {
            openWeatherType = 'https://api.openweathermap.org/data/2.5/weather?q=' + place + ',' + code + '&appid=' + this.weatherApi + "&lang=ru";
        }
        else {
            openWeatherType = 'https://api.openweathermap.org/data/2.5/forecast?q=' + place + ',' + code + '&appid=' + this.weatherApi + "&lang=ru";
        }
        return await fetch(openWeatherType)
            .then(res => res.json())
            .then(data => {
                …
                    return data;
            })
    }
…
}, //isFoundLocation

		

Параметры place, code передаются из  CountriesTextBox.vue – наименование населённого пункта, код страны согласно ISO 3166-1 alpha-2.

Сервис OpenStreetMap

OpenStreetMap (OSM) – это бесплатный, открытый и глобальный общественный проект карты мира. Подобно Википедии, данные OSM могут быть добавлены, отредактированы и использованы всеми желающими.

OSM представляет собой базу картографических объектов. Картинка формируются на её основе. Эту базу объектов можно посмотреть и самостоятельно изменить. Все объекты на карте делятся на четыре типа: точка, линия, полигон и составной объект.

Чтобы подключить и интегрировать OSM-карты на веб-сайт можно использовать различные картографические библиотеки JavaScript, такие как: Openlayers, Leaflet, Mapbox. В данном проекте используется библиотека Openlayers.

OpenLayers – это многофункциональная библиотека на JavaScript для встраивания карт. Она распространяется под лицензией BSD для программного обеспечения с открытым исходным кодом. OpenLayers поддерживает OpenStreetMap и другие карты. Доступа по ссылке.

Openlayers и набор расширений можно установить помощью следующих команд npm:

			npm install ol
npm install ol-ext

		

Пример кода Vue JS для отображения карт OpenStreetMap через Openlayers:

			<template>
<div ref="map-root" style="width: 100%; height: 100%">
</div>
…
</template>
…
<script>
import View from 'ol/View'
import Map from 'ol/Map'
import TileLayer from 'ol/layer/Tile'
import OSM from 'ol/source/OSM'
import 'ol/ol.css'
…
export default {
mounted() {
   new Map({
        // shows the map for the 'map-root' ref
        target: this.$refs['map-root'],
        layers: [
            // background tiled layer
            new TileLayer({
                source: new OSM() 
            }),
        ],

        // the map with smallest zoom
        view: new View({
            zoom: 0,
            center: [0, 0],
            constrainResolution: true
        }),
    });

}, //mounted 
}
</script>

		

Описание компонентов, маршрутизации приложения

Компонент App.vue

Основной компонент App.vue собирает вместе все приложение. В нем подключается OpenWeatherMap API и располагаются компоненты для поиска населенных пунктов, маршрутизация для выбора типа погоды и карта OpenStreetMap.

Компоненты CountriesCodes.vue, CountriesTextBox.vue

CountriesCodes.vue – отдельный компонент, который загружает и обрабатывает CSV-данные о населенных пунктах и странах. Загрузка данных происходит в методе beforeMount. Родительскому компоненту загруженные данные передаются через $emit:

			    async beforeMount() {
        await this.initialInit();
        this.$emit('getCodes', this.allCountriesCodes, this.allCountriesCities);
    },
…
    methods: {
        async initialInit() {
            this.allCountriesCities = await this.parseCSV(link);
            this.allCountriesCodes = await this.parseCSV(link);
        },

		

В App.vue данные передаются так:

			<template>
	…
    <countries-codes @getCodes="getCountriesCodes" />
</template>
…
    methods: {
…
        getCountriesCodes(codeName, cityName) {
            this.countriesCodes = codeName;
            this.countriesCities = cityName;
        },
}

		

CountriesTextBox.vue компонент, который создает текстовое поле для ввода и поиска местоположения. При вводе текста появляется выпадающий, отфильтрованный список для выборки местоположения. Выпадающий список визуально формируется на основе манипуляций css-свойств для контейнеров HTML.

CountriesTextBox.vue принимает CSV-данные из App.vue:

			export default {
…     
props: {
        countriesCodesFilter: {
            type: Array,
            required: true
        },
        countriesCitiesFilter: {
            type: Array,
            required: true
        }
    },

		

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

			this.$emit(
    "getLocation",
    this.getCityInput().value,
    this.getCityInput().dataset.cityeng,
    this.getCityInput().dataset.country,
    this.getCityInput().dataset.countrycode,
    this.getCityInput().dataset.coord
);

		

Далее получение данных в App.vue от CountriesTextBox.vue происходит в методе getLocation:

			<template>
…
<countries-text-box v-bind:countriesCodesFilter="countriesCodes" 
    v-bind:countriesCitiesFilter="countriesCities"
    @getLocation="getLocation" @searchClick="searchLocationClick"
    @clearClick="clearClick" />
</template>
…
<script>
export default {
…
    methods: {
        /**
        * finds openweathermap location though text search area
        * paramCity - city in the textbox
        * paramCityEng - city in English
        * paramCountry - country name
        * paramCountryCode - country code
        * paramCoord - coordinates of the city
        */
async getLocation(paramCity, paramCityEng, paramCountry, paramCountryCode, paramCoord) {
…
}

}
}

		

Маршрутизация в приложении

С помощью маршрутов в приложении происходит навигация к различным компонентам. Для этого подключается необходимая библитека:

			npm install vue-router
		

Разным типам погоды прогноза погоды соответствуют свои компоненты: прогноз сейчас, на сегодня и на 5 дней. Все компоненты маршрутизации находятся в папке src/pages: ForecastNow.vue, ForecastToday.vue, ForecastFiveDays.vue. Для описания маршрутов в файле src/router/router.js создается массив с описанием объектов к страницам роутера.

Фрагмент кода router.js :

			import ForecastNow from "@/pages/ForecastNow";
…
import { createRouter, createWebHistory } from "vue-router";
const routes = [
    {
        name: 'Now',
        path: '/ForecastNow',
        component: ForecastNow,
        props: true
    },
…
]
… 

		

Для выбора типа прогноза погоды пользователь сайта должен нажать на соответствующей вкладке в правой части экрана. За создание вкладок отвечает отдельный компонент ForecastTypeTabs.vue, который в цикле обрисовывает кнопки навигации. При нажатии кнопки/вкладки для определенного прогноза через $emit родительскому компоненту App.vue передаются данные о выбранном типе погоды.

Фрагмент кода ForecastTypeTabs.vue:

			  <div class="tab">
     <button  
        v-for="item in forecastTypes" 
        class="tablinks" 
        @click = "changeForecast($event, item)">
        {{ item }}
     </button>
  </div>
…
<script> 
      methods : {
        changeForecast(evt, type) {
…
              this.$emit('getForecastType',  type);
          } 
}

		

В свою очередь в родительском компоненте App.vue находится сам роутер <router-view> и происходит навигация к необходимой странице через метод getForecastType.

Пример навигации к компоненту ForecastNow.vue, ответственному за прогноз погоды на данный момент:

			this.$router.push({
    name: 'Now',
    params: {
        currentCity: this.locationCity,
        currentCountry: this.locationCountry,
        forecastData: JSON.stringify(foundData)
    }
});

		

Компоненту ForecastNow.vue передаются данные в формате JSON от сервиса OpenWeatherMap, которые компонент отображает в требуемом формате.

Итоговый результат

Онлайн результат работы приложения можно увидеть по ссылке:

Ссылка на исходный код:

Настройка сборки

  • клонировать проект
			git clone https://github.com/practicalDeveloper/weather_forecast_vue
		
  • войти в папку проекта
			cd weather_forecast_vue
		
  • установить зависимости
			npm install
		
  • запустить локальный сервер разработки
			npm run serve
		
Следите за новыми постами
Следите за новыми постами по любимым темам
1К открытий6К показов