Building A Weather App Using VueJS
Last Updated :
16 May, 2024
We will explore how to create a weather application using Vue.js. We'll cover an approach to fetching weather data, displaying current weather conditions, and forecasting. By the end of this guide, you'll have a fully functional weather application that displays current weather information and forecasts for any location.
Prerequisites
Approach to build a Weather App
- Set up a Vue.js project, install dependencies, and create reusable Single File Components (SFC).
- Use Axios to fetch weather data from OpenWeatherMap API, including current weather and forecasts.
- Display fetched data in components, showing current weather conditions, including temperature, description, and icon.
- Format and display hourly and daily forecasts for the upcoming hours and days, respectively.
- Allow user input for city selection, trigger data fetching, and apply CSS styles for visual appeal.
Setup Vue.js Project
Step 1: Install Vue CLI globally if you haven't already.
npm install -g @vue/cli
Step 2: navigate to root directory Then, create a new Vue.js project:
vue create client
Step 3: navigate to client folder
cd client
Project Structure:

Step 4: Install required dependencies
npm i axios
updated dependencies looks like
"dependencies": {
"axios": "^1.6.8",
"core-js": "^3.8.3",
"vue": "^3.2.13"
},
Step 5: Manage files and folders
- Replace the code of App.vue with give code below
- Create styles.css insider src folder
Example: This example show the creation of the weather app.
CSS
/* styles.css */
@import url(
'https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
@import url(
'https://fonts.googleapis.com/css2?family=Orbitron:wght@300;700&display=swap');
/* General Styles */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
font-family: 'Roboto', sans-serif;
background-color: #f8fafa;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
/* Header */
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
.header h1 {
font-family: 'Orbitron', sans-serif;
font-size: 2.5rem;
color: #2b6cb0;
margin: 0;
}
/* Search Bar */
.search-bar {
display: flex;
align-items: center;
margin-bottom: 2rem;
}
.search-input {
font-size: 1rem;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 0.25rem;
background-color: #f5f5f5;
width: 60%;
margin-right: 1rem;
}
.search-button {
font-size: 1rem;
background-color: #4a90e2;
color: white;
border: none;
border-radius: 0.25rem;
padding: 0.5rem 1rem;
cursor: pointer;
transition: background-color 0.3s ease;
}
.search-button:hover {
background-color: #357dbf;
}
/* Weather Widget */
.weather {
text-align: center;
color: #fff;
margin-bottom: 3rem;
padding: 2rem;
background-color: #4caf50;
border-radius: 1rem;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.1);
}
.weather h2 {
font-size: 2rem;
margin-bottom: 1rem;
}
.weather-icon {
width: 120px;
height: 120px;
border-radius: 50%;
background-color: rgba(240, 248, 255, 0.5);
}
.temperature {
font-size: 3rem;
margin-top: 1rem;
}
.clouds {
display: inline-block;
background-color: #f5f5f5;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
font-size: 1.2rem;
color: #4caf50;
}
/* Forecast */
.forecast {
margin-bottom: 3rem;
}
.cast-header {
font-size: 1.5rem;
color: #333;
background-color: #ffc107;
padding: 0.5rem 1rem;
border-radius: 1rem;
margin-bottom: 1rem;
}
.divider {
height: 10px;
background-color: #ffc107;
border-radius: 1rem;
margin-bottom: 2rem;
}
.forecast-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.next {
width: calc(50% - 1rem);
padding: 1.5rem;
border-radius: 1rem;
background-color: #fff;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.1);
margin-bottom: 1rem;
transition: transform 0.3s ease;
}
.next:hover {
transform: translateY(-5px);
}
.time {
font-size: 1.2rem;
color: #4a90e2;
margin-bottom: 0.5rem;
}
.temp-max,
.temp-min {
font-size: 1.2rem;
margin-bottom: 0.5rem;
}
.desc {
color: #555;
}
/* Responsive Styles */
@media screen and (max-width: 768px) {
.header {
flex-direction: column;
align-items: stretch;
}
.search-bar {
flex-direction: column;
}
.search-input,
.search-button {
width: 100%;
border-radius: 0.5rem;
}
.search-input {
margin-right: 0;
margin-bottom: 1rem;
}
.weather-icon {
width: 100px;
height: 100px;
}
.temperature {
font-size: 2.5rem;
}
.cast-header {
font-size: 1.2rem;
}
.divider {
height: 7px;
}
.next {
width: 100%;
}
}
JavaScript
<!-- App.vue -->
<template>
<div class="container">
<div class="header">
<h1>WEATHER APP</h1>
<div class="search-bar">
<input
type="text"
v-model="city"
placeholder="Enter city name"
class="search-input"
/>
<button @click="searchByCity"
class="search-button">Search</button>
</div>
</div>
<main class="main-section">
<div v-if="weatherData" class="weather">
<h2>{{ weatherData.name }},
{{ weatherData.sys.country }}</h2>
<div class="temp-box">
<img :src="iconUrl" alt="Weather Icon"
class="weather-icon" />
<p class="temperature">{{ temperature }} °C</p>
</div>
<span class="clouds">{{ weatherData.weather[0].description }}</span>
</div>
<div v-else class="loading">Loading...</div>
<div class="divider"></div>
<div class="forecast">
<div class="cast-header">Upcoming forecast</div>
<div class="forecast-list">
<div
class="next"
v-for="(forecast, index) in hourlyForecast"
:key="index"
>
<div>
<p class="time">{{ forecast.time }}</p>
<p class="temp-max">{{ forecast.temp_max }} °C</p>
<p class="temp-min">{{ forecast.temp_min }} °C</p>
</div>
<p class="desc">{{ forecast.description }}</p>
</div>
</div>
</div>
</main>
<div v-if="dailyForecast.length" class="forecast">
<div class="cast-header">Next 4 days forecast</div>
<div class="forecast-list">
<div
class="day"
v-for="(forecast, index) in dailyForecast"
:key="index"
>
<p class="date">{{ forecast.date }}</p>
<p class="temp-max">{{ forecast.temp_max }} °C</p>
<p class="temp-min">{{ forecast.temp_min }} °C</p>
<p class="desc">{{ forecast.description }}</p>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
const apikey = "feff206daa60b539abe8fae8f2ab7f29";
export default {
name: "App",
data() {
return {
city: "",
weatherData: null,
hourlyForecast: [],
dailyForecast: [],
};
},
computed: {
temperature() {
return this.weatherData
? Math.floor(this.weatherData.main.temp - 273)
: null;
},
iconUrl() {
return this.weatherData
?
`http://api.openweathermap.org/img/w/${this.weatherData.weather[0].icon}.png`
: null;
},
},
mounted() {
this.fetchCurrentLocationWeather();
},
methods: {
async fetchCurrentLocationWeather() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(async (position) => {
const { latitude, longitude } = position.coords;
const url = `ht
tp://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${apikey}`;
await this.fetchWeatherData(url);
});
}
},
async fetchWeatherData(url) {
try {
const response = await axios.get(url);
this.weatherData = response.data;
// Fetch forecast data
await this.fetchForecast(this.weatherData.name);
} catch (error) {
console.error("Error fetching weather data:", error);
}
},
async fetchForecast(city) {
const urlcast =
`http://api.openweathermap.org/data/2.5/forecast?q=${city}&appid=${apikey}`;
try {
const response = await axios.get(urlcast);
const forecast = response.data;
this.hourForecast(forecast);
this.dayForecast(forecast);
} catch (error) {
console.error("Error fetching forecast data:", error);
}
},
async searchByCity() {
if (!this.city) return;
try {
const urlsearch =
`http://api.openweathermap.org/data/2.5/weather?q=${this.city}&appid=${apikey}`;
const response = await axios.get(urlsearch);
this.weatherData = response.data;
// Fetch forecast data
await this.fetchForecast(this.weatherData.name);
} catch (error) {
console.error("Error fetching weather data:", error);
}
this.city = "";
},
hourForecast(forecast) {
this.hourlyForecast = [];
for (let i = 0; i < 5; i++) {
const date = new Date(forecast.list[i].dt * 1000);
this.hourlyForecast.push({
time: date
.toLocaleTimeString(undefined, "Asia/Kolkata")
.replace(":00", ""),
temp_max: Math.floor(forecast.list[i].main.temp_max - 273),
temp_min: Math.floor(forecast.list[i].main.temp_min - 273),
description: forecast.list[i].weather[0].description,
});
}
},
dayForecast(forecast) {
this.dailyForecast = [];
for (let i = 8; i < forecast.list.length; i += 8) {
const date = new Date(forecast.list[i].dt * 1000);
this.dailyForecast.push({
date: date.toDateString(undefined, "Asia/Kolkata"),
temp_max: Math.floor(forecast.list[i].main.temp_max - 273),
temp_min: Math.floor(forecast.list[i].main.temp_min - 273),
description: forecast.list[i].weather[0].description,
});
}
},
},
};
</script>
Step 6: Start the Application
# Inside client directory
npm run serve
Output:
Similar Reads
Build a Movie App with VueJS We will build a movie application using Vue.js. By the end, you'll have a fully functional movie app that will allow users to search for movies, view their details, and get information such as title, year, rating, and plot. Prerequisites:Vue.jsNode.js and npm are installed on your system.Approach Vu
5 min read
Building a Shopping List with VueJS The following approach covers how to build a simple shopping list app with VueJs. Vue (or Vue.js) is an open-source JavaScript framework geared towards building user interfaces, it was created by Evan You.Prerequisites:Basic understanding of HTML.Basic knowledge of CSSBasic knowledge of JavaScriptIn
3 min read
Build a Todo List App using VueJS This article provides an in-depth exploration of creating a Todo List application using Vue.js. It covers various aspects of building the application, whether you're new to Vue.js or looking to expand your skills, this comprehensive guide offers valuable insights and practical instructions to help y
4 min read
Building A Weather CLI Using Python Trying to know the weather is something that we all do, every day. But have you ever dreamed of making a tool on your own that can do the same? If yes, then this article is for you. In this article, we will look at a step-by-step guide on how to build a Weather CLI using OpenWeather API. What is Ope
4 min read
Build A Weather App in HTML CSS & JavaScript A weather app contains a user input field for the user, which takes the input of the city name. Once the user enters the city name and clicks on the button, then the API Request is been sent to the OpenWeatherMap and the response is been retrieved in the application which consists of weather, wind s
7 min read
Weather app using Django | Python Our task is to create a Weather app using Django that lets users enter a city name and view current weather details like temperature, humidity, and pressure. We will build this by setting up a Django project, creating a view to fetch data from the OpenWeatherMap API, and designing a simple template
2 min read