一、引言
在移动应用开发中,天气功能是一个常见且实用的模块。使用 UniApp 进行跨平台开发时,构建一个美观且功能实用的天气组件能够为应用增添不少价值。本文将介绍一个基于 UniApp 开发的天气组件,详细解析其代码实现,并展示它的实际效果,就像下面展示的这样
二、组件功能概述
该天气组件主要实现了以下功能:
- 显示当前城市信息:展示当前定位或选择城市的名称。
- 呈现实时天气信息:包括天气状况(如晴、多云等)、风向、风力等级、湿度以及当前温度。
- 展示一周天气预报:列出未来一周每天的日期、天气状况、风力等级以及昼夜温度范围
三、组件代码详细解析
3.1 模板(<template>
)部分
<view class="wy-weather">
<!-- 温度 -->
<view class="header">
<view class="city-info" @click="handleSelect('')">
<u-icon size="16" color="#ffffff" name="map"></u-icon>
{{ fromData.real.station.city }}
</view>
<view class="weather-info">
<view class="weather-details">
<view v-if="fromData.real.weather.info" class="detail-item">
{{ fromData.real.weather.info }}
</view>
<view v-if="fromData.predict.detail[0].day.wind.direct" class="detail-item">
{{ fromData.predict.detail[0].day.wind.direct }}
</view>
<view v-if="fromData.real.wind.power" class="detail-item">
{{ fromData.real.wind.power }}
</view>
<view v-if="fromData.real.weather.humidity" class="detail-item">
湿度{{ fromData.real.weather.humidity }}%
</view>
</view>
<view class="temperature">
<view class="wendu">{{ fromData.real.weather.temperature || "" }}℃</view>
</view>
</view>
</view>
<!-- 一周天气 -->
<view class="body">
<view class="box" v-for="(item, index) in fromData.predict.detail.slice(1)" :key="index">
<view class="riqi">{{ item.date | predictDate }}</view>
<view class="state">{{ item.day.weather.info }}</view>
<view class="state">{{ item.day.wind.power }}</view>
<view class="wendu">{{ item.night.weather.temperature }}-{{ item.day.weather.temperature }}℃</view>
</view>
</view>
</view>
- 城市信息区域:通过
fromData.real.station.city
展示城市名称,点击city-info
区域可以触发handleSelect
方法,可能用于选择城市。 - 实时天气信息区域:通过多个
v-if
条件判断数据是否存在,然后展示天气状况、当天风向(来自预测数据的第一条)、实时风力等级和湿度信息。温度则直接从fromData.real.weather.temperature
获取并展示。 - 一周天气预报区域:使用
v-for
循环遍历fromData.predict.detail
数组(从第二个元素开始,因为第一个元素可能用于当天实时数据关联),展示日期(经过predictDate
过滤器处理)、当天天气状况、风力等级以及昼夜温度范围。
3.2 脚本(<script>
)部分
import * as IndexApi from '@/api/index';
export default {
props: {
cityCode: {
type: String,
default: ""
}
},
data() {
return {
fromData: {
predict: { detail: [] }
}
};
},
filters: {
predictDate(e) {
return e.slice(5);
}
},
async mounted() {
await this.onGetdata();
},
watch: {
cityCode: {
immediate: true,
async handler(newValue) {
if (newValue) {
await this.onGetdata();
}
}
}
},
methods: {
handleSelect() {
this.$emit('selectCity');
},
async onGetdata() {
try {
const res = await IndexApi.postWeather({ cityCode: this.cityCode });
this.fromData = JSON.parse(res.data).data;
} catch (error) {
console.error('获取天气数据失败:', error);
}
}
}
};
- 属性定义:通过
props
接收父组件传递的cityCode
,用于指定查询天气的城市编码。 - 数据定义:
fromData
用于存储获取到的天气数据,初始化为包含空的predict.detail
数组。 - 过滤器:
predictDate
过滤器用于处理日期格式,只截取日期字符串的后部分进行展示。 - 生命周期钩子函数:在
mounted
钩子函数中调用onGetdata
方法,在组件挂载后立即获取天气数据。 - 监听器:监听
cityCode
的变化,当cityCode
有新值时(immediate: true
表示在组件创建时立即执行一次监听器),调用onGetdata
方法重新获取对应城市的天气数据。 - 方法定义:
handleSelect
方法通过$emit
触发自定义事件selectCity
,可能用于通知父组件进行城市选择操作;onGetdata
方法通过调用IndexApi.postWeather
接口获取天气数据,并处理成功和失败的情况。
四、使用该组件
<template>
<view>
<WyWeather :cityCode="yourCityCode" @selectCity="handleCitySelect" />
</view>
</template>
<script>
import WyWeather from '@/components/wy-weather.vue';
export default {
components: {
WyWeather
},
data() {
return {
yourCityCode: '具体城市编码'
};
},
methods: {
handleCitySelect() {
// 处理城市选择逻辑
}
}
};
</script>
五、中央天气网接口说明
我们使用的是中央气象台的api接口:
http://www.nmc.cn/rest/province #省份获取
http://www.nmc.cn/rest/province/{省份代码} #城市获取
http://www.nmc.cn/rest/weather?stationid={城市代码} #城市天气预报获取
关于数据的含义,推荐对照root->data->real->station->url网页信息,其中9999.0表示要素缺测,要素如果无观测为9998。
图片接口
http://www.weather.com.cn/m/i/weatherpic/29x20/d0.gif
http://www.weather.com.cn/m2/i/icon_weather/29x20/n00.gif
这个图就是天气现象0(晴)的图片,其他天气现象的图片依此类推。c打头的图片是20*20像素的,b打头的是50*46像素的,d打头的是反白的图标,29*20像素,n打头的是夜间反白图标,29*20像素,注意这里的文件名是两位数字!
也许还有更多的图标,等待大家发掘啦~
六、总结
通过上述代码的实现,我们成功构建了一个基于 UniApp 并接入中央天气网接口的天气组件。从数据获取、展示到样式布局都进行了详细的处理。在实际应用中,可以根据需求进一步优化,比如增加更多的天气数据展示、优化数据请求的错误处理、提升界面的交互体验等。希望本文能为大家在 UniApp 开发中实现天气相关功能提供有益的参考。
请注意,上述代码中的接口地址、请求参数和 API Key 仅为示例,实际使用时需要根据中央天气网的真实接口文档进行调整。同时城市数据json已经封装,需要关注点赞私信。