我是一个初学者开发人员,目前我正在使用 vue 进行天气应用程序项目.js .我在使用 vue 的组件和数据绑定方面遇到了一些问题。谁能用一些代码示例向我解释一下?!
我读过一些论坛,看了一些关于自定义组件的教程视频,也试过了,但我想我犯了一些错误。具体来说,我想知道,如何将我的 API url 数据绑定到下拉框,位置会随着每次选择而变化。
注意:使用的 API 是基于纬度和经度位置的开放天气 API。
var myDropdown = Vue.component('my-dropdown', {
template: '#dropdown',
data: function() {
return {
isOpen: false,
selected: null,
options: [
'Heidenheim an der Brenz',
'Giengen',
'Ulm',
]
}
},
methods: {
toggle: function() {
this.isOpen = !this.isOpen;
},
show: function() {
this.isOpen = true;
},
hide: function() {
this.isOpen = false;
},
set: function(option) {
this.selected = option;
this.hide();
}
},
mounted: function() {
console.log('My dropdown component is mounted!')
}
});
let weatherApp = new Vue({
el: '#app',
data: {
town: '',
Temp: '',
minTemp: '',
maxTemp:'',
wind: '',
description: '',
icon: '',
hdh: 'https://fcc-weather-api.glitch.me/api/current?lat=48.6833&lon=10.15',
ulm: 'https://fcc-weather-api.glitch.me/api/current?lat=48.39841&lon=9.99155',
giengen: 'https://fcc-weather-api.glitch.me/api/current?lat=48.39841&lon=9.99155'
},
methods: {
getWeather() {
var url = '';
axios
.get(url)
.then(response => {
this.town = response.data.name
this.Temp = response.data.main.temp;
this.minTemp = response.data.main.temp_min;
this.maxTemp = response.data.main.temp_max;
this.wind = response.data.wind.speed;
this.description = response.data.weather[0].description;
this.icon = response.data.weather[0].icon;
})
.catch(error => {
console.log(error);
});
},
},
beforeMount() {
this.getWeather();
},
});
body {
background: url(https://shiftyjelly.files.wordpress.com/2013/11/w.jpg?w=960&h=400);
background-repeat: no-repeat;
font-family: 'Montserrat', sans-serif;
font-weight: 100;
text-shadow: 0px 0px 2px #000000;
color: #ffffff;
width: 960px;
height: 400px;
}
#weather {
padding: 15px;
}
#temperature {
position: absolute;
font-size: 40px;
top: 240px;
left: 420px;
color: black;
}
#temp-values {
text-align: right;
position: relative;
text-justify: distribute;
display: block;
top: 60px;
left: -200px;
color: black;
}
#info {
padding: 15px;
}
#name {
top: 10px;
left: 300px;
font-size: 40px;
color: black;
position: relative;
}
.wind {
top: 180px;
left: 380px;
color: black;
position: relative;
}
#icon {
color: black;
font-size: 20px;
left: -180px;
top: 120px;
position: relative;
}
#my-dropdown {
cursor: pointer;
position: absolute;
left: 0%;
top: 0%;
min-width: 250px;
height: 40px;
}
#selected {
position: relative;
z-index: 2;
display: block;
width: 100%;
height: 40px;
padding: 0 20px;
background: rgba(05, 46, 41, 0.1);
border-radius: 10px;
font: 1.25rem/40px 'Ubuntu', Helvetica, Arial, sans-serif;
text-shadow: 2px 2px 0px #000;
color: rgb(0, 237, 255);
}
#selected: after {
opacity: 0.5;
display: inline-block;
margin-left: 10px;
content: '▼';
color: black;
}
#selected:hover: after {
opacity: 1;
}
#options {
position: absolute;
left: 0;
top: 100%;
z-index: 1;
width: 100%;
margin-top: 3px;
background: rgba(05, 46, 41, 0.1);
border-radius: 10px;
}
#option {
padding: 5px 20px;
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
font: 1.2rem 'Vollkorn', Georgia, Times, serif;
color: rgb(0, 237, 255);
text-shadow: 2px 2px 0px #000;
}
#option:hover {
background-color: rgba(0, 0, 0, 0.05);
}
#option:last-child {
border-bottom: none;
}
#fade-enter-active, .fade-leave-active {
transition: all 0.25s ease-out;
}
#fade-enter, .fade-leave-active {
opacity: 0.5;
transform: translateY(-30px);
}
* { box-sizing: border-box; }
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.js"></script>
<title>Weather App</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<template id="dropdown">
<div id="my-dropdown">
<div id="selected" @click="toggle">Select Your Town Here</div>
<div id="options" v-show="isOpen">
<div id="option" v-for="option in options" @click="set(option)">
{{ option }}
</div>
</div>
</div>
</template>
<body>
<div id="app">
<my-dropdown></my-dropdown>
<div id="weather">
<span id="name">{{town}}</span>
<span id="icon">{{description}}</span>
<span id="temperature">{{Temp}}°</span><br>
<span id="temp-values">Min: {{minTemp}}° <br> Max: {{maxTemp}}°</span>
</div>
<div id="info">
<img class="wind" height="40px" width="40px" src="https://www.svgrepo.com/show/71601/wind.svg">
<span class="wind">{{wind}} m/s</span>
</div>
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</body>
</html>
这是一个小提琴
首先,最好将所有数据保存在一个位置,而不是在下拉组件中对城镇名称进行硬编码。 您也不需要每次都存储整个 URL。 因此,请从下拉列表中删除options
。您将通过道具将城镇数据传递给它。
1( 将应用的城镇数据重组为对象数组,如下所示:
data: {
...
towns: [
{abbr: 'hdh', name: 'Heidenheim an der Brenz', lat: '48.6833', lon: '10.15'},
{abbr: 'ulm', name: 'Ulm', lat: '48.39841', lon: '9.99155'},
{abbr: 'giengen', name: 'Giengen', lat: '48.39841', lon: '9.99155'}
]
}
2( 通过名为"选项"的道具将城镇数据传递给下拉组件:
<my-dropdown :options="towns"></my-dropdown>
3( 将下拉标签更改为{{ option.name }}
4(将道具添加到组件中:
props: ['options']
5( 当城镇发生变化时发出自定义事件:
set: function(option) {
this.$emit('change-town', option);
...
}
6( 在父模板的getWeather
中处理该事件:
<my-dropdown :options="towns" @change-town="getWeather"></my-dropdown>
7( 生成 URL 并发送请求:
getWeather(option) {
const urlpath = 'https://fcc-weather-api.glitch.me/api/current?'
const qs = `lat=${option.lat}&lon=${option.lon}`;
const url = path + qs;
axios.get(url)...
...
}