[vue]实现一个天气预报页面

前言

使用vue3 + element plus + axios。效果:

步骤

  1. 创建项目并安装依赖
npm create vue@latest

cd vue3-demo1
npm install
npm run dev

npm install --save axios vue-axios
npm install element-plus --save
  1. main.js全局引入
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import VueAxios from 'vue-axios'
import axios from 'axios'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
app.use(VueAxios, axios)
app.mount('#app')
  1. vite.config.js中配置跨域代理
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueDevTools(),
  ],
  server: {
    proxy: {
      '/myApi': {
        target: 'https://apis.juhe.cn/',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/myApi/, '')
      }
    }
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
})
  1. 编辑App.Vue。注意替换axios请求中的key。
<script setup>
import WeatherDemo from './components/WeatherDemo.vue'
</script>

<template>

    <div>
      <WeatherDemo/>
    </div>

</template>
  1. 编辑WeatherDemo.vue
<template>
  <el-container class="container">
    <el-header>
      <el-input placeholder="Please input" class="input" v-model="city">
        <template #prepend>城市名:</template>
      </el-input>
    </el-header>

    <el-main class="main">
      <div class="today">
        今日:
        <span>{{ this.todayData.weather ?? this.plc }} {{ this.todayData.temperature ?? this.plc }}</span>
        <span style="margin-left: 20px;">{{ this.todayData.direct ?? this.plc }}</span>
        <span style="margin-left: 100px;">{{ this.todayData.date }}</span>
      </div>
      <div class="real">
        <span class="temp">{{ this.realtime.temperature ?? this.plc }}°</span>
        <span class="realInfo">{{ this.realtime.info ?? this.plc }}</span>
        <span class="realInfo" style="margin-left: 20px;">{{ this.realtime.direct ?? this.plc }}</span>
        <span class="realInfo" style="margin-left: 20px;">{{ this.realtime.power ?? this.plc }}</span>
        <span></span>
      </div>
      <div class="real">
        <span class="realInfo">空气质量: {{ this.realtime.aqi ?? this.plc }}</span>
        <span class="realInfo" style="margin-left: 30px;">湿度: {{ this.realtime.humidity ?? this.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>

<script>
export default {
  mounted() {
    this.axios.defaults.baseURL = '/myApi'
    this.requestData()
  },
  data() {
    return {
      city: "合肥",
      weatherData: {},
      todayData: {},
      plc: "暂无数据",
      realtime: {},
      futureData: []
    }
  },
  watch: {
    city() {
      this.requestData()
    }
  },
  methods: {
    requestData() {
      let city = encodeURI(this.city)
      let api = `/simpleWeather/query?key=xxx&city=${city}`
      this.axios.get(api).then((resp) => {
        console.log(resp.data)
        this.weatherData = resp.data
        this.todayData = this.weatherData.result.future[0]
        this.realtime = this.weatherData.result.realtime
        this.futureData = this.weatherData.result.future
      })
    }
  }
}
</script>

<style scoped>
.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>

参考

  • 《循序渐进Vue.JS前端开发实战》
posted @ 2025-03-16 17:22  花酒锄作田  阅读(272)  评论(2)    收藏  举报