【愚公系列】《循序渐进Vue.js 3.x前端开发实践》054-案例:天气预报应用
【摘要】 标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳...
标题 | 详情 |
---|---|
作者简介 | 愚公搬代码 |
头衔 | 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。 |
近期荣誉 | 2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳博主等。 |
博客内容 | .NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。 |
欢迎 | 👍点赞、✍评论、⭐收藏 |
🚀前言
随着科技的快速发展和移动互联网的普及,天气预报应用成为了日常生活中不可或缺的一部分。无论是计划出行、安排户外活动,还是关注气候变化,准确的天气信息都能帮助我们做出更明智的决策。在这个背景下,我们将通过一个具体的案例,深入探讨如何开发一款功能丰富、用户友好的天气预报应用。
🚀一、案例:天气预报应用
🔎1.main.js
// 模块引入
import { createApp } from 'vue'
import App from './App.vue'
import VueAxios from 'vue-axios'
import axios from 'axios';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
// 注册Element Plus图标组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
// 向应用实例中全局注册图标组件
app.component(key, component)
}
// 注册Element
app.use(ElementPlus)
// 注册axios
app.use(VueAxios, axios)
app.mount('#app')
这段 Vue 代码是一个典型的 Vue 3 项目初始化过程,主要做了以下几件事:模块引入、插件注册和应用挂载。接下来,我将逐步解释每行代码的作用:
🦋1.1 模块引入
import { createApp } from 'vue'
import App from './App.vue'
import VueAxios from 'vue-axios'
import axios from 'axios'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import { createApp } from 'vue'
: 从 Vue 库中导入createApp
方法,这是 Vue 3 创建应用实例的入口。import App from './App.vue'
: 导入主组件App.vue
,这个组件是整个应用的根组件。import VueAxios from 'vue-axios'
: 导入vue-axios
,它是axios
的 Vue 插件,可以方便地在 Vue 组件中使用axios
发起网络请求。import axios from 'axios'
: 导入axios
,用于发送 HTTP 请求,通常用于与后端 API 进行交互。import ElementPlus from 'element-plus'
: 导入 Element Plus UI 组件库,它是一个基于 Vue 3 的组件库,用于快速构建现代化的 Web 界面。import 'element-plus/dist/index.css'
: 导入 Element Plus 的 CSS 样式文件,使得 UI 组件能正确显示。import * as ElementPlusIconsVue from '@element-plus/icons-vue'
: 导入 Element Plus 提供的图标库,允许在项目中使用 Element Plus 的图标组件。
🦋1.2 创建 Vue 应用实例
const app = createApp(App)
createApp(App)
:通过createApp
方法创建 Vue 应用实例,并将根组件App
传递给它。这个app
是后续对 Vue 应用进行配置和挂载的关键对象。
🦋1.3 全局注册 Element Plus 图标组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
// 向应用实例中全局注册图标组件
app.component(key, component)
}
Object.entries(ElementPlusIconsVue)
:这个语句将ElementPlusIconsVue
对象的每个键值对转化为数组形式(键是图标的名字,值是图标组件本身)。for (const [key, component] of Object.entries(ElementPlusIconsVue))
:通过for...of
循环遍历所有的图标组件。app.component(key, component)
:将每个图标组件注册为全局组件,这样在项目中的任何地方都可以使用这些图标,避免每次使用时都要单独导入。
🦋1.4 注册 Element Plus 插件
app.use(ElementPlus)
app.use(ElementPlus)
:将 Element Plus 作为插件注册到 Vue 应用中。这使得你可以在整个项目中使用 Element Plus 提供的 UI 组件和功能(如表格、按钮、弹窗等)。
🦋1.5 注册 axios 和 vue-axios 插件
app.use(VueAxios, axios)
app.use(VueAxios, axios)
:将axios
和vue-axios
插件注册到 Vue 应用中。这样,axios
实例将被注入到 Vue 的应用实例中,使得可以在任何组件中通过this.axios
或this.$axios
来访问和发送 HTTP 请求。
🦋1.6 挂载 Vue 应用
app.mount('#app')
app.mount('#app')
:将 Vue 应用实例挂载到页面上 ID 为app
的 DOM 元素中。这个步骤意味着 Vue 会控制并渲染该 DOM 元素中的内容,并将根组件App
作为渲染的入口。
🦋1.7 总结
这段代码完成了以下几个任务:
- 创建了 Vue 应用实例。
- 注册了 Element Plus 的图标组件,让它们可以在整个应用中全局使用。
- 安装了 Element Plus 组件库,使得应用能够使用 Element Plus 提供的 UI 组件。
- 注册了
axios
和vue-axios
,使得在 Vue 中能够方便地进行 HTTP 请求。 - 最后,将应用挂载到
#app
DOM 元素上,启动 Vue 应用。
这段代码简洁而高效,通常是 Vue 项目初始化时的标准配置。
🔎2.App.vue
<script setup>
import WeatherDemo from './components/WeatherDemo.vue'
</script>
<template>
<WeatherDemo/>
</template>
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
这段代码就不做说明
🔎3.WeatherDemo.vue
<script setup>
import { onMounted, getCurrentInstance, ref, watch} from 'vue'
const city = ref("上海")
const weatherData = ref({})
const todayData = ref({})
const plc = ref("暂无数据")
const realtime = ref({})
const futureData = ref([])
const requestData = () => {
let c = encodeURI(city.value)
let api = `/simpleWeather/query?city=${c}&key=key`
axios.get(api).then((response)=>{
weatherData.value = response.data
todayData.value = weatherData.value.result.future[0]
realtime.value = weatherData.value.result.realtime
futureData.value = weatherData.value.result.future
console.log(response.data)
})
}
let axios = getCurrentInstance().appContext.app.axios
// 组件挂载时,进行默认数据的初始化
onMounted(() => {
axios.defaults.baseURL = '/myApi'
requestData()
})
// 当用户输入的城市发生变化后,调用接口进行数据请求
watch(city, ()=>{
requestData()
})
</script>
<template>
<el-container class="container">
<el-header>
<el-input placeholder="请输入" class="input" v-model="city">
<template #prepend>城市名:</template>
</el-input>
</el-header>
<el-main class="main">
<div class="today">
今天:
<span>{{todayData.weather ?? plc}} {{todayData.temperature ?? plc}}</span>
<span style="margin-left:20px">{{todayData.direct ?? plc}}</span>
<span style="margin-left:100px">{{todayData.date}}</span>
</div>
<div class="real">
<span class="temp">{{realtime.temperature ?? plc}}°</span>
<span class="realInfo">{{realtime.info ?? plc}}</span>
<span class="realInfo" style="margin-left:20px">{{realtime.direct ?? plc}}</span>
<span class="realInfo" style="margin-left:20px">{{realtime.power ?? plc}}</span>
</div>
<div class="real">
<span class="realInfo">空气质量:{{realtime.aqi ?? plc}}°</span>
<span class="realInfo" style="margin-left:20px">湿度:{{realtime.humidity ?? plc}}</span>
</div>
<div class="future">
<div class="header">5日天气预报</div>
<el-table :data="futureData" style="margin-top:30px">
<el-table-column prop="date" label="日期"></el-table-column>
<el-table-column prop="temperature" label="温度"></el-table-column>
<el-table-column prop="weather" label="天气"></el-table-column>
<el-table-column prop="direct" label="风向"></el-table-column>
</el-table>
</div>
</el-main>
</el-container>
</template>
<style>
.container {
background: linear-gradient(rgb(13, 104, 188), rgb(54, 131, 195));
}
.input {
width: 300px;
margin-top: 20px;
}
.today {
font-size: 20px;
color: white;
}
.temp {
font-size: 79px;
color: white;
}
.realInfo {
color: white;
}
.future {
margin-top: 40px;
}
.header {
color: white;
font-size: 27px;
}
</style>
🦋3.1 <script setup>
部分
这是 Vue 3 中一种新的书写方式,<script setup>
提供了更简洁的 API 使用方法。
☀️3.1.1 导入 Vue 的 API
import { onMounted, getCurrentInstance, ref, watch } from 'vue'
onMounted
:生命周期钩子,当组件挂载完成后执行。getCurrentInstance
:获取当前组件实例,通常用于访问 Vue 的内部实例。ref
:用于创建响应式引用,用于存储和追踪数据。watch
:用来观察数据的变化,并在数据变化时执行某些操作。
☀️3.1.2 定义响应式数据
const city = ref("上海") // 当前城市
const weatherData = ref({}) // 天气数据
const todayData = ref({}) // 今天的天气数据
const plc = ref("暂无数据") // 默认显示文本
const realtime = ref({}) // 实时天气数据
const futureData = ref([]) // 未来天气数据
city
:当前选中的城市(默认为“上海”)。weatherData
:保存从 API 获取的完整天气数据。todayData
:保存当天的天气数据。plc
:如果数据缺失时显示的默认文本(“暂无数据”)。realtime
:保存当前实时天气数据。futureData
:保存未来天气的数据。
☀️3.1.3 请求数据函数
const requestData = () => {
let c = encodeURI(city.value) // 将城市名称进行 URI 编码
let api = `/simpleWeather/query?city=${c}&key=b801ab8d9ef23d37e8ff394083a4728e`
axios.get(api).then((response) => {
weatherData.value = response.data
todayData.value = weatherData.value.result.future[0] // 今天的数据
realtime.value = weatherData.value.result.realtime // 实时数据
futureData.value = weatherData.value.result.future // 未来几天的数据
console.log(response.data)
})
}
requestData
:此函数会根据当前city
发起 HTTP GET 请求,获取天气数据。- 请求的 API 地址为
/simpleWeather/query
,带有city
(城市)和key
(API 密钥)参数。 - 数据请求成功后,更新
weatherData
、todayData
、realtime
和futureData
等响应式数据。
☀️3.1.4 获取 Axios 实例
let axios = getCurrentInstance().appContext.app.axios
getCurrentInstance()
:获取当前组件的实例,appContext.app.axios
用来访问全局注册的axios
实例。
☀️3.1.5 组件挂载时初始化
onMounted(() => {
axios.defaults.baseURL = '/myApi' // 设置 axios 的基础 URL
requestData() // 调用 requestData 函数,获取默认城市的数据
})
onMounted()
:当组件挂载时,设置axios
的baseURL
为/myApi
,然后调用requestData
函数请求天气数据。
☀️3.1.6 城市变化时重新请求数据
watch(city, () => {
requestData() // 当用户输入的城市发生变化时,重新请求数据
})
watch(city, ...)
:当city
(城市)发生变化时,触发requestData
函数,重新获取对应城市的天气数据。
🦋3.2 <template>
部分
这是 Vue 组件的模板部分,用于描述组件的视图结构。
☀️3.2.1 UI 结构
<el-container class="container">
<el-header>
<el-input placeholder="请输入" class="input" v-model="city">
<template #prepend>城市名:</template>
</el-input>
</el-header>
<el-main class="main">
<div class="today">
今天:
<span>{{ todayData.weather ?? plc }} {{ todayData.temperature ?? plc }}</span>
<span style="margin-left:20px">{{ todayData.direct ?? plc }}</span>
<span style="margin-left:100px">{{ todayData.date }}</span>
</div>
<div class="real">
<span class="temp">{{ realtime.temperature ?? plc }}°</span>
<span class="realInfo">{{ realtime.info ?? plc }}</span>
<span class="realInfo" style="margin-left:20px">{{ realtime.direct ?? plc }}</span>
<span class="realInfo" style="margin-left:20px">{{ realtime.power ?? plc }}</span>
</div>
<div class="real">
<span class="realInfo">空气质量:{{ realtime.aqi ?? plc }}°</span>
<span class="realInfo" style="margin-left:20px">湿度:{{ realtime.humidity ?? plc }}</span>
</div>
<div class="future">
<div class="header">5日天气预报</div>
<el-table :data="futureData" style="margin-top:30px">
<el-table-column prop="date" label="日期"></el-table-column>
<el-table-column prop="temperature" label="温度"></el-table-column>
<el-table-column prop="weather" label="天气"></el-table-column>
<el-table-column prop="direct" label="风向"></el-table-column>
</el-table>
</div>
</el-main>
</el-container>
el-container
:Element Plus 提供的布局容器,用于分隔页面的不同部分。el-input
:输入框组件,v-model="city"
实现了双向数据绑定,当用户输入城市名时,city
会自动更新。el-table
:用于展示未来 5 天的天气预报数据。{{ }}
:插值表达式,用于显示todayData
、realtime
和futureData
中的天气信息。如果某个数据为空,则显示默认文本plc
(“暂无数据”)。
☀️3.2.2 显示天气信息
- 显示今天的天气,包括
weather
、temperature
(温度)、direct
(风向)和date
(日期)。 - 显示实时天气数据:温度、天气信息、风向、风力等。
- 显示空气质量(
aqi
)和湿度(humidity
)。 - 显示 5 天的天气预报:日期、温度、天气和风向。
🦋3.3 <style>
部分
.container {
background: linear-gradient(rgb(13, 104, 188), rgb(54, 131, 195));
}
.input {
width: 300px;
margin-top: 20px;
}
.today {
font-size: 20px;
color: white;
}
.temp {
font-size: 79px;
color: white;
}
.realInfo {
color: white;
}
.future {
margin-top: 40px;
}
.header {
color: white;
font-size: 27px;
}
container
:为整个容器设置背景色,使用渐变色。input
:设置输入框的宽度和顶部边距。today
、temp
、realInfo
等:设置文本的字体大小和颜色(大部分为白色)。future
:设置未来天气预报部分的顶部边距。header
:设置未来天气预报标题的颜色和字体大小。
🦋3.4 总结
这段代码实现了一个简单的天气应用,允许用户输入城市名,获取该城市的天气数据并展示。它利用了 Vue 3 的 Composition API 来组织组件的逻辑,并使用 Element Plus 组件库来构建 UI。关键功能包括:
- 获取天气数据并展示当天、实时和未来几天的天气。
- 使用
watch
监听城市变化,自动更新天气数据。 - 使用
axios
发送 API 请求并处理返回的数据。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)