LoginSignup
13
15

Vue.js v3でLeafletの開発環境を構築してみた

Last updated at Posted at 2020-12-05

sample201123_01.gif


try-049_00.png


この記事は、「Vue Advent Calendar 2020」の5日目の記事です。

Vue.js v3でLeafletの開発環境を構築してみました :tada:

Vue.js v3でLeafletを利用されているかたはまだ少ないと思うので、Vue.js v3向けのラッパーライブラリを利用して開発環境を構築してみました!

Mapbox GL JSとOpenLayersについては、2020年12月現在Vue 3に対応したラッパーライブラリはまだ公開されていないようです...


事前準備

try-049_02.png


Vue.js v3 x Leaflet

Vue.js v3とLeafletの組み合わせの場合は、「vue-leaflet」を利用します。


はじめに、各ライブラリをインストールします。今回は「Vue CLI UI」を利用しleaflet、@types/leaflet、@vue-leaflet/vue-leafletを検索しインストールします。

try-049_03.png


次に、ひな形に地図を表示させるためのコードを追記していきます。

全体構成

try-049_04.png


package.json

{
  "name": "vue3_prj",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@types/leaflet": "^1.5.19",
    "@vue-leaflet/vue-leaflet": "^0.4.2",
    "core-js": "^3.6.5",
    "leaflet": "^1.7.1",
    "vue": "^3.0.0",
    "vue-class-component": "^8.0.0-0",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^2.33.0",
    "@typescript-eslint/parser": "^2.33.0",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-typescript": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/eslint-config-typescript": "^5.0.2",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^7.0.0-0",
    "typescript": "~3.9.3"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended",
      "@vue/typescript/recommended"
    ],
    "parserOptions": {
      "ecmaVersion": 2020
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

/src

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// Leafletのスタイル読み込み
import 'leaflet/dist/leaflet.css'

createApp(App).use(store).use(router).mount('#app')

main.tsでleaflet.cssを読み込みます。

// Leafletのスタイル読み込み
import 'leaflet/dist/leaflet.css'

/src/views

Home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
    <MapPane></MapPane>
  </div>
</template>

<script lang="ts">
import { Options, Vue } from 'vue-class-component';
import HelloWorld from '@/components/HelloWorld.vue';
// マップコンポーネント読み込み
import MapPane from '@/components/MapPane.vue';

@Options({
  components: {
    HelloWorld,
    MapPane
  },
})
export default class Home extends Vue {}
</script>

Home.vueでMapPaneコンポーネントを読み込みます。

<MapPane></MapPane>
// マップコンポーネント読み込み
import MapPane from '@/components/MapPane.vue'

components: {
    MapPane
}

/src/components

MapPane.vue

<template>
    <div class="mapPane">
        <!--マップ-->
        <l-map
            :zoom="zoom"
            :center="center"
        >
            <!--レイヤーコントロール-->
            <l-control-layers
                position="topright"
            ></l-control-layers>
            <!--レイヤ設定-->
            <l-tile-layer
                v-for="tileProvider in tileProviders"
                :key="tileProvider.name"
                :name="tileProvider.name"
                :visible="tileProvider.visible"
                :url="tileProvider.url"
                :attribution="tileProvider.attribution"
                layer-type="base"
            ></l-tile-layer>
            <!--マーカー-->
            <l-marker
                :lat-lng="marker"
            ></l-marker>
        </l-map>
    </div>
</template>

<script lang="ts">
import {
    LMap,
    LTileLayer,
    LControlLayers,
    LMarker
} from '@vue-leaflet/vue-leaflet';

export default {
    name: 'MapPane',
    components: {
        LMap,
        LTileLayer,
        LControlLayers,
        LMarker
    },
    data() {
        return {
            center: [35.681, 139.763],
            zoom: 14,
            marker: [35.681, 139.763],
            tileProviders: [
                {
                    name: 'MIERUNE Streets',
                    visible: true,
                    url: 'https://api.maptiler.com/maps/jp-mierune-streets/256/{z}/{x}/{y}.png?key=[APIキー]',
                    attribution: '<a href="https://maptiler.jp/" target="_blank">&copy; MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>'
                },
                {
                    name: 'MIERUNE Gray',
                    visible: false,
                    url: 'https://api.maptiler.com/maps/jp-mierune-gray/256/{z}/{x}/{y}.png?key=[APIキー]',
                    attribution: '<a href="https://maptiler.jp/" target="_blank">&copy; MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>'
                }
            ]
        }
    }
}
</script>

<style scoped>
.mapPane {
    height: 800px;
    margin: 0;
    text-align: left;
}
</style>

マップのタグを指定します。

<template>
    <div class="mapPane">
        <!--マップ-->
        <l-map
            :zoom="zoom"
            :center="center"
        >
            <!--レイヤーコントロール-->
            <l-control-layers
                position="topright"
            ></l-control-layers>
            <!--レイヤ設定 Maptiler-->
            <l-tile-layer
                v-for="tileProvider in tileProviders"
                :key="tileProvider.name"
                :name="tileProvider.name"
                :visible="tileProvider.visible"
                :url="tileProvider.url"
                :attribution="tileProvider.attribution"
                layer-type="base"
            ></l-tile-layer>
            <!--マーカー-->
            <l-marker
                :lat-lng="marker"
            ></l-marker>
        </l-map>
    </div>
</template>

マップのサイズを指定します。

.mapPane {
    height: 800px;
    margin: 0;
    text-align: left;
}

マップとレイヤとマーカーの設定をします。背景レイヤは、今回Maptilerを指定します。

import {
    LMap,
    LTileLayer,
    LControlLayers,
    LMarker
} from '@vue-leaflet/vue-leaflet';

export default {
    name: 'MapPane',
    components: {
        LMap,
        LTileLayer,
        LControlLayers,
        LMarker
    },
    data() {
        return {
            center: [35.681, 139.763],
            zoom: 14,
            marker: [35.681, 139.763],
            tileProviders: [
                {
                    name: 'MIERUNE Streets',
                    visible: true,
                    url: 'https://api.maptiler.com/maps/jp-mierune-streets/256/{z}/{x}/{y}.png?key=[APIキー]',
                    attribution: '<a href="https://maptiler.jp/" target="_blank">&copy; MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>'
                },
                {
                    name: 'MIERUNE Gray',
                    visible: false,
                    url: 'https://api.maptiler.com/maps/jp-mierune-gray/256/{z}/{x}/{y}.png?key=[APIキー]',
                    attribution: '<a href="https://maptiler.jp/" target="_blank">&copy; MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>'
                }
            ]
        }
    }
}

ローカルサーバーで確認

npm run serve

ローカルサーバーを立ち上げると、マップが表示されます。

try-049_01.gif


Vue.js v3とvue-leafletを利用することで、手軽にVue 3用Leafletの開発環境の構築ができました :thumbsup:

Leafletのライブラリを、直接読み込んで利用することもできると思いますが、ラッパーライブラリを利用することである程度は手軽に操作ができると思います。ただ、用途により直接読み込むかラッパーライブラリを利用するかの選択は必要となりそうです:bulb: また、vue-leafletはまだベータ版ではありますが、Vue 2からVue 3への移行の参考になればと思います!

Vue 2の記事、「Vue.jsでLeafletとMapbox GL JSの開発環境を構築してみた」と比べてみて頂ければと思います :grinning:


Vue.js・Leafletについて、他にも記事を書いています。よろしければぜひ :bow:
tags - Leaflet
tags - Vue.js

やってみたシリーズ :grinning:
tags - Try



book

13
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
15