Vue实现大屏获取当前所处城市及当地天气(纯免费)

之前做过的大屏项目一般是在内网环境中使用,所以一般顶部不牵扯展示城市和天气。但是这次做的是放在外网的,所以简单实现一下展示城市名称和当前实时天气信息。

获取当前所处位置

获取当前定位可以通过浏览器原生的Geolocation API获取经纬度信息。

js 复制代码
function getLocation() {
	return new Promise((resolve, reject) => {
		if (navigator.geolocation) {
			navigator.geolocation.getCurrentPosition(
				(position) => {
					const lat = position.coords.latitude;
					const lon = position.coords.longitude;
					resolve({lat, lon});
					console.log('当前位置:', lat, lon);
				},
				(error) => {
					console.error('无法获取位置:', error.message);
					reject(error);
				}
			);
		}
	})
}

需要注意,Geolocation API是异步的,所以这里用 Promise 进行了简单的封装。另外这里只能获取到经纬度,无法获取到所在城市名称,需要通过逆地理编码的方式实现。

逆地理编码

目前国内主要是御三家 提供逆地理编码 的服务,但是都需要进行付费,不过唯一可以庆幸的是各家都有免费额度

如果你的大屏部署在外网,国外的Nominatim 是完全免费的,咱们这边目前是无法访问的。官网地址也放一个nominatim.openstreetmap.org

这里我以腾讯的逆地理编码服务为例子简单写一下:

js 复制代码
async function getCityName(lat, lon) {
	const sig = CryptoJs.MD5(`/ws/geocoder/v1/?key=${你的key}&location=${lat},${lon}${你的签名}`).toString();
	const {result} = await request.get(`/tencent/ws/geocoder/v1/?key=${你的key}&location=${lat},${lon}&sig=${sig}`);
	return `${result.address_component.city}-${result.address_component.district}`
}

这里需要代理一下,我这里的代理如下:

js 复制代码
'/tencent': {
    target: 'https://apis.map.qq.com',
    changeOrigin: true,
    rewrite: (path) => path.replace(/^\/tencent/, '')
},

获取天气

天气信息目前咱们这边有和风天气,提供了一定的免费额度。

但是我在网上找到一个外面的,但是咱们这边能访问到的Open-Meteo ,官方地址也放一下open-meteo.com

特点如下:

  • 无需注册、无 API Key、无调用限制
  • 支持全球经纬度实时天气 + 未来7天预报
  • 数据来源:欧洲中期天气预报中心(ECMWF)等权威机构

唯一不好的一点在于返回的都是英文数据,需要认为的转成中文。

js 复制代码
// 部分天气中英文映射
const WEATHER_CODE_MAP = {
	0: { en: 'Clear sky', zh: '晴' },
	1: { en: 'Mainly clear', zh: '晴转多云' },
	2: { en: 'Partly cloudy', zh: '多云' },
	3: { en: 'Overcast', zh: '阴' },
	45: { en: 'Fog', zh: '雾' },
	48: { en: 'Depositing rime fog', zh: '冻雾' },
	51: { en: 'Drizzle: Light', zh: '小雨' },
	53: { en: 'Drizzle: Moderate', zh: '中雨' },
	55: { en: 'Drizzle: Dense', zh: '大雨' },
	61: { en: 'Rain: Slight', zh: '小雨' },
	63: { en: 'Rain: Moderate', zh: '中雨' },
	65: { en: 'Rain: Heavy', zh: '大雨' },
	71: { en: 'Snow fall: Slight', zh: '小雪' },
	73: { en: 'Snow fall: Moderate', zh: '中雪' },
	75: { en: 'Snow fall: Heavy', zh: '大雪' },
	95: { en: 'Thunderstorm', zh: '雷阵雨' },
	96: { en: 'Thunderstorm with slight hail', zh: '雷阵雨伴小冰雹' },
	99: { en: 'Thunderstorm with heavy hail', zh: '雷阵雨伴大冰雹' }
};
js 复制代码
// 获取天气
async function getWeather(lat, lon) {
	const result = await request.get(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}&current_weather=true`);
	const code = result.current_weather.weathercode;
	return WEATHER_CODE_MAP[code] || {en: 'Unknown', zh: '未知'};
}

这个是不需要代理的,因为Open-Meteo 本身支持CORS

总结

获取经纬度和城市信息,以及天气信息在技术上没什么难度。

主要的问题点在于很多东西都是付费的,自己玩玩还好,但要是真的上线正式环境一定要防备被别人恶意刷爆。

之前我还见过一个大屏上实时展示天气状况,卫星地图上前面有一层蒙版展示。如果是下雨的话有雨滴打在屏幕上的感觉,效果非常不错,回头实现完分享给大家。

欢迎关注我的公众号李剑一,分享更多的干货,畅聊圈内八卦。

相关推荐
_果果然13 小时前
这 7 个免费 Lottie 动画网站,帮你省下一个设计师的工资
前端
QT.qtqtqtqtqt13 小时前
uni-app小程序前端开发笔记(更新中)
前端·笔记·小程序·uni-app
Aliex_git14 小时前
跨域请求笔记
前端·网络·笔记·学习
37方寸14 小时前
前端基础知识(Node.js)
前端·node.js
powerfulhell14 小时前
寒假python作业5
java·前端·python
木子啊15 小时前
前端组件化:模板继承拯救发际线
前端
三十_A15 小时前
零基础通过 Vue 3 实现前端视频录制 —— 从原理到实战
前端·vue.js·音视频
前端小菜袅15 小时前
PC端原样显示移动端页面方案
开发语言·前端·javascript·postcss·px-to-viewport·移动端适配pc端
We་ct15 小时前
LeetCode 228. 汇总区间:解题思路+代码详解
前端·算法·leetcode·typescript