iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 25
0
Modern Web

《你的地圖會說話? WebGIS與JavaScript的情感交織》系列 第 25

[Vue2Leaflet系列一] 從vue-cli安裝到建置地圖

Web前端瞬息萬變的今天,
相信大家都有聽過前端主流的三大框架:angular、react、vue,
如今也有許多前端工程,邁向模組化、系統化的開發模式,
並且套用框架,定義每支程式該有的職責,達到關注點分離。

那麼WebGIS發展至今,究竟能否跟上主流框架們的演進?
套用主流框架來進行開發?
今天就讓我們來介紹WebGIS結合vue.js的實作吧!
今天使用的Vue2Leaflet GitHub


建置vue環境

今天要使用的是vue-cli,並且用webpack建置,如果還沒裝npm及webpack的人,請先參考[番外篇] 從npm安裝到活用Webpack Babel - 十分鐘就上手

↓ 首先先安裝vue-cli

    npm i vue-cli -g

npm i & npm install

  • npm i是npm install的簡寫,使用起來大同小異。
  • npm i解除安裝時要使用npm uninstall i;npm install則是用npm uninstall
  • npm i會檢測當前node版本最匹配的npm建議版本

↓ 初始化一個vue專案並使用webpack

    vue init webpack vue-leaflet

vue init webpack [專案名稱]。這邊的vue-leaflet為專案名稱(建立的資料夾名稱)。

可能會遇到的錯誤

https://ithelp.ithome.com.tw/upload/images/20201010/20130604c39mR9t8V4.jpg
因為Windows預設的PowerShell執行原則,已停用指令碼執行。

↓ 以系統管理員身分執行powershell
https://ithelp.ithome.com.tw/upload/images/20201010/20130604wYMGZAKtbd.jpg

↓ 使用 get-executionpolicy 可以取得目前powershell的執行原則

    get-executionpolicy

↓ Windows預設為Restricted
https://ithelp.ithome.com.tw/upload/images/20201010/20130604Fgziti8USm.jpg

PowerShell的執行原則

  • Restricted: 所有PowerShell Script皆無法執行
  • AllSigned: 僅限經過受信任的發行者簽屬過後才可執行
  • RemoteSigned: 異地下載需經過簽屬,本機可直接執行
  • Unrestricted: 無限制,所有PowerShell Script皆可直接執行
  • Default: 調整成預設模式
  • Bypass: 不會有任何警示,設計for更大的應用程式中的配置

現在我們要將PowerShell執行原則改為RemoteSigned,本機可直接執行。

    set-executionpolicy remotesigned

↓ 變更執行原則
https://ithelp.ithome.com.tw/upload/images/20201010/20130604kyLttHLi8a.jpg

↓ 使用 get-executionpolicy確認為RemoteSigned
https://ithelp.ithome.com.tw/upload/images/20201010/20130604nk9IvH7Nox.jpg

vue init webpack [專案名稱]成功後,準備建置webpack

↓ 移至該專案路徑,cd [資料夾名稱]

    cd vue-leaflet

↓ 這時我們看package.json,準備以webpack建置
https://ithelp.ithome.com.tw/upload/images/20201010/20130604SHSVCkRuCa.jpg

↓ 執行dev

    npm run dev

↓ 成功,會建立一個vue專案,結構如下
https://ithelp.ithome.com.tw/upload/images/20201010/20130604vmruN0Uq9a.jpg

結構

  • build: 放專案管理工具,如webpack.base.conf.js
  • config: 放config的資料夾
  • dist: 經建置後的完整網頁,由npm run build建立
  • index.html 根檔案,也是SPA(Single Page Application)的頁面
  • node_modules: 放npm modules的資料夾
  • package.json: npm套件的依賴關係
  • src: 程式放置的資料夾
  • static: 放靜態檔案的資料夾,例如圖片等
  • test: 放單元測試的資料夾

↓ 安裝 vue 及 vue2-leaflet

    npm install vue2-leaflet leaflet --save

↓ 開啟8080port頁面,成功如下
https://ithelp.ithome.com.tw/upload/images/20201010/20130604EqAkoSAjIA.jpg

建立.vue檔案

↓ 我們在conponents資料夾中建立.vue檔案,取名為Leaflet.vue,.vue檔案分成三塊。

<!-- 樣板 -->
<template></template>

<!-- js -->
<script></script>

<!-- 樣式 -->
<style scoped></style>

↓ 我們先來寫script。引入模組 "vue2-leaflet"

    import {
        LMap,
        LTileLayer,
        LMarker,
        LPopup
    } from "vue2-leaflet";

取得LMap, LTileLayer, LMarker, LPopup四個等等要用的vue components。

