1. 程式人生 > >Vue專案用百度地圖定位

Vue專案用百度地圖定位

1.首先我們先在本地獲取到城市定位

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微軟雅黑";}
    </style>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的金鑰"></script>
    <title>IP定位獲取當前城市</title>
</head>
<body>
    <div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
    // 百度地圖API功能
    //var map = new BMap.Map("allmap");
    //var point = new BMap.Point(116.331398,39.897445);
    //map.centerAndZoom(point,12);

    function myFun(result){
        var cityName = result.name;
        //map.setCenter(cityName);
        console.log("當前定位城市:"+cityName);
    }
    var myCity = new BMap.LocalCity();
    myCity.get(myFun);
    console.log('不好意思,我先走一步');
</script>

頁面效果

需要注意的是script標籤引入百度地圖時記得換成你的開發金鑰。

接下來我們可以去Vue專案中獲取當前城市了。

1.在index.js中引入

<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的金鑰"></script>

2.我們瞭解一下模組化程式設計

模組化程式設計的基本思想是自頂向下、逐步分解、分而治之,即將一個較大的程式按照功能分割成一些小模組,各模組相對獨立、功能單一、結構清晰、介面簡單。

我們整個Vue專案就是一個大的程式,而用百度地圖通過IP定位獲取當前城市就是其中的一個小功能。符合我們前面說的模組化程式設計思想。

前端用模組化開發,剛好ES6就為我們提供了 export 和 import

export

export語句用於在建立JavaScript模組時,從模組中匯出函式、物件或原始值,以便其他程式可以通過 import 語句使用它們。

import

import語句用於匯入由另一個模組匯出的繫結。無論是否聲明瞭 strict mode ,匯入的模組都執行在嚴格模式下。import語句不能在嵌入式指令碼中使用。

其中的語法這裡不詳細介紹,但有需要注意的地方是模組語法的限制

只能在模組的頂級作用域使用 export 和 import

if (flag) {
    export flag; // 語法錯誤
}

模組化開發瞭解後,我們開始封裝用百度地圖通過IP定位獲取當前城市的js

3.封裝用百度地圖通過IP定位獲取當前城市的js

1.建立getUserLocation.js檔案

// 這樣匯出,引入的是 ''
let currentCity = '';//當前城市
function getCurrentCity(result){
  currentCity = result.name;
  console.log("當前定位城市:" + currentCity);
}
var myCity = new BMap.LocalCity();
myCity.get(getCurrentCity);
console.log('不好意思,我先走一步' + currentCity);
export default currentCity

細心的朋友在上面的頁面效果時應該就發現了我們這樣匯出的變數是我們第一次複製的空字串。

為什麼會出現上面的結果?瞭解 JS執行順序 的應該知道,JS是一門單執行緒解釋型語言,JS會從上到下排序執行。 排序執行,那當然就有排序的規則,這個自行了解。我這裡說的就是JS會自上而下先執行頂層的語句(export),遇到回撥函式,會塞入非同步佇列中等待執行,等頂層的語句都執行完畢再依次執行非同步佇列中的函式(getCurrentCity),非同步佇列執行時也是同理。

那我們回到上面的問題,我們可以把問題歸納一下:在模組化開發時,非同步獲取到的資料如何匯出?或者說不論同步或者非同步,我們如何能拿到我們想要的值,完成業務?

我們再回到上面的程式碼,發現我們並不是沒拿到值,而是拿到值的時機不對。那我們就會想直接不模組化開發了,把我們的業務寫在回撥函式中好了。 當然,這樣也是可以拿到值的。

但這樣給我們帶來的風險是:
1.那以後我需要用到這個值的業務是不是都要寫在這個回撥函式內?如test函式
2.那其他專案中需要用到這個功能時,我們是不是再把這份程式碼檢查一遍,把其他的業務刪除掉,再複製過去?
......
這樣普通的需求成千上萬個,那我們是不是都要這麼費力不討好的寫下去?

前面我們說到問題的關鍵在於匯出值的時機不對,因為非同步操作,匯出的值是我們初始定義的值。那我們會想,要不把生成值的過程匯出,此例就是匯出myCity.get函式。

var myCity = new BMap.LocalCity()
export default myCity.get

但我在元件中拿到卻是這樣的:


這個應該是他的原始碼,其中this是上下文,我們匯出這個get函式再在元件中呼叫時,this是指向vue例項的,而他的this是要指向Hd.prototype的。所以此路不通。

我們去百度搜索下:模組化開發非同步獲取到的資料如何匯出?
答案就是ES6的 promise,我們不再匯出單個的值,我們匯出一個封裝好的promise 物件
Promise 介紹:

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future

意思是:
1.promise是一個在promise建立時不一定知道最終值的一個代理。
2.它允許您將處理程式與非同步操作的最終成功值或失敗原因相關聯
3.它讓非同步方法返回類似同步方法的值
4.這個非同步方法不是立即返回最終值,而是返回一個promise,在將來的某個時候提供該值

我們來把上面的非同步函式封裝成promise,再匯出:

let getCurrentCityName = function () {
  return new Promise(function (resolve, reject) {
    let myCity = new BMap.LocalCity()
    myCity.get(function (result) {
      resolve(result.name)
    })
  })
}

export default getCurrentCityName

我這裡獲取到的值commit到vuex的mutations裡