likes
comments
collection
share

“「风起云涌」:Vue、ECharts与高德地图的气象联盟”《「风起云涌」:Vue、ECharts与高德地图的气象联盟》

作者站长头像
站长
· 阅读数 24

在当今互联网时代,信息的实时性和准确性变得尤为重要,特别是在天气预报领域。本篇文章将引导你如何利用Vue.js框架、ECharts图表库及高德地图API,构建一个集实时天气查询、未来天气预报与数据可视化于一体的动态气象站。这不仅是一次技术的融合,更是创意与实用性的完美结合。

“「风起云涌」:Vue、ECharts与高德地图的气象联盟”《「风起云涌」:Vue、ECharts与高德地图的气象联盟》

一、项目结构与基础设置

首先,我们需要了解项目的整体结构和基础设置。这包括Vue项目的创建、组件的组织、插件的引入和使用等。

1.项目结构

项目的基本结构如下:

weather-app/
├── ....../
├── src/
│   ├── assets/reset.css
│   ├── router/index.js
│   ├── views/index.vue
│   ├── App.vue
│   ├── main.js
|   ├── index.html
|   ├──package.json
└── ....../

2.引入必要的插件和库

在项目的package.json中,我们引入了Vue Router、AMap插件、Vant组件库和ECharts图表库:

  "dependencies": {
    "@vant/area-data": "^1.5.1",
    "echarts": "^5.5.1",
    "vant": "^4.9.1",
    "vue": "^3.4.29",
    "vue-router": "^4.3.3"
  }

3.项目启动文件

main.js中,我们配置了Vue Router和Vant组件库,并将应用挂载到#app节点:

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import './assets/reset.css';
import { Area, ActionSheet } from 'vant';
import 'vant/lib/index.css';

const app = createApp(App);
app.use(router);
app.use(Area);
app.use(ActionSheet);
app.mount('#app');

二、组件与页面

“「风起云涌」:Vue、ECharts与高德地图的气象联盟”《「风起云涌」:Vue、ECharts与高德地图的气象联盟》

让我们别停下脚步,接着开冲!!!

1.顶层组件App.vue

App.vue是应用的顶层组件,负责渲染主要的结构和内容。我们在这个组件中引入了天气查询功能的主要部分:

<template>
  <RouterView></RouterView>
</template>
<script>
export default {
  setup () {
    return {}
  }
}
</script>
<style lang="css" scoped>
</style>

2.首页组件Index.vue

views/Index.vue中,我们实现了主要的天气查询和展示功能:

<template>
  <div class="container">
    <div class="nav">
      <div class="time">{{ now }}</div>
      <div class="city" @click="state.show = true">切换城市</div>
    </div>
    <div class="city-info">
      <p class="city">{{ state.city }}</p>
      <p class="weather">{{ state.today.weather }}</p>
      <h2 class="temp">
        <em>{{ state.today.temperature }}</em>
      </h2>
      <div class="detail">
        <span>风力: {{ state.today.windPower }}级</span> |
        <span>风向: {{ state.today.windDirection }}风</span> |
        <span>空气湿度: {{ state.today.humidity }}%</span>
      </div>
    </div>
    <div class="future" v-if="state.forecast.length">
      <div class="group">
        明天:
        <span class="tm">白天: {{ state.forecast[1].dayTemp }}℃ {{ state.forecast[1].dayWeather }} {{ state.forecast[1].dayWindDir }} {{ state.forecast[1].dayWindPower }}级</span>
        <span class="tm">夜间: {{ state.forecast[1].nightTemp }}℃ {{ state.forecast[1].nightWeather }} {{ state.forecast[1].nightWindDir }} {{ state.forecast[1].nightWindPower }}级</span>
      </div>
      <div class="group">
        后天:
        <span class="tm">白天: {{ state.forecast[2].dayTemp }}℃ {{ state.forecast[2].dayWeather }} {{ state.forecast[2].dayWindDir }} {{ state.forecast[2].dayWindPower }}级</span>
        <span class="tm">夜间: {{ state.forecast[2].nightTemp }}℃ {{ state.forecast[2].nightWeather }} {{ state.forecast[2].nightWindDir }} {{ state.forecast[2].nightWindPower }}级</span>
      </div>
    </div>
    <div class="echarts-wrap" ref="echartsWrap"></div>
    <van-action-sheet v-model:show="state.show">
      <div class="content">
        <van-area title="地区" :area-list="areaList" :columns-num="2" @confirm="selectCity" @cancel="state.show = false" />
      </div>
    </van-action-sheet>
  </div>
</template>

<script setup>
import { onBeforeMount, reactive, ref, nextTick } from 'vue';
import { areaList } from '@vant/area-data';
import * as echarts from 'echarts';
import { onMounted } from 'vue';

let now = ref('00:00:00');
setInterval(() => {
  now.value = new Date().toLocaleTimeString();
}, 1000);

const state = reactive({
  city: '',
  today: {},
  show: false,
  forecast: [],
});

