基于Vue+ElementUi+高德API实现的轻量级天气小卡片

2,458 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

该组件除了具备展示实时温度、风力、湿度等常用功能外,还借助高德API添加了自动定位的功能,以达成更加便利的用户体验

另,最近想学习一下微信小程序,想看看uni-app,应该怎么学啊 :<

注意!使用时需要在高德地图中申请一个key来完成功能,key的目的应该是为了记录请求次数以在该key请求过多时限流。我已经在下列源码中标注  #在这里填入你申请来的key# ,申请教程在如下链接中

lbs.amap.com/api/android…

效果图

屏幕截图 2022-07-02 092542.png

运行解释

该卡片为一个.vue组件,为了更加轻量没有使用天气预报,而是直接展示当前实时天气,为方便讲解,我以中间分割线为界,将该组件分为:下方展示框,上方查询框

展示框

组件挂载时,若为第一次运行,则将向高德地图申请ip地址并接收返回值中的adcode与城市名,adcode的变动触发watch函数以查询一次天气信息,此次查询到的位置信息将会被上方自动定位使用

若不是第一次运行,则将获取localStorage中的地址信息并发送请求查询天气

在watch中,adcode每一次变动都会触发查询该地天气信息(很重要) ,查询所用的adcode将被存入localStorage以方便在下一次进入时直接查询该地天气

天气图标将会根据左侧天气信息计算应该呈现的图标

查询框

上方查询input框中,敲下回车以触发函数来根据该位置查询该地adcode并存入以触发watch

查询成功时仅更新展示框内容

当查询失败时,将会弹出警告框,以下为查询错误时弹框样式

image.png

函数解读

前提:adcode是高德开放平台下的用于记录地理位置的编码,将adcode发往某一接口中可返回所需要的信息

核心函数:众所周知,Vue中的watch将检测所配置上的变量,并在该变量发生变化时及时运行所配置的函数。在watch配置项中的adcode函数将会监视data中的adcode,每一次变化都将发送一次请求到restapi.amap.com/v3/weather/… ,该url接受两个必选参数:city、key并返回一串关于查询结果的json

详情:lbs.amap.com/api/webserv…

useIp:当用户点击“使用该地区”时将会调用,将第一次挂载时或localStorage获取到的adcode(已被存入ipAdCode)填入data中的adcode

keyUp:当用户在上方查询框中敲下回车时触发,将会把input框中的内容存入city并触发getCityCode函数(根据city查询adcode的函数)

getIp:直接发送一次请求并返回该地的位置信息

详情:lbs.amap.com/api/webserv…

getCityCode:根据城市名查询该地adcode

详情:lbs.amap.com/api/webserv…

代码

<template lang="">
    <el-card shadow="hover">
        <h1>天气</h1>
        <el-input v-model="input" placeholder="输入位置并按下回车以查询该地天气" @keyup.enter.native="keyUp"></el-input>
        <p class="ipAddress"><i class="el-icon-location-outline"></i>{{ipAddress}} <el-link type="primary"
                @click="useIp">使用该地区</el-link>
        </p>
        <el-divider></el-divider>
        <div class="showBlock">
            <p class="address">{{address}}</p>
            <p class="temperature">{{temperature}}℃<span class="weather">{{weather}} <span><i class="mainWeather"
                            :class="getIcon"></i></span></span></p>


            <div class="other">
                <p class="wind"><i class="el-icon-wind-power"></i>
                    风向:<span>{{winddirection}}</span>&nbsp;&nbsp;&nbsp;<span>风力:{{windpower}}级</span></p>
                <p class="humidity"><i class="el-icon-odometer"></i> 湿度:{{humidity}}</p>
                <p id="reporttime">消息发布时间:{{reporttime}}</p>
            </div>
        </div>
    </el-card>
