最近因為公司需求,除了需要學習React之外,也要隨時預備一些舊產品重構成Vue的準備,像是最近公司的讀書會主題都以Vue為主了,雖然主題換成Vue,但是基本上有React的觀念,Vue的概念幾乎是一點就通了,可以說是更簡單容易懂。 這幾天有看到workshop的活動是以Vue為主題,剛好抓到機會可以趁機好好學一下Vue,那麼以下就來介紹專案一下。

專案介紹

詳細的介紹我都打在GitHub上了,有興趣的人可以到這邊去看一下
下面的介紹我主要以Vue為主要介紹,並且假設各位已經建立好基本的Vue了。

leaflet介紹

相信各位都很常用Google map找地點,但是你一定會有一個疑問,為什麼那些開發者都不直接使用Google map開發?因為$$呀!! 還記得年初的時候,有一個開發者開發了一個口罩地圖給大家使用,但是一瞬間就燒了好幾十萬。 也因為考量到實用性,所以open map成為一個折衷的選擇,很多公司有用到地圖的產品,通常也會這麼做。 詳細介紹可以參考官方網站,裡面的資料寫得很豐富。

leaflet使用方式

雖然官方講得很詳細,但是有時候挖資料就像是在走迷宮一樣,因此我這邊來幫忙引路一下。

  1. 到public設置

    1
    2
    3
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
    integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
    crossorigin=""/>
  2. 在你要顯示的地方加入地圖tag

    1
    <div id="map"></div>
  3. 安裝leaflet

    1
    npm install leaflet
  4. 引入leaflet

    1
    import leaflet from 'leaflet';
  5. 在Vue data裡面加入

    1
    2
    3
    4
    5
    6
    7
    ...
    data: () => ({
    ...
    Map: {},
    ...
    }),
    ...
  6. 在mounted加入地圖
    center表示一打開會在什麼座標出現,這邊以西門町的位置為例:[25.041956, 121.508791]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    mounted() {
    // leaflet文件
    // https://leafletjs.com/examples/quick-start/
    // https://leafletjs.com/reference-1.6.0.html#tilelayer-url-template
    // map 設定
    this.Map = leaflet.map('map', {
    center: [25.041956, 121.508791],
    zoom: 18,
    });
    leaflet.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
    maxZoom: 18,
    }).addTo(this.Map);
    },
  7. 加入map的css
    如果你沒加入大小的話,會看不到地圖

    1
    2
    3
    4
    5
    6
    <style scoped lang="scss">
    #map {
    position: relative;
    height: 100vh;
    }
    </style>

這些步驟做完的話,就完成啦~一開打網站就能看到地圖出現了
其他功能就要參考官方的methods介紹了

其他功能

以下可以大概提供一些可能會用到的一些methods

  • 新增座標 - marker
    這邊使用marker加入座標

    1
    2
    3
    4
    5
    6
    7
    8
    methods: {
    updateMarkers() {
    // 新增選擇的座標
    this.elements.forEach((element) => {
    leaflet.marker([element.lat, element.lng]).addTo(this.Map);
    });
    },
    },
  • 彈出訊息 - popup
    讓使用者點選座標可以觀看訊息,裡面可以放你寫好的HTML tags

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    methods: {
    updateMarkers() {
    // 新增選擇的座標
    this.elements.forEach((element) => {
    leaflet.marker([element.lat, element.lng])
    .bindPopup(`<p><strong style="font-size: 20px;">${element.sna}</strong></p>
    <small>更新時間: ${element.mday}</small>`)
    .addTo(this.Map);
    });
    },
    },
  • 移除座標 - eachLayer()、removeLayer()
    如果你想要移除已經新增的座標,可以使用這兩個功能

    1
    2
    3
    4
    5
    this.Map.eachLayer((layer) => {
    if (layer instanceof leaflet.Marker) {
    this.Map.removeLayer(layer);
    }
    });
  • 聚焦功能 - panTo
    如果你想要讓使用者選取座標之後,將畫面跳到指定的地方,可以使用panTo

    1
    2
    3
    4
    5
    6
    7
    8
    // 聚焦到選擇的座標 panTo
    // https://leafletjs.com/reference-1.6.0.html#map-panto
    this.city[0].districts.find((dist) => {
    if (dist.name === this.select.dist) {
    this.OSMap.panTo(new leaflet.LatLng(dist.latitude, dist.longitude));
    }
    return dist.name === this.select.dist;
    });
  • 聚焦功能 - flyTo
    跟panTo差不多,但是是有飛過去的特效。

    1
    this.Map.flyTo(new leaflet.LatLng(dist.latitude, dist.longitude), 15);

