Vue3 + TypeScript で Mapbox の マップ を表示する サンプル を紹介します。 create-vue で作成した プロジェクト に Mapbox の 公式 JavaScript クライアント ライブラリである Mapbox GL JS を組み入れることで 簡単に マップ を実装することができます。 一方で Vue3 + TypeScript 環境向けの サンプル はあまり見受けられません。 多少 コツ のようなものも必要でしたので、 本記事で合わせて紹介していきます。
macOS
: 12.3vue
: 3.2.31typescript
: 4.5.5mapbox-gl
: 2.7.1@type/mapbox-gl
: 2.6.3
Vue3 + TypeScript プロジェクト の作成
それでは最初に 今回使用する Vue3 + TypeScript の プロジェクト を以下の要領で作成します。
init vue@3
コマンド で プロジェクト 作成- TypeScript のみ追加
なお プロジェクト 作成の詳細は以下の記事を参考にしてください。
Mapbox GL JS の インストール
mapbox-gl の インストール
次に 作成した プロジェクト に Mapbox GL JS を 公式 サイト の手順 に従って インストール していきます。 以下の ように npm install
コマンド を実行します。
npm install --save mapbox-gl
% npm install --save mapbox-gl added 29 packages, and audited 143 packages in 7s 18 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
無事 インストール が完了したら、 package.json
に 以下のように mapbox-gl
が追加されていることを確認することができます。
Type/mapbox-gl の インストール
次に 今回は TypeScript 環境で進めていきますので、 Type/mapbox-gl についても合わせて インストール していきます。 こちらを インストール しないと 以下のような ワーニング が表示されてしまいます。
パッケージ の 公式 サイト の手順に従って インストール していきます。
npm install --save @types/mapbox-gl
% npm install --save @types/mapbox-gl added 2 packages, and audited 145 packages in 3s 18 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
無事 インストール が完了したら、 package.json
に 以下のように @types/mapbox-gl
が追加されていることを確認することができます。
マップ 表示用の コンポーネント の準備
最後に マップ 表示用の コンポーネント を準備しておきます。 今回は 新規に作成する MyMap.vue
に マップ 表示部分を実装し App.vue
から MyMap.vue
を呼び出す シンプル な構成にしたいと思います。
src / App.vue
<script setup lang="ts"> import MyMap from './components/MyMap.vue' </script> <template> <MyMap /> </template>
src / components / MyMap.vue
<script setup lang="ts"> </script> <template></template>
tsconfig.json
環境によっては、 コンパイラ が以下の エラー を出力する場合があります。 ここでは、以下のように tsconfig.json
に Deprecations を無視する設定 (2行目) を追加して対処することにします。
Option 'importsNotUsedAsValues' is deprecated and will stop functioning in TypeScript 5.5. Specify compilerOption '"ignoreDeprecations": "5.0"' to silence this error.
Use 'verbatimModuleSyntax' instead.
"compilerOptions": { "ignoreDeprecations": "5.0", "baseUrl": ".", "paths": { "@/*": [ "./src/*" ] } },
ここまでで マップ を表示させるための プロジェクト の準備は完了となります。 次に 実際に マップ の表示部分を実装していきましょう。
マップ 表示の実装
Mapbox Access Token の準備
Mapbox の マップ 表示を実装するためには Mapbox アカウント と その アカウント に紐づく Access Token が必要になります。 こちらについては 公式 サイト の手順に従っていただければ 問題なく 作成 取得 ができると思います。 今回は アカウント 作成と同時に生成される Default Public Token を用いて進めていきます。
なお、 以下は iOS 向けの 記事ですが Access Token については Mapbox GL JS と考え方は同じですので 詳細について 参考にしてみてください。
マップ 表示 コンポーネント の実装
それでは 本記事の本題である マップ 表示 コンポーネント の実装を進めていきます。MyMap.vue
の script タグ に以下の内容を記載していきます。 今回は 国立競技場 を中心とした マップ を表示していきます。
実装の ポイント は以下の通りです。
- 4 行目: 公式 サイト の手順に従って mapbox-gl で使用する CSS を インポート します。
- 6 行目: ‘<your access token here>’ の部分には 上述した Default Public Token の値を指定してください。
- 8 行目: Vue3 の ライフサイクルフック の onMounted の タイミング で Map オブジェクト を生成する必要があります。
- 11 行目: container: 生成する マップ の オブジェクト を識別する文字列
- 13 行目: 生成する マップ の中心地点の 緯度経度 を指定
<script setup lang="ts"> import { onMounted } from 'vue' import mapboxgl from 'mapbox-gl' import 'mapbox-gl/dist/mapbox-gl.css' mapboxgl.accessToken = '<your access token here>' onMounted(() => { const mapObj = new mapboxgl.Map({ // 国立競技場 container: 'japan-national-stadium', // container ID style: 'mapbox://styles/mapbox/streets-v11', // style URL center: [139.714590, 35.678184], // starting position [lng, lat] zoom: 14 // starting zoom }) }) </script>
template 部分には 上記 container で 指定した 名称を id
にもつ div
コンテンツ を配置していきます。
<template> <div id="japan-national-stadium"></div> </template>
ここまでで 公式 サイト に記載されている手順 は完了となりますが、 実際にこの状態で npm run dev
を用いて アプリケーション を起動しても マップ が表示されていないと思います。 次に この問題に対処していきます。
mapbox-gl.css インポート 問題への対処
色々試したところ 4 行目 に記載した import 文 を コメントアウト すると マップ が表示されるようになることが分かりました。 ただし これでは根本的な解決にはなっていません。コメントアウト した状態で ブラウザ の コンソール を開くと 以下の ワーニング が表示されていることを見つけることができます。
ワーニング の詳細確認
1 つ目の警告は必要な css である mapbox-gl.css
が ロードできていないという内容です。
2 つ目の警告は環境固有のため無視できます。 3 つ目の警告は ズームレベル が大きい時に 一部の画像が ロード できなかった というもので これも無視できます。
つまり やはり対処すべきは 1 つ目の mapbox-gs.css
に関する問題です。mapbox-gl.css
を インポート した状態で マップ が表示できる必要がありそうです。
div の 高さ指定を追加
更に 色々と調査したところ、 以下の情報の通り、「div の 高さを指定する」 ことで マップ が表示されるようになります。 ちなみに 高さの指定は パーセント ではうまくいかず、 px や em といった 実値 を指定する必要があるようでした。
<template> <div id="japan-national-stadium" :style="{ height: '20em' }"></div> </template>
上記の template に修正した後に npm run dev
で起動してみると、無事 以下のように マップ を表示することができました。 この部分は今後改善される可能性もありますが 少なくとも mapbox-gl v2.7.1 では必須になってきますので 注意してください。
参考:
まとめ
init vue@3
で TypeScript を 追加 して プロジェクト 作成
mapbox-gl
, @type/mapbox-gl
の 2 つを npm install
onMounted
フック で mapbox.Map オブジェクト を生成
Default Public Token
を用いるcontainer
に オブジェクト の名称を指定
div
タグ に Map 表示部を記載
id
にcontainer
で指定した 名称を指定height
をpx
かem
で指定
今回使用したコード
src / App.vue
<script setup lang="ts"> import MyMap from './components/MyMap.vue' </script>
<template> <MyMap /> </template>
src / components / MyMap.vue
<script setup lang="ts"> import { onMounted } from 'vue' import mapboxgl from 'mapbox-gl' import 'mapbox-gl/dist/mapbox-gl.css' mapboxgl.accessToken = '<your access token here>' onMounted(() => { const mapObj = new mapboxgl.Map({ // 国立競技場 container: 'japan-national-stadium', // container ID style: 'mapbox://styles/mapbox/streets-v11', // style URL center: [139.714590, 35.678184], // starting position [lng, lat] zoom: 14 // starting zoom }) }) </script>
<template> <div id="japan-national-stadium" :style="{ height: '20em' }"></div> </template>
tsconfig.json
{ "extends": "@vue/tsconfig/tsconfig.web.json", "include": [ "env.d.ts", "src/**/*", "src/**/*.vue" ], "compilerOptions": { "ignoreDeprecations": "5.0", "baseUrl": ".", "paths": { "@/*": [ "./src/*" ] } }, "references": [ { "path": "./tsconfig.vite-config.json" } ] }