↓ 預設輸出

    export default {
        name: "Leaflet",
        components: {
            LMap,
            LTileLayer,
            LMarker,
            LPopup,
        },
        data() {
            return {
                zoom: 7,
                center: L.latLng(23.5, 121),
                url: "http://{s}.tile.osm.org/{z}/{x}/{y}.png",
                attribution: "",
                marker: L.latLng(23.5, 121),
                text: "你好!vue2-leaflet!",
            };
        },
    };

data裡面放等等v-bind要使用的變數。

↓ 繼續來寫template

<template>
    <div>
        <l-map class="map" :zoom="zoom" :center="center">
            <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
        </l-map>
    </div>
</template>

這邊建立一個放置地圖的div,並且用"vue2-leaflet"的components標籤

components

  • l-map: leaflet地圖
  • l-tile-layer: 放置圖層
  • l-marker: 放置標記點
  • l-popup: 標記點的資訊視窗

冒號(:)與小老鼠(@)

  • 冒號(:)在vue.js為v-bind的縮寫,代表該元素與Vue中的data值做雙向綁定
  • 小老鼠(@)在vue.js為v-on的縮寫,將該元素綁定Vue中的事件

↓ css 稍微排版

<style scoped>
    .map {
        width: 100%;
        height: 85vh;
    }
</style>

更改路由(router)

↓ 修改router資料夾中的index.js

import Vue from 'vue'
import Router from 'vue-router'
import Leaflet from '@/components/Leaflet'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Leaflet',
      component: Leaflet
    }
  ]
})

import剛剛寫好的Leaflet.vue,並且把路由的component由原先的HelloWorld改為import的Leaflet。

App.vue

↓ 原本的App.vue加一點css,讓vue的logo小一點,以及邊界為0。

html,
body {
    padding: 0;
    margin: 0;
    height: 100%;
}

#app {
    height: 100%;
    font-family: "Avenir", Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
}

.logo {
    height: 15%;
}

.logo>img {
    height: 100%;
}

↓ template

<template>
<div id="app">
    <div class="logo">
        <img src="./assets/logo.png" />
    </div>
    <router-view />
</div>
</template>

main.js

↓ import leaflet.css

import Vue from 'vue'
import App from './App'
import router from './router'
import 'leaflet/dist/leaflet.css'

↓ 初始化網頁的Vue物件

new Vue({
  el: '#app',  // 綁定vue的dom元素
  router,
  components: { App },
  template: '<App/>'
})

↓ 結果
https://ithelp.ithome.com.tw/upload/images/20201010/20130604whmxPRqpjH.jpg

l-marker

讓我們在地圖中加入l-marker。

↓ 回到Leaflet.vue檔案,於l-map標籤中加入l-marker

        <l-map class="map" :zoom="zoom" :center="center">
            <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
            <l-marker :lat-lng="marker">
                <l-popup :content="text"></l-popup>
            </l-marker>
        </l-map>

↓ 結果
https://ithelp.ithome.com.tw/upload/images/20201010/20130604lyqjGsJhPL.jpg
結果marker圖片竟然找不到!在vue.js的官方文件中明確指出Marker Icons are missing,使用webpack建置會發生的問題。

↓ 回到main.js,修正方式如下

delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});

↓ 結果
https://ithelp.ithome.com.tw/upload/images/20201010/20130604gLO3Ru52Mg.jpg

vue.js是個dom與資料雙向綁定的框架,並且以data驅動。

↓ 我們可以開啟F12,使用vue開發者工具(chrome Vue.js devtools)來監聽vue的結構。
https://ithelp.ithome.com.tw/upload/images/20201010/20130604W7jZAuVmfO.jpg

↓ Leaflet的data
https://ithelp.ithome.com.tw/upload/images/20201010/20130604GyNGOT80Bq.jpg

↓ 用vue開發者工具改變data中的zoom值會直接影響到綁定的地圖,並且同時縮放。
圖片


今天簡單介紹了Vue2Leaflet來建置地圖,
大家可以回去從vue-cli安裝開始來試試看吧!

對於vue.js新手的我來說今天的內容寫得有點兒吃力QAQ/images/emoticon/emoticon06.gif
不過呢!鐵人賽開賽至今已接近尾聲了!
越到尾聲內容就要越精彩,越不能夠鬆懈!
希望對大家都有收穫!


上一篇
[8-3] 讓Marker動起來! 實作Leaflet.MovingMarker與bouncemarker
下一篇
[Vue2Leaflet系列二] Leaflet Plugins with Vue
系列文
《你的地圖會說話? WebGIS與JavaScript的情感交織》30

尚未有邦友留言

立即登入留言