AMap.plugin('AMap.CitySearch', function () {
  var citySearch = new AMap.CitySearch();
  citySearch.getLocalCity(function (status, result) {
    if (status === 'complete' && result.info === 'OK') {
      state.city = result.city;
      getWeather(result.city);
    }
  });
});

const getWeather = (city) => {
  AMap.plugin('AMap.Weather', function () {
    var weather = new AMap.Weather();
    weather.getLive(city, function (err, data) {
      state.today = data;
    });
    weather.getForecast(city, function (err, data) {
      state.forecast = data.forecasts;
      nextTick(() => {
        initEcharts(data.forecasts.map(item => item.dayTemp));
      });
    });
  });
};

const selectCity = ({ selectedOptions }) => {
  state.city = selectedOptions[1].text;
  getWeather(selectedOptions[1].text);
  state.show = false;
};

const echartsWrap = ref(null);

const initEcharts = (arr) => {
  let myChart = echarts.init(echartsWrap.value);
  myChart.setOption({
    xAxis: { type: 'category', data: ['今天', '明天', '后天', '大后天'] },
    yAxis: {},
    series: [{ name: '温度', data: arr, type: 'line' }],
  });
};
</script>

<style lang="css" scoped>
.container { min-height: 100vh; background: #000; opacity: 0.7; color: #fff; }
.nav { display: flex; justify-content: space-between; padding: 20px; }
.city-info { text-align: center; }
p { margin-top: 10px; }
.temp { font-size: 26px; margin: 10px 0; }
.temp em { font-size: 34px; }
.future { margin-top: 30px; }
.group { height: 44px; line-height: 44px; background-color: rgba(255, 255, 255, 0.3); font-size: 13px; padding: 0 10px; margin-bottom: 10px; border-radius: 5px; }
.echarts-wrap { width: 100%; height: 50vh; }
</style>

三、代码解析与关键技术点

“「风起云涌」:Vue、ECharts与高德地图的气象联盟”《「风起云涌」:Vue、ECharts与高德地图的气象联盟》

1.Vue的组合式API

在这个应用中,我们使用了Vue的组合式API(Composition API),这使得状态管理和逻辑更加清晰和模块化。以下是关键部分的解释:

1)reactive 和 ref

我们使用reactive函数定义了一个响应式对象state,用于存储当前城市、今日天气和未来天气预报等信息:

const state = reactive({
  city: '',
  today: {},
  show: false,
  forecast: [],
});

同时,我们使用ref函数定义了一个响应式变量now,用于存储当前时间:

let now = ref('00:00:00');
setInterval(() => {
  now.value = new Date().toLocaleTimeString();
}, 1000);

2)生命周期钩子

onBeforeMount钩子中,我们初始化了城市搜索和天气查询功能:

onBeforeMount(() => {
  AMap.plugin('AMap.CitySearch', function () {
    var citySearch = new AMap.CitySearch();
    citySearch.getLocalCity(function (status, result) {
      if (status === 'complete' && result.info === 'OK') {
        state.city = result.city;
        getWeather(result.city);
      }
    });
  });
});

2.AMap天气插件的集成

我们通过AMap的插件系统,集成了城市搜索和天气查询功能。具体代码如下:

const getWeather = (city) => {
  AMap.plugin('AMap.Weather', function () {
    var weather = new AMap.Weather();
    weather.getLive(city, function (err, data) {
      state.today = data;
    });
    weather.getForecast(city, function (err, data) {
      state.forecast = data.forecasts;
      nextTick(() => {
        initEcharts(data.forecasts.map(item => item.dayTemp));
      });
    });
  });
};

这里使用了AMap.Weather插件来获取实时天气和未来天气预报数据,并在数据更新后调用nextTick确保页面已渲染完毕后再初始化ECharts图表。

3.ECharts图表的展示

我们使用了ECharts来展示未来几天的白天和夜间温度变化趋势。初始化ECharts图表的代码如下:

const initEcharts = (arr) => {
  let myChart = echarts.init(echartsWrap.value);
  myChart.setOption({
    xAxis: { type: 'category', data: ['今天', '明天', '后天', '大后天'] },
    yAxis: {},
    series: [{ name: '温度', data: arr, type: 'line' }],
  });
};

这里使用了echartsWrap来引用DOM节点,通过echarts.init方法初始化图表,并通过setOption方法设置图表的配置项和数据。

那么最终的动态效果图如下所示:

“「风起云涌」:Vue、ECharts与高德地图的气象联盟”《「风起云涌」:Vue、ECharts与高德地图的气象联盟》

四、总结与扩展

本文通过一个具体的项目实例,详细解析了如何使用Vue.js、ECharts、高德地图API和Vant UI构建一个动态天气预报应用。从实时时间显示、天气数据获取,到数据可视化和用户交互设计,每一步都紧密相连,展现了前端技术在实际项目中的应用。此外,项目还预留了扩展空间,如增加更多天气指标的显示、优化图表样式等,为开发者提供了进一步探索的方向。

转载自:https://juejin.cn/post/7388088513457963017
评论
请登录