</template>
<script>
    export default {
        name: 'Weather',
        data() {
            return {
                input: '',
                city: '',
                adcode: '',
                address: '',
                ipAddress: '',
                ipAdCode: '',
                weather: '',
                temperature: '',
                winddirection: '',
                windpower: '',
                humidity: '',
                reporttime: '',
                icon: true
            }
        },
        watch: {
            adcode() {        //当adcode发生变化时,重新请求该地天气
                this.$axios.get('https://restapi.amap.com/v3/weather/weatherInfo?parameters', {
                    params: {
                        key: '#在这里填入你申请来的key#',        //需要操作
                        city: this.adcode,
                        extensions: 'base'
                    }
                }).then(
                    response => {
                        let lives = response.data.lives[0]
                        this.weather = lives.weather
                        this.temperature = lives.temperature
                        this.winddirection = lives.winddirection
                        this.windpower = lives.windpower
                        this.humidity = lives.humidity
                        this.reporttime = lives.reporttime
                        this.address = lives.city

                        localStorage.setItem('adcode', this.adcode)    //将存储目前查询的天气


                    },
                    error => {
                        this.$notify.info({
                            title: '未知错误',
                            message: error.message
                        });
                    }
                )
            },

        },
        computed: {
            getIcon() {
                this.icon = false
                if (this.weather == '晴') {
                    return 'el-icon-sunny'
                } else if (this.weather == '多云') {
                    return 'el-icon-cloudy-and-sunny'
                } else if (this.weather == '阴') {
                    return 'el-icon-partly-cloudy'
                } else if (this.weather.indexOf('雨')) {
                    return 'el-icon-heavy-rain'
                } else if (this.weather.indexOf('雪')) {
                    return 'el-icon-light-rain'
                }
                this.icon = true
            }
        },
        methods: {
            useIp() {
                this.adcode = this.ipAdCode
            },
            keyUp() {
                this.city = this.input
                this.input = ''
                this.getCityCode()
            },
            getIp() { //挂载时执行,获取ip地址
                this.$axios.get('https://restapi.amap.com/v3/ip?parameters', {
                    params: {
                        key: '#在这里填入你申请来的key#'        //需要操作
                    }
                }).then(
                    response => {
                        this.ipAddress = `${response.data.province}${response.data.city}`
                        this.ipAdCode = response.data.adcode

                        if (!(localStorage.getItem('adcode'))) {
                            this.adcode = response.data.adcode
                        }
                    }
                )
            },
            getCityCode() {        //查询城市的adcode
                this.$axios.get('https://restapi.amap.com/v3/geocode/geo?parameters', {
                    params: {
                        key: '#在这里填入你申请来的key#',        //需要操作
                        address: this.city,
                    }
                }).then(
                    response => {
                        if(response.data.status == '1'){
                            console.log(response);
                            this.adcode = response.data.geocodes[0].adcode
                        }
                        else if (response.data.status == '0') {
                            this.$notify.error({
                                title: '查询错误',
                                message: '请重新核对查询地址'
                            });
                        }
                    }
                )
            }
        },
        mounted() {
            if (localStorage.getItem('adcode')) {            //取出本地存储的地址,若不存在,则使用ip地址
                this.adcode = localStorage.getItem('adcode')
            }
            this.getIp()
        },
    }
</script>
<style scoped>
    .ipAddress {
        margin-top: 10px;
    }

    .el-card {
        background-color: rgba(255, 215, 55, 0.8);
        height: 409px;
        color: #000;
    }

    h1 {
        margin: 0px 0px 10px 10px;
    }

    .showBlock {
        margin-top: 10px;
    }

    .temperature {
        font-size: 50px;
    }

    .weather {
        margin-left: 20px;
        font-size: 35px;
    }

    .address {
        font-size: 20px;
    }

    .other {
        margin-top: 10px;
    }

    .other p {
        margin-top: 10px;
        font-size: 18px;
    }

    #reporttime {
        margin-top: 10px;
        font-size: 14px;
    }

    .mainWeather {
        float: right;
        margin-top: 10px;
        margin-right: 10%;
        font-size: 120px;
    }

    .showBlock {
        margin-left: 10px;
    }
</style>