vue如何根据ip地址获取实时当地城市、时间、天气


需求说明:通常我们在做一个项目时,首页需要一个模块,根据ip地址获取实时当地城市、时间、天气。因为天气的接口需要城市这个参数,因此首先需要根据ip地址获取设备所在城市,再在回调函数中调用天气的接口。

1.定位ip地址所在城市

网上有很多获取位置的api,但是使用腾讯的位置服务api最好,返回的信息最全,包括经纬度,国家城市地区等。而其他绝大多数仅仅反馈了一个城市名。

1.1获取使用腾讯位置API资格

首先在https://lbs.qq.com/console/setting.html这个网页中 , 申请你自己key,也就是密钥,有了这个密钥,你才有资格使用位置服务api;

1.2设置授权IP

申请后,然后在官网上设置你的key,找到  key管理–》启用产品–》WebServiceAPI 选择授权IP 内容输入0.0.0.0-255.255.25.255

1.3使用API获取IP地理位置

这个接口是跨域的,腾讯给的方法是jsonp解决跨域,倘若是原生,我们可以直接用jq来进行jsonp跨域,可是axios根本不能进行jsonp跨域,网上查了半天,才找到vue中原来有一个依赖 vue-jsonp 用于专门解决jsonp跨域。

1.3.1处理跨域问题

安装下载vue-jsonp依赖

npm i -S vue-jsonp

在main.js中导入vue-jsonp

// 导入腾讯地图,获取用户当前位置
import VueJsonp from 'vue-jsonp'
Vue.prototype.$jsonp = VueJsonp
Vue.use(VueJsonp)

1.3.2请求接口,获取数据

在date中先定义需要展示的数据

data() {
    return {
      // 当地信息(城市、时间、地点、天气)
      local: {
        // ip地址所在城市
        city: '',
        // 所在城市温度
        temperature: '',
        // 天气类型
        type: '',
        // 时
        hour: '',
        // 分
        minute: '',
        // 月
        month: '',
        // 日
        date: '',
        // 星期几
        day: '',
        // 出勤率echart数据
      },
    }
 }

在methods中定义获取城市的方法getLocalCity,在created()中调用

getLocalCity() {
      var data = {
        key: 'KSPBZ-V5L33-5EM3D-35N5X-DIY66-CRF7J', //申请的密钥,写死就行
      }
      var url = 'https://apis.map.qq.com/ws/location/v1/ip' //这个就是地理位置信息的接口
      data.output = 'jsonp'
      this.$jsonp(url, data)
        .then((res) => {
          this.local.city = res.result.ad_info.city
          // 根据城市,获取当前天气和时间(在此先预留获取天气方法,完成后取消注释)
          // this.getLocalWeather(this.local.city)
          return res
        })
        .catch((error) => {
          console.log(error)
        })
    },

2.根据获取的城市名称获取当地天气

2.1引入axios

安装axios

npm install axios

在main.js中引入axios

import axios from "axios";
Vue.prototype.$axios = axios;  //此处根据项目情况来配置

2.2使用接口,获取当地天气

2.2.1声明定时器

在data中声明定时器,用于后期的销毁

timeId: '',

2.2.2使用接口获取实时天气数据

// 获取当地时间和天气
getLocalWeather(city) {
   if (city && city !== '') {
     this.$axios
       .get('http://wthrcdn.etouch.cn/weather_mini?city=' + city)
       .then((res) => {
         // 获取当天数据
         let todayWeather = res.data.forecast[0]
         if (todayWeather !== '') {
           // 获取温度,取平均值
           let high = todayWeather.high.split(' ')[1].slice(0, -1)
           let low = todayWeather.low.split(' ')[1].slice(0, -1)
           this.local.temperature = (parseInt(low) + parseInt(high)) / 2
           // 获取天气类型
           this.local.type = todayWeather.type
           // 获取星期几
           this.local.day = todayWeather.date.slice(-3)
           // 获取当前时间
           let newDate = new Date()
           this.local.hour = newDate.getHours()
           this.local.minute = newDate.getMinutes()
           this.local.month = newDate.getMonth() + 1
           this.local.date = newDate.getDate()
           // 使用定时器,实时刷新城市、天气和时间
           this.timeId = setTimeout(() => {
             this.getLocalCity(city)
           }, 1000)
         }
       })
       .catch(function(error) {
         console.log(error)
       })
   }
 },

很多时候人们会使用setInterval进行时间等实时数据的刷新,但是第一次执行需要setInterval的时间间隔,会造成用户的体验感下降。因此这里使用了setTimeout进行优化,每次在执行完成后再次进行调用

2.2.3销毁定时器

beforeDestroy() {
    if (this.timeId && this.timeId !== '') {
      clearTimeout(this.timeId)
      this.timeId = null
    }
  },

3.补充

因为返回的时间数据为一位数时,前面不会自动补0,因此可以定义一个时间规范管道:

/**
 * 处理月、日、时、分、秒等时间为个位数的情况
 * @param {String} string
 */
export function handleTime(time) {
  time = '' + time
  if (time && time.length === 1) {
    time = '0' + time
  }
  return time
}

在引入时间数据时进行使用:

{
   
   { local.hour | handleTime }}

如果有需要,可以进行收藏。
坚持写文章不容易,请各位看到这篇文章的朋友点个赞呗。

Guess you like

Origin blog.csdn.net/qq_39055970/article/details/107534143