11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MIERUNEAdvent Calendar 2020

Day 16

Vue3.0 + TypeScript + Mapbox GL JSの環境構築

Last updated at Posted at 2020-12-16

はじめに

Vue.jsが好きです(告白)

最近は寝ても醒めてもVueの事ばかり考えてしまって、食事はごはんとおかずとお味噌汁くらいしか喉を通らず、夜も8時間くらいしか眠れません

そんな注目の的のVue、今年v3.0が正式リリースされ、そろそろ勉強しておこうと試した訳ですが、マップライブラリ周りの情報が少ないような気がしたので、本記事ではVue3.0 + TypeScript + Mapbox GL JSの環境構築方法をまとめます

Vue.js最高!

もくじ

Vue3.0プロジェクトの生成

まずCLIツールを更新しておきましょう

npm install -g @vue/cli

お好みのディレクトリで以下のコマンドで、Vueアプリケーションを対話形式で生成出来ます

vue create newapp

Vue3.0+TypeScript環境をつくるために、以下のとおり入力していきます

Vue CLI v4.5.9
? Please pick a preset: Manually select features
? Check the features needed for your project: 
 ◉ Choose Vue version
 ◉ Babel
❯◉ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◯ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing
? Choose a version of Vue.js that you want to start the project with 3.x (Preview)
? Use class-style component syntax? No
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfill
s, transpiling JSX)? Yes
? Pick a linter / formatter config: Basic? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> 
to invert selection)
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated confi
g files
? Save this as a preset for future projects? No

すると、上記の例では「newapp」というディレクトリが生成され、プロジェクトファイル一式が出力されます

以下のコマンドで

cd newapp
npm install
npm run serve

いつものウェルカムページが表示されます

スクリーンショット 2020-12-13 8.29.23.png

Mapbox GL JSの環境構築

インストール

いつものようにnpm install mapbox-glとすると、一悶着あった最新のv2.0がインストールされ、Mapbox APIトークンが必要になります(Mapboxのデータを使わなくても、マップの読み込みの都度APIアクセスが発生します)。

ということで、とりあえず従来と同じように使いたかったら

npm install mapbox-gl@v1.13.0

と、OSS時代の最終バージョンを指定しましょう
型定義も忘れずに…

npm install @types/mapbox-gl

地図コンポーネントの作成

デフォルト

HelloWorld.vue
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: String,
  },
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

Mapbox GL JS導入

HelloWorld.vue
<template>
    <div>
        {{ msg }}
        <div id="map" />
    </div>
</template>

<script lang="ts">
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';

import { defineComponent, onMounted, reactive } from 'vue';
export default defineComponent({
    name: 'HelloWorld',
    props: {
        msg: String,
    },
    setup(props, context) {
        const mapstyle = reactive<mapboxgl.Style>({
            version: 8,
            sources: {
                OSM: {
                    type: 'raster',
                    tiles: ['http://tile.openstreetmap.org/{z}/{x}/{y}.png'],
                    tileSize: 256,
                    attribution:
                        '<a href="http://osm.org/copyright">© OpenStreetMap contributors</a>',
                },
            },
            layers: [
                {
                    id: 'OSM',
                    type: 'raster',
                    source: 'OSM',
                    minzoom: 0,
                    maxzoom: 18,
                },
            ],
        });
        onMounted(() => {
            const map = new mapboxgl.Map({
                container: 'map',
                style: mapstyle,
                center: [140.0, 38.2],
                zoom: 9,
                maxZoom: 18,
            });
        });
    },
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#map {
    height: 500px;
}
</style>

するとこうなる

スクリーンショット 2020-12-13 8.43.34.png

ここで、見慣れないsetup()という関数以下が、CompositionAPIなるものです。これまでVueを使っていたらすぐに使えそうな感触でした(ほんとはこの辺もまとめたかったのですが時間的なアレで割愛)。

VSCodeの設定

これで動くっちゃ動くんですが、もしかしたらマウスホバーしても変数定義は見られないし、コード補完も効いてないんじゃないでしょうか。TypeScriptの魅力の4割くらいはそこにあると思っているので、このままではいけません。

マウスホバーとコード補完

エクステンション「Vetur」が必要です。

スクリーンショット 2020-12-13 8.47.55.png

コードフォーマット

で、私の環境だとコード補完だとかはこれで解決したんですが、コードフォーマットが効かなくなりました。Veturのインストール直後からです。これは、VSCodeのフォーマットは「Prettier」に任せているからでした。Veturにもフォーマット機能が内蔵されていて競合するっぽいので、エクステンションの設定から

スクリーンショット 2020-12-13 8.50.26.png

Vetur > Format: Enableという項目のチェックを外したら解決しました。

おわりに

まだ実際にこの構成でアプリケーションを作ってはいませんが、ただでさえ最高なVue.jsにTypeScriptが加わる事でアホほど快適な開発環境になるのではないでしょうか。Mapbox GL JSはVue.jsとの相性も非常によく(個人の感想です)、さらにTypeScriptによる強力なコード補完で向かうところ敵なしです。

さぁみなさんもご一緒に

Vue.js最高!

11
6
1

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
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?