Vue項(xiàng)目引用百度地圖并實(shí)現(xiàn)搜索定位等功能(案例分析)
本文給大家介紹如何在vue項(xiàng)目中引用百度地圖,并設(shè)計(jì)實(shí)現(xiàn)簡單的地圖定位、地址搜索功能。
Tip:本篇文章為案例分析,技術(shù)點(diǎn)較多,所以篇幅較長,認(rèn)真閱覽的你一定會學(xué)到很多知識。
前言:百度地圖開放平臺 給開發(fā)者們提供了豐富的地圖功能與服務(wù),使我們的項(xiàng)目中可以輕松地實(shí)現(xiàn)地圖定位、地址搜索、路線導(dǎo)航等功能。本文給大家介紹如何在vue項(xiàng)目中引用百度地圖,并設(shè)計(jì)實(shí)現(xiàn)簡單的地圖定位、地址搜索功能。
一、效果圖及功能點(diǎn)
先來看一下效果圖
效果圖看不夠? 點(diǎn)此 試試在線操作?。ǔ醮芜M(jìn)入加載較慢,請耐心等待)
功能點(diǎn):
掛載百度地圖封裝逆地址解析函數(shù)(根據(jù)坐標(biāo)點(diǎn)獲取詳細(xì)地址)設(shè)置圖像標(biāo)注并綁定拖拽標(biāo)注結(jié)束后事件添加(右上角)平移縮放控件添加(左下角)定位控件瀏覽器定位(定位當(dāng)前地點(diǎn))綁定點(diǎn)擊地圖任意點(diǎn)事件結(jié)合element-ui實(shí)現(xiàn)輸入提示選取地址并定位功能
二、前期準(zhǔn)備
在正式開發(fā)之前,我們先做好以下準(zhǔn)備:
- 在你的vue項(xiàng)目中引入element-ui (引入方法 戳這)
說明:本案例是結(jié)合element-ui進(jìn)行開發(fā),主要是為方便實(shí)現(xiàn)上面第8點(diǎn)功能,大家若是引入其他UI框架也可以,功能實(shí)現(xiàn)方法參照本案例自行修改即可。
- 申請百度地圖AK
前往 百度地圖開放平臺控制臺 ,登錄百度賬號,創(chuàng)建應(yīng)用即得。
三、引入百度地圖
下面介紹如何在vue項(xiàng)目中引入百度地圖
方法一
第1步:在 index.html 中引入下面代碼,注意將你的AK代入
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=您的密鑰"></script>
第2步:在 webpack.base.conf.js 添加externals.BMap配置,與entry平級,內(nèi)容如下,
entry: { app: ['babel-polyfill', './src/main.js'] }, externals: { BMap: 'BMap' }
第3步:在組件中引入BMap
import BMap from 'BMap'
方法二
我們知道,vue-cli 3.0+ 的版本已經(jīng)取消了webpack.conf這些文件了,所以上面的方法就不適用了。而且,方法一在index.html中全局引入百度api,有點(diǎn)耗性能。更多時(shí)候我們只希望在單個(gè)組件里按需引入即可,所以下面介紹的是以封裝的方法引入。
第1步:在你的項(xiàng)目js資源文件夾下新建loadBMap.js文件,內(nèi)容如下:
/** * 動(dòng)態(tài)加載百度地圖api函數(shù) * @param {String} ak 百度地圖AK,必傳 */ export default function loadBMap(ak) { return new Promise(function(resolve, reject) { if (typeof window.BMap !== 'undefined') { resolve(window.BMap) return true } window.onBMapCallback = function() { resolve(window.BMap) } let script = document.createElement('script') script.type = 'text/javascript' script.src = 'http://api.map.baidu.com/api?v=3.0&ak=' + ak + '&callback=onBMapCallback' script.onerror = reject document.head.appendChild(script) }) }
第2步:在組件中引入loadBMap函數(shù)
import loadBMap from '@/<js資源文件夾>/loadBMap.js'
第3步:在mounted中調(diào)用 loadBMap()
//這里運(yùn)用async/await 進(jìn)行異步處理,保證BMap加載進(jìn)來后才執(zhí)行后面的操作 async mounted() { await loadBMap('您的密鑰') //加載引入BMap ... }
這樣就在當(dāng)前組件中引入百度地圖 BMap 了,可以開始開發(fā)了。
四、功能解析
下面開始對上述所列 8 點(diǎn)功能進(jìn)行詳細(xì)的代碼解析。
說明:本文用的是方法一引入百度地圖,源碼 用的是方法二
1、掛載百度地圖
首先需要給地圖分配一個(gè)容器,并設(shè)置寬高
<div id="map-container" style="width:100%;height:500px;"></div>
根據(jù)需求,定義data參數(shù)
data() { return { form: { address: '', //詳細(xì)地址 addrPoint: { //詳細(xì)地址經(jīng)緯度 lng: 0, lat: 0 } }, map: '', //地圖實(shí)例 mk: '' //Marker實(shí)例 } }
初始化地圖
methods: { initMap() { var that = this; this.map = new BMap.Map("map-container", {enableMapClick:false}) //新建地圖實(shí)例,enableMapClick:false :禁用地圖默認(rèn)點(diǎn)擊彈框 var point = new BMap.Point(113.30765,23.12005); this.map.centerAndZoom(point,19) } }, mounted() { this.initMap() }
到此,就可以在你的頁面上看到地圖啦!
2、封裝逆地址解析函數(shù)
參考百度地圖 逆地址解析 示例demo,封裝一個(gè)逆地址解析函數(shù),供下面的功能調(diào)用。
/** * 逆地址解析函數(shù)(根據(jù)坐標(biāo)點(diǎn)獲取詳細(xì)地址) * @param {Object} point 百度地圖坐標(biāo)點(diǎn),必傳 */ getAddrByPoint(point){ var that = this; var geco = new BMap.Geocoder(); geco.getLocation(point, function(res){ console.log(res) //內(nèi)容見下圖 that.mk.setPosition(point) //重新設(shè)置標(biāo)注的地理坐標(biāo) that.map.panTo(point) //將地圖的中心點(diǎn)更改為給定的點(diǎn) that.form.address = res.address; //記錄該點(diǎn)的詳細(xì)地址信息 that.form.addrPoint = point; //記錄當(dāng)前坐標(biāo)點(diǎn) }) }
3、設(shè)置圖像標(biāo)注并綁定拖拽標(biāo)注結(jié)束后事件
圖像標(biāo)注Marker是百度地圖覆蓋物類中的其中一種,它用來標(biāo)識當(dāng)前坐標(biāo)點(diǎn)的位置,也就是我們在地圖上所看到的小紅點(diǎn)(當(dāng)然這個(gè)點(diǎn)也可以自定義圖標(biāo)樣式,這里我們不說,有興趣的可以參考百度地圖覆蓋物示例 - 設(shè)置點(diǎn)的新圖標(biāo))。
設(shè)置圖像標(biāo)注很簡單,只需要下面兩行代碼
initMap() { ... this.mk = new BMap.Marker(point,{enableDragging:true}) //創(chuàng)建一個(gè)圖像標(biāo)注實(shí)例,enableDragging:是否啟用拖拽,默認(rèn)為false this.map.addOverlay(this.mk) //將覆蓋物添加到地圖中 }
這樣你就可以在地圖上看到小紅點(diǎn)啦,接下來我們給這個(gè)點(diǎn)綁定拖拽事件。
拖拽事件有三類,dragstart(開始拖拽時(shí)觸發(fā))、dragging(拖拽過程中觸發(fā))和dragend(拖拽結(jié)束時(shí)觸發(fā)),實(shí)際項(xiàng)目中我們更注重的是拖拽標(biāo)注結(jié)束后的位置信息,因此我們在這給標(biāo)注綁定拖拽結(jié)束后事件:
initMap() { ... this.mk.addEventListener('dragend', function(e){ that.getAddrByPoint(e.point) //拖拽結(jié)束后調(diào)用逆地址解析函數(shù),e.point為拖拽后的地理坐標(biāo) }) }
注意:這里我們將代碼寫在上面定義的 initMap 函數(shù)中,地圖初始化時(shí)一同執(zhí)行即可
4、添加(右上角)平移縮放控件
百度地圖提供了很多的 控件類,方便我們查看和操作地圖。本案例只解析平移縮放控件NavigationControl 和 地圖定位控件GeolocationControl,其他控件可 參考示例 自行學(xué)習(xí)。
下面我們先引入平移縮放控件并將其位置置于右上角:
initMap() { ... var navigationControl = new BMap.NavigationControl({ //創(chuàng)建一個(gè)特定樣式的地圖平移縮放控件 anchor: BMAP_ANCHOR_TOP_RIGHT, //靠右上角位置 type: BMAP_NAVIGATION_CONTROL_SMALL //SMALL控件類型 }) this.map.addControl(navigationControl ) //將控件添加到地圖 }
附:
anchor參數(shù)解析
BMAP_ANCHOR_TOP_LEFT | 控件將定位到地圖的左上角
BMAP_ANCHOR_TOP_RIGHT | 控件將定位到地圖的右上角
BMAP_ANCHOR_BOTTOM_LEFT | 控件將定位到地圖的左下角
BMAP_ANCHOR_BOTTOM_RIGHT | 控件將定位到地圖的右下角
type參數(shù)解析
BMAP_NAVIGATION_CONTROL_LARGE | 標(biāo)準(zhǔn)的平移縮放控件(包括平移、縮放按鈕和滑塊)
BMAP_NAVIGATION_CONTROL_SMALL | 僅包含平移和縮放按鈕
BMAP_NAVIGATION_CONTROL_PAN | 僅包含平移按鈕
BMAP_NAVIGATION_CONTROL_ZOOM | 僅包含縮放按鈕
5、添加(左下角)定位控件
下面我們引入地圖定位控件并將其位置置于左下角:
initMap() { ... var geolocationControl = new BMap.GeolocationControl({anchor: BMAP_ANCHOR_BOTTOM_LEFT}) //創(chuàng)建一個(gè)地圖定位控件 geolocationControl.addEventListener("locationSuccess", function(e){ //綁定定位成功后事件 that.getAddrByPoint(e.point) //定位成功后調(diào)用逆地址解析函數(shù) }); geolocationControl.addEventListener("locationError",function(e){ //綁定定位失敗后事件 alert(e.message); }); this.map.addControl(geolocationControl) //將控件添加到地圖 }
6、瀏覽器定位
參考百度地圖 瀏覽器定位 示例demo,進(jìn)入頁面,我們將坐標(biāo)定位到當(dāng)前所在地坐標(biāo)。
/** * 瀏覽器定位函數(shù) */ geolocation() { var that = this; var geolocation = new BMap.Geolocation(); geolocation.getCurrentPosition(function(res){ if(this.getStatus() == BMAP_STATUS_SUCCESS){ that.getAddrByPoint(res.point) //當(dāng)成功時(shí),調(diào)用逆地址解析函數(shù) } else { alert('failed'+this.getStatus()); //失敗時(shí),彈出失敗狀態(tài)碼 } },{enableHighAccuracy: true}) //enableHighAccuracy:是否要求瀏覽器獲取最佳效果,默認(rèn)為false }
同樣在initMap中調(diào)用即可
initMap() { ... this.geolocation() }
7、綁定點(diǎn)擊地圖任意點(diǎn)事件
在地圖上選取地址。點(diǎn)擊地圖上任意點(diǎn),都將獲取該點(diǎn)的地址信息。
initMap() { ... this.map.addEventListener('click', function(e){ //給地圖綁定點(diǎn)擊事件 that.getAddrByPoint(e.point) //點(diǎn)擊后調(diào)用逆地址解析函數(shù) }) }
8、結(jié)合element-ui實(shí)現(xiàn)輸入提示選取地址并定位功能
最后是本案例的主要功能,輸入框輸入關(guān)鍵字搜索地址,調(diào)用百度地圖LocalSearch服務(wù)進(jìn)行檢索。
首先,我們需要寫入一個(gè)輸入框。這里利用的是element-ui的 <el-autocomplete>組件,該組件提供了fetch-suggestions屬性和select事件【參考文檔】,方便我們把檢索結(jié)果遍歷顯示出來并進(jìn)行選擇操作。
<el-autocomplete style="width:100%;" popper-class="autoAddressClass" v-model="form.address" :fetch-suggestions="querySearchAsync" :trigger-on-focus="false" placeholder="詳細(xì)地址" @select="handleSelect" clearable> <template slot-scope="{ item }"> <i class="el-icon-search fl mgr10"></i> <div style="overflow:hidden;"> <div class="title">{{ item.title }}</div> <span class="address ellipsis">{{ item.address }}</span> </div> </template> </el-autocomplete>
接下來需提供兩個(gè)方法:
querySearchAsync:搜索建議方法(參考百度地圖檢索示例 - 本地檢索的數(shù)據(jù)接口)
querySearchAsync(str,cb){ var options = { onSearchComplete: function(res){ //檢索完成后的回調(diào)函數(shù) var s = []; if (local.getStatus() == BMAP_STATUS_SUCCESS){ for (var i = 0; i < res.getCurrentNumPois(); i ++){ s.push(res.getPoi(i)); } cb(s) //獲取到數(shù)據(jù)時(shí),通過回調(diào)函數(shù)cb返回到<el-autocomplete>組件中進(jìn)行顯示 } else{ cb(s) } } } var local = new BMap.LocalSearch(this.map, options) //創(chuàng)建LocalSearch構(gòu)造函數(shù) local.search(str) //調(diào)用search方法,根據(jù)檢索詞str發(fā)起檢索 }
handleSelect:點(diǎn)擊選中建議項(xiàng)時(shí)觸發(fā)的方法
handleSelect(item) { this.form.address = item.address + item.title; //記錄詳細(xì)地址,含建筑物名 this.form.addrPoint = item.point; //記錄當(dāng)前選中地址坐標(biāo) this.map.clearOverlays() //清除地圖上所有覆蓋物 this.mk = new BMap.Marker(item.point) //根據(jù)所選坐標(biāo)重新創(chuàng)建Marker this.map.addOverlay(this.mk) //將覆蓋物重新添加到地圖中 this.map.panTo(item.point) //將地圖的中心點(diǎn)更改為選定坐標(biāo)點(diǎn) }
最后再稍微處理一下autocomplete組件的下拉款樣式
.autoAddressClass{ li { i.el-icon-search {margin-top:11px;} .mgr10 {margin-right: 10px;} .title { text-overflow: ellipsis; overflow: hidden; } .address { line-height: 1; font-size: 12px; color: #b4b4b4; margin-bottom: 5px; } } }
至此,我們就完成了上面所有的功能點(diǎn)。
附:
項(xiàng)目源碼git地址:vue-admin-web
項(xiàng)目線上地址:vue-admin-web/BMap
到此這篇關(guān)于Vue項(xiàng)目引用百度地圖并實(shí)現(xiàn)搜索定位等功能(案例分析)的文章就介紹到這了,更多相關(guān)vue百度地圖搜索定位內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于vue3+echart5?遇到的坑?Cannot?read?properties?of?undefine
這篇文章主要介紹了vue3+echart5?遇到的坑?Cannot?read?properties?of?undefined?(reading?'type'),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04element-ui中表格設(shè)置正確的排序及設(shè)置默認(rèn)排序
表格中有時(shí)候會有排序的需求,下面這篇文章主要給大家介紹了關(guān)于element-ui中表格設(shè)置正確的排序及設(shè)置默認(rèn)排序的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05vue項(xiàng)目中解決 IOS + H5 滑動(dòng)邊界橡皮筋彈性效果(解決思路)
最近遇到一個(gè)問題,我們在企業(yè)微信中的 H5 項(xiàng)目中需要用到table表格(支持懶加載 上劃加載數(shù)據(jù)),但是他們在鎖頭、鎖列的情況下,依舊會出現(xiàn)邊界橡皮筋效果,這篇文章主要介紹了vue項(xiàng)目中解決 IOS + H5 滑動(dòng)邊界橡皮筋彈性效果,需要的朋友可以參考下2023-02-02Vue 數(shù)組和對象更新,但是頁面沒有刷新的解決方式
今天小編就為大家分享一篇Vue 數(shù)組和對象更新,但是頁面沒有刷新的解決方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11Vue移動(dòng)端項(xiàng)目實(shí)現(xiàn)使用手機(jī)預(yù)覽調(diào)試操作
這篇文章主要介紹了Vue移動(dòng)端項(xiàng)目實(shí)現(xiàn)使用手機(jī)預(yù)覽調(diào)試操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Vue中$on和$emit的實(shí)現(xiàn)原理分析
這篇文章主要介紹了Vue中$on和$emit的實(shí)現(xiàn)原理分析,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05