如何打API

這邊使用axios做示範

  1. 安裝axios

    1
    npm install --save axios vue-axios
  2. axios設置
    在App.vue設置使用Vue.use:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <template>
    <div id="app">
    <Map />
    </div>
    </template>
    <script>
    import axios from 'axios';
    import VueAxios from 'vue-axios';
    import Vue from 'vue';

    Vue.use(VueAxios, axios);

    export default {
    name: 'App',
    components: {
    Map,
    },
    };
    </script>

    <style lang="scss">
    </style>

  3. 在created加入axios
    因為已經在App加入use了,所以其他components可以用this呼叫axios。
    這邊請注意,get打出去之後一定要then,不然是接不到資料的,這其實也要看後端打的資料是什麼。
    只是這邊的例子是直接打json資料,所以考量的層面相對單純。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ...
    created() {
    const url = 'https://...../xxx.json';
    this.axios.get(url)
    .then((response) => {
    // do something
    return response;
    });
    },
    ...
  4. 接收資料
    只需要直接呼叫自己設置好的變數,即可輕鬆接收回傳的資料。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ...
    created() {
    const url = 'https://...../xxx.json';
    this.axios.get(url)
    .then((response) => {
    this.data = response.data;
    return response;
    });
    },
    ...

部署

我看網路上有人部署是用懶人sh檔,大概也傳到快爛掉了,以下請看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 懶人打包指令(僅限Linux based OS),請輸入:sh ./deploy.sh
#!/usr/bin/env sh

# 當發生錯誤時終止腳本
set -e

# 打包
npm run build

# cd 到打包完的目錄下
cd dist

# 初始化
git init
git add -A
git commit -m 'deploy'

# 部署到 https://<USERNAME>.github.io/<REPO>
git push -f git@github.com:yangyangisyou/ubike-map.git master:gh-pages

cd -

但是我部署並不是用上面的sh檔來部署,我還是跟以前一樣用gh-pages套件就夠了。
如果你用過就知道我在說什麼了,請看以下:

  1. 加入以下參數在package.json

    1
    2
    3
    ...
    "homepage": "https://<user-name>.github.io/<project-name>"
    ...
  2. 安裝gh-pages

    1
    npm install gh-pages
  3. 新增以下指令集在script
    這邊請注意,官方寫的指令是gh-pages -d build,但是Vue build完的目錄名稱叫做dist,並不是build。
    因此需要改成以下:

    1
    2
    "predeploy":"npm run build",
    "deploy":"gh-pages -d dist"
  4. 設置完之後,就能開始部署上線了

    1
    2
    npm run predeploy
    npm run deploy
  5. 查看結果
    查看結果請看:

    1
    <user-name>.github.io/<project-name>

雷點

  • Vue3.0設置
    因為我起的專案是Vue3.0,跟以前Vue2的設置是不太一樣的,例如部署的時候,config研究一陣子才部署成功。
    只要把vue.config.js路徑設定成以下即可
    1
    2
    3
    4
    5
    module.exports = {
    publicPath: process.env.NODE_ENV === 'production'
    ? '/'
    : '/'
    }

我看網路上很多人說要改/project/,但是部署在GitHub pages上路徑卻是’/‘。

CNAME

有需要設置客製化CNAME的話,請放在public下,直接放網域即可

1
example.nicetry.tw

結論

之前都是開發React,難得能夠給自己一個機會開發一下Vue玩玩看還蠻不錯的。
基本上開發網頁如果要轉換框架開發,主要需要了解他們的概念是什麼,有了概念就容易上手開發。