适用于中级使用者:对百度地图的使用和应用创建有了解过的。主要是说明在vue中如何使用,怎么引入JavaScript API和使用,以及访问web服务端API遇跨域问题。
实现效果:页面里面获得天气信息
思路:就是获得城市定位后->根据城市编码获得天气。
申请账号咱们不赘述,在控制台应用管理里面创建应用,主要是为了获取AK
一、JavaScript API的使用,与项目的结合度较高,需要通过yarn或者npm导入依赖包
1.在vue里面引入百度地图
在index.html添加
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=GSqsMKaN3s0DzqgqGIkHwZNspEkwe1Vl&services=false"></script>
2.新建文件bmap.js 来初始化,此处是绑定的是浏览器端的AK,该步骤也算作一个封装
export default {
init: function () {
const AK = "3s9RVp........"; //你的AK
const BMap_URL =
"https://api.map.baidu.com/api?v=2.0&ak=" +
AK +
"&s=1&callback=onBMapCallback";
return new Promise((resolve, reject) => {
// 如果已加载直接返回
if (typeof BMap !== "undefined") {
resolve(BMap);
return true;
}
// 百度地图异步加载回调处理
window.onBMapCallback = function () {
resolve(BMap);
};
let getCurrentCityName = function () {
return new Promise(function (resolve, reject) {
let myCity = new BMap.LocalCity();
myCity.get(function (result) {
resolve(result.name);
});
});
};
// 插入script脚本
let scriptNode = document.createElement("script");
scriptNode.setAttribute(type, "text/javascript");
scriptNode.setAttribute("src", BMap_URL);
document.body.appendChild(scriptNode);
});
},
};
3.页面中使用,我这里通过Geolocation()来获取城市编码。但是结果中并没有显示,之后我又加了一步通过经纬度获取城市编码。
myBMap.init().then((BMap) => {
const geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(
(position) => {
var temp = position.point.lat + "," + position.point.lng;
this.city = position.address.city; //获取城市信息
},
(e) => {
console.log(e);
console.log("定位失败");
},
{ provider: "baidu" }
);
});
二、web服务端API的使用
1、解决跨域问题,在vue.config,js文件里面配置,我这是3.0项目,对2.0配置大家百度即可
module.exports = {
publicPath: "/",
devServer: {
proxy: {
"/dmap": {
target: "https://api.map.baidu.com", //这里后台的地址模拟的;应该填写你们真实的后台接口
ws: true,
changOrigin: true, //允许跨域
pathRewrite: {
"^/dmap": "", //请求的时候使用这个api就可以
},
},
},
},
}
2.怎么使用服务端API,获取城市id
this.$http.get("/dmap/reverse_geocoding/v3/?ak=3zIEC10W0fzHQXoCTYn7MRGEsX1OZvTF&location&output=json&coordtype=wgs84ll&location=" +temp).then((res) => {
if (res.status == 0) {
}
});
3.通过城市id获取天气
this.$http.get(
"/dmap/weather/v1/?district_id=" +
res.result.addressComponent.adcode +
"&data_type=all&ak=3zIEC10W0fzHQXoCTYn7MRGEsX1OZvTF"
)
.then((res) => {
if (res.status == 0) {
this.wendu = res.result.now.temp;
this.fengxiang = res.result.now.wind_dir;
this.type = res.result.now.text;
this.fengli = res.result.now.wind_class;
}
});
4.在跨域解决方面其实还可以通过jsonp来解决,网上说引入vue-jsonp即可,我引入之后在main.js文件里面引入到vue实例时候控制台就出现报错。说是undefined install,这个我也没有深究是咋回事,就没有使用这步实现。但是之前在写uniapp项目时候实现H5定位时候使用过,在这把代码跟大家分享一下。使用还是很简单的。(注意这里使用的是腾讯地图哦)
终端 yarn add jsonp
getCurrentCity(){
var temp=this.form.lat+','+this.form.lng
console.log(temp)
this.$jsonp('https://apis.map.qq.com/ws/geocoder/v1?coord_type=5&get_poi=1&output=jsonp&poi_options=page_size=1;page_index=1' , {
key: 'LBVBZ-YWKCO-POPWN-S2SJR-3TVMO-XWFH5',
location:temp
}).then((res)=>{
console.log(res.result)
this.locations=res.result.address;
uni.showToast({
title:"定位成功",
duration:2000,
icon:'none'
})
})
5.1这里要补充一个axios封装后使用于访问封装baseURL地址之外,主要分享的是,上面调用服务端API时候直接使用$http(封装好的的axios),当发出请求的时候在前面必然会出现baseUrl拼接。怎么排除baseUrl访问咱们后端服务器之外地址呢,其实就是在前置拦截这块去改变。直接把bsdeURL给清空。
// 如果url纯在ak字段,修改banseUrl
if (config.url.indexOf("ak") > -1) {
config.baseURL = "";
}
5.2这是我的vue项目axios的封装,各类封装都大同小异,绑定一个基础的访问路径,做前置拦截和后置拦截。前置一般是对请求头中Content-Type进行修改,像图片上传和一般的获得信息对Content-Type的类型要求是不一样的。后置拦截主要是做跳转拦截,当返回中存在401,就跳转登录页面。
/**
* Http请求封装类
* axios参考:https://segmentfault.com/a/1190000008470355#articleHeader16
*/
import qs from "qs";
import axios from "axios";
import router from "@/router/";
import store from "@/store/";
import { message } from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
// axios 配置
axios.defaults.timeout = 10000;
axios.defaults.baseURL = process.env.VUE_APP_URL;
axios.defaults.withCredentials = false; // 设置请求携带cookies
let isRefreshToken = false;
let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let cancelToken = axios.CancelToken;
let removePending = (ever) => {
for (let p in pending) {
if (pending[p].u === ever.url + "&" + ever.method) {
//当当前请求在数组中存在时执行函数体
pending[p].f(); //执行取消操作
pending.splice(p, 1); //把这条记录从数组中移除
}
}
};
// 添加请求拦截器
axios.interceptors.request.use(
(config) => {
// 每次发起请求前取消掉在进行中的相同请求
removePending(config);
config.cancelToken = new cancelToken((c) => {
// 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
pending.push({ u: config.url + "&" + config.method, f: c });
});
// 如果url纯在ak字段,修改banseUrl
if (config.url.indexOf("ak") > -1) {
config.baseURL = "";
}
if (config.url == "/file/upload") {
config.headers["Content-Type"] = "multipart/form-data";
}
if (store.getters.Authorization) {
config.headers[
"Authorization"
] = `Bearer ${store.getters.Authorization.token}`;
}
return config;
},
(error) => {
message.error("请求超时");
return Promise.reject(error);
}
);
// 添加返回拦截器
axios.interceptors.response.use(
(response) => {
//在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
removePending(response.config);
if (!isRefreshToken) {
if (store.getters.TokenExpire - 60000 <= new Date().getTime()) {
if (store.state.User.Authorization) {
store.dispatch("refreshToken");
isRefreshToken = true;
}
}
}
return response.data;
},
(error) => {
if (error.response) {
switch (error.response.status) {
case 401:
message.error(error.response.data.msg);
// 返回 401 清除token信息并跳转到登录页面
if (window.location.pathname != "/login") {
localStorage.clear();
router.replace({
path: "/login",
});
}
break;
default:
message.error(error.response.data.msg);
break;
}
}
// 返回接口返回的错误信息
return Promise.reject(error);
}
);
export default axios;
总结:百度地图的接口说明文档好难理解,看网上大家分享的片段,才一点点的知道怎么使用了,感谢万能互联网,文章系原创转发注明出处。若有问题请大家指出!