category icon
2022-08-20
JavaScript - Nuxt3

Nuxt3 で GoogleMap の代替である Leaflet を使う方法

nuxt
3.0.0-rc.8
leaflet
1.8.0
profile
hikaru
Software Developer / DIY'er

Google Map の代替として Leaflet js を Nuxt3 で使う方法です。

Google Map のような操作感の地図アプリを作れる

なお、コーディングスタイルは Nuxt3 で標準的である、Vue3 Composition API 形式で統一しています。

まずはプロジェクトの準備

(1) Nuxt3 プロジェクトの作成

Nuxt3 の公式情報に従い、プロジェクトを作成します。

shell
# nuxt3の新規プロジェクトを作成
$ npx nuxi init nuxt3-monaco-example

# カレントディレクトリを移動
$ cd nuxt3-monaco-example

# 各種パッケージのインストール
$ npm i

# 開発環境で実行 (Ctrl+Cで停止)
$ npm run dev

(2) Leaflet パッケージをインストール

Leaflet に必要な公式パッケージを追加します。

shell
# Leafletに必要な公式パッケージを追加
$ npm install leaflet

この記事を執筆している時点での最新バージョンである nuxt:3.0.0-rc.8 と leaflet:1.8.0 がインストールされました。

実装コード

(1) Leaflet 用のコンポーネントを作成する

Vue3 Composition API 形式で、Leaflet を内包するコンポーネントを作成します。
components/AppLeaflet.vue ファイルを作成して、以下のように実装します。

./components/AppLeaflet.vue
<script lang="ts" setup>
import L from "leaflet";
import "leaflet/dist/leaflet.css";

/** テンプレート参照: マップ表示用のDOM要素 */
const mapEl = ref<HTMLElement>();

// MEMO: テンプレート参照(mapEl)はonMounted内で使える
onMounted(() => {
  // leafletのセットアップ
  const map = L.map(mapEl.value).setView([37.9022418, 139.0235109], 13);

  // 地図情報を読み込み
  L.tileLayer(`https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png`, {
    maxZoom: 19,
    attribution: `© OpenStreetMap`,
  }).addTo(map);

  // マーカーピンの設定
  L.marker([37.9022418, 139.0235109], { opacity: 0.8 })
    .addTo(map)
    .bindPopup(`<b>Hello world!</b><br>I am a popup.`);
});
</script>

<template>
  <!-- 地図表示エリア -->
  <div ref="mapEl" style="width: 1024px; height: 768px"></div>
</template>

注意点として、leaflet パッケージを静的 import しているこのコンポーネントは、サーバー上でレンダリングできません。(SSR や SSG モードだとサーバーでレンダリングされる)

このコンポーネントを呼び出す親コンポーネント内で ClientOnly + Lazy(遅延読み込み) を行うことで、SSR や SSG モードでもブラウザ上でのみレンダリングするようにする必要があります。

(2) app.vue の書き換え

親コンポーネントにあたる app.vue を以下のように書き換えます。

./app.vue
<template>
  <div>
    <!-- MEMO: SSR/SSGモードではサーバー上でレンダリングせず、ブラウザでのみレンダリングする -->
    <ClientOnly>
      <!-- MEMO: Lazyを付加することをAppLeafletコンポーネントを遅延読み込みする -->
      <LazyAppLeaflet></LazyAppLeaflet>
    </ClientOnly>
  </div>
</template>

LazyAppLeaflet コンポーネントは、Lazy(遅延読み込み)を指定した AppLeaflet コンポーネントです。このように記載することで Nuxt3 が勝手に AppLeaflet コンポーネントを遅延読み込みしてくれます。

ClientOnly は SSR と SSG モードの時にサーバーではレンダリングせず、ブラウザでのみレンダリングするようにする指定です。

完成・動作確認

Google Map のような地図アプリを作れる

完成するとこんな感じ。ブラウザ上で Google Map の様な操作感の地図アプリを作れます。

おわり。

おすすめ本コーナー

最近、DIY ブログ用に Amazon アソシエイトを登録しました~!DIY で使った商品リンクを載せて収益を得ようという魂胆だったのですが、『この記事のような技術記事にも本載せられるやん』って気が付いたので、さっそくのおすすめ本コーナーを作ってみました✨

(1) 個人開発をはじめよう!クリエイター25人の実践エピソード

個人開発を楽しんでる人におすすめ。読み物としても面白いし、気を張らずに気楽に読めます。
自分自身の開発モチベーションを上げるためにも使ってます。

(2) Vue.js3やさしい入門書[Vite/Vue Router/Pinia 対応]

Vue 3 から追加された Composition API での解説や <script setup> 構文を前提に解説している本。
ほかの入門書では Vue2.0 での書き方である Option API で書かれていたり、<script setup> 構文を使わないものが多いため、ほかの書籍にはないメリットだと思います。