简要概述
我基本上是在构建一个简单的天气小部件,在其中输入城市名称,它将从API请求中触发并获取该城市的天气对象。
表单/ API请求的触发器是当某人停止键入时通过debounce
和当某人在输入中按下回车键时通过onsubmit
。
问题
当有人搜索城市时,我有一个watch
函数,该函数将localStorage键city
设置为等于用户即时输入的任何内容。
问题是,如果不存在他们搜索的城市,则该城市仍将保存在本地存储中,并且当页面重新加载时,它会杀死小部件,因为API请求无法获取该城市的详细信息
如果请求的响应状态为200,我已经尝试应用本地存储值,但是观察者只是将其覆盖。
因此,基本上,我需要在响应为200时设置localStorage
值,如果不是,则将其删除。
我尝试过执行if
语句来确定何时响应为200
,何时不响应,但是Local Storage中的值不变。
从逻辑上讲,我认为不需要观察者,并且在请求的响应为200之前,不应更新city
值。
请在此处查看我的示例:https://jsfiddle.net/mattclarke/mjswgb63/
复制我的问题的步骤
London
替换为Liverpool
,以查看Application -> LocalStorage
中的密钥更新。Liverpool
更改为不存在的城市,例如Londonpool
。city
值改回London
或任何其他城市名称。代码
import axios from 'axios'
import Swal from 'sweetalert2'
import _ from 'lodash'
const Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000
})
export default {
name: 'app',
data() {
return {
weather: [],
city: 'London',
loading: false,
}
},
mounted() {
this.weatherRequest();
},
watch: {
city(city) {
localStorage.city = city;
}
},
methods: {
weatherRequest: function() {
this.loading = true;
if(localStorage.city) {
this.city = localStorage.city;
}
let cityName = this.city;
if(cityName == "") {
this.loading = false;
return;
}
axios
.get('http://api.openweathermap.org/data/2.5/weather?q=' + cityName + '&APPID=757cfb0ae831a41efa790e4fd9b008e8&units=metric')
.then(response => {
this.loading = false;
this.weather = response.data;
if(response.status == 200) {
}
Toast.fire({
type: 'success',
title: cityName + ' was loaded successfully.'
});
}, () => {
this.loading = false;
Toast.fire({
type: 'error',
title: 'Couldn\'t find the city: ' + cityName,
})
})
},
getWeather: function() {
this.weatherRequest()
},
debounceWeather: _.debounce(function() {
this.weatherRequest()
}, 700),
}
}
<template>
<div id="app">
<form v-on:submit.prevent="weatherRequest" class="mb-2 max-w-2xl mx-auto flex">
<input type="text" v-model="city" class="border-2 p-2 w-full" @input="debounceWeather" placeholder="Please specify a city name" data-city-name>
</form>
<div class="max-w-2xl mx-auto">
<div class="flex w-full rounded-lg" style="background: url('http://placeimg.com/640/480/nature');">
<div class="text-white p-6 rounded-lg shadow-lg text-sm w-full relative" style="background-color: rgba(42, 67, 101, 0.75); backdrop-filter: blur(5px);" data-weather-box>
<div v-if="loading" class="absolute bg-blue-900 flex h-full items-center justify-center left-0 opacity-75 rounded-lg top-0 w-full"><img src="./assets/loading.svg" /></div>
<div class="border-b-2 border-blue-800 mb-4 pb-4 flex justify-between">
<div class="text-left">
<div class="block text-lg">
<span data-city-result>{{ weather.name }}</span> (<span data-country>{{ weather.sys.country }}</span>)
</div>
<span class="text-blue-300" data-weather>{{ weather.weather[0].main }} - {{ weather.weather[0].description }}</span>
</div>
<div class="absolute p-3 pr-5 right-0 text-5xl top-0 weather">
<i v-if="weather.weather[0].main == 'Clouds'" class="fas fa-cloud"></i>
<i v-if="weather.weather[0].main == 'Clear'" class="fas fa-sun text-yellow-400"></i>
<i v-if="weather.weather[0].main == 'Rain'" class="fas fa-cloud-rain"></i>
<i v-if="weather.weather[0].main == 'Snow'" class="far fa-snowflake"></i>
<i v-if="weather.weather[0].main == 'Mist'" class="fas fa-smog"></i>
<i v-if="weather.weather[0].main == 'Smoke'" class="fas fa-smog"></i>
<i v-if="weather.weather[0].main == 'Haze'" class="fas fa-smog"></i>
<i v-if="weather.weather[0].main == 'Thunderstorm'" class="fas fa-bolt"></i>
</div>
</div>
<div class="flex justify-between">
<div><span class="text-blue-400 text-xs">Temp: </span><span class="text-white" data-temp>{{ weather.main.temp }}</span>°c</div>
<div><span class="text-blue-400 text-xs">Max: </span><span class="text-white" data-temp-max>{{ weather.main.temp_max }}</span>°c</div>
<div><span class="text-blue-400 text-xs">Min: </span><span class="text-white" data-temp-min>{{ weather.main.temp_min }}</span>°c</div>
</div>
<div class="flex justify-between">
<div><span class="text-blue-400 text-xs">Pressure: </span><span data-pressure>{{ weather.main.pressure }}</span></div>
<div><span class="text-blue-400 text-xs">Humidity: </span><span data-humidity>{{ weather.main.humidity }}</span></div>
<div><span class="text-blue-400 text-xs">Visibility: </span><span data-visibility>{{ weather.visibility }}</span></div>
</div>
<div class="flex justify-between">
<div><span class="text-blue-400 text-xs">Wind Speed: </span><span data-wind-speed>{{ weather.wind.speed }}</span>mph</div>
<div><span class="text-blue-400 text-xs">Wind Direction: </span><span data-wind-direction>{{ weather.wind.deg }}</span>°deg</div>
</div>
<div class="flex justify-between">
<div><span class="text-blue-400 text-xs">Sunrise: </span><span data-sunrise>{{ new Date(weather.sys.sunrise * 1000).toLocaleString() }}</span></div>
<div><span class="text-blue-400 text-xs">Sunset: </span><span data-sunset>{{ new Date(weather.sys.sunset * 1000).toLocaleString() }}</span></div>
</div>
</div>
</div>
</div>
</div>
</template>
任何帮助将不胜感激!
答案 0 :(得分:1)
我设法使它按应有的方式工作。如果响应不成功,我只需要删除localStorage密钥。
下面的weatherRequest
方法的正确代码:
weatherRequest: function() {
this.loading = true;
if(localStorage.city) {
this.city = localStorage.city;
}
let cityName = this.city;
if(cityName == "") {
this.loading = false;
return;
}
axios
.get('http://api.openweathermap.org/data/2.5/weather?q=' + cityName + '&APPID=757cfb0ae831a41efa790e4fd9b008e8&units=metric')
.then(response => {
this.loading = false;
this.weather = response.data;
if(response.status == 200) {
localStorage.city = cityName;
}
Toast.fire({
type: 'success',
title: cityName + ' was loaded successfully.'
});
}, () => {
this.loading = false;
window.localStorage.removeItem('city');
Toast.fire({
type: 'error',
title: 'Couldn\'t find the city: ' + cityName,
})
})
},