需求:
1:在项目中加载谷歌地图,众所周知,访问谷歌是需要使用vpn的,没有vpn,或者vpn在不稳定的情况下谷歌就会自动报错!(解决这个报错问题)
2:使用谷歌地图我们就需要使用谷歌js,这是属于第三方的js,我们需求中不允许在index.html中加载,产品给我们提及需要按需加载,在哪里使用就在哪里加载。
做法具体如下:
(1)首先,因为我们的谷歌地图加载呢是需要一个key的,所以需要我们在vue中定义一个key,然后把这个key传给我们的动态加载函数。
const googleMapsCDN = 'https://www.google.com/maps/api/js?libraries=geometry&key=' + GOOGLE_KEY
除此之外我们需要定义一个初始化的值,我们把这个值保存在vuex里面。
import Vue from 'vue'
import Vuex from 'vuex'
const state = {
requestState: 'init'
}
const mutations = {
changeRequestState(state, val) {
state.requestState = val
}
}
export default {
state,
mutations
}
(2)我们需要写一个函数,在函数里面动态加载js
loadScript( url, callback ){
var script = document.createElement('script'),
fn = callback || function(){};
script.type = 'text/javascript';
if(script.readyState){
script.onreadystatechange = function(){
if( script.readyState == 'loaded' || script.readyState == 'complete' ){
script.onreadystatechange = null;
fn('success');
}
};
}else{
//其他浏览器
script.onload = function(){
fn('success');
};
script.onerror = function() {
fn('fail');
}
}
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
}
(3)写初始化加载我们谷歌js的代码,如果我们的requestState状态值是“success”那么我们就初始化我们的地图,反之我们不做任何操作。
//动态cdn加载js
initCdn() {
this.loadScript(googleMapsCDN, (requestState) => {
if(requestState == 'success'){
// cdn加载成功就初始化地图
this.initMap()
} else {
// cdn加载失败
console.log('谷歌地图apiCDN加载失败')
}
// 记录cdn加载状态
this.changeState(requestState)
})
},
//初始化地图
initMap() {
this.map = new google.maps.Map(document.getElementById('map'), {
center: this.pointions,
zoom: 15
});
},
(4)我们需要根据我们存在vuex里面的值来判断我们是不是第一次加载这个地图,如果是的话我们就走这个函数,如果已经加载过我们就需要再加载这个地图的js。
这里呢,我们选择在created钩子函数中来判断。
created(){
// 没有加载谷歌地图cdn的时候再去加载,已经加载过就不用再去加载
if(this.requestState == 'init'){
this.initCdn()
}
},
(5)做好了这些基本的工作之后接下来就是我们在项目中的使用了:
①这个函数是我们在父组件中使用的,我们获取地址后会调用这个函数然后拿到我们地址,我们拿到地址后就检查我们的cdn请求状态。
②我们判断我们的cdn有没有加载过,如果加载过我们就直接请求我们的地图,根据我们的地址来找坐标。
③如果我们的cdn此时还没有加载完,那么我们需要开启一个定时器来监听cdn家在状态,在监听加载完成之后等待地图初始化完毕,然后我们清除掉计时器。
④如果加载失败,直接清除掉计时器。
// 获取地址检查cdn请求状态
zoomToArea(mapdata) {
if(mapdata && mapdata.address){
this.addresVal = mapdata.address
}
let that = this
// 当使用到地图的页面得到地址后会请求此函数来获取坐标
// 如果此时cdn还未加载完毕就开启一个定时器监听cdn加载状态
if(that.requestState == 'init'){
that.requestClearTime = setInterval(() => {
// 等到加载成功后就继续等待地图初始化完毕
if(that.requestState == 'success'){
// 地图初始化完毕以后获取地址并清除定时器
if(that.map){
that.getCoordinate()
clearInterval(that.requestClearTime);
}
}
// 如果加载失败清除定时器
if(that.requestState == 'fail'){
clearInterval(that.requestClearTime);
}
}, 1000);
} else if(that.requestState == 'success'){
// 如果已经加载过就直接调用
// 此处写else if是因为还会有加载失败的情况,加载失败不做处理
that.getCoordinate()
}
},
// 根据地址找坐标
getCoordinate(){
let geocoder = new google.maps.Geocoder();
let address = this.addresVal;
let that = this
geocoder.geocode(
{
address: address
}, (results, status)=> {
if (status == google.maps.GeocoderStatus.OK) {
var regionInfo = results[0];
that.map.setCenter(regionInfo.geometry.location);
that.map.setZoom(15);
that.pointions = regionInfo.geometry.location;
that.reloadMarker(regionInfo)
this.$emit('oninputVal',this.addresVal)
}
});
},
总之呢,这个需求做完基本就是这样的,代码是部分代码哦,如果我写的有不对的地方恳请各位大佬们指出哦。当然,如果有需要了解在项目中如何使用谷歌地图的朋友可以直接找我哈。