Skip to content

Vue Componentのマウント方法

Masashi Hasegawa edited this page Jul 3, 2022 · 3 revisions

概要

bootcampアプリ内でのVue Componentのマウント方法について説明します。

経緯

bootcampでのSFCs(Single File Components)のマウント方法は、最初は一つ一つ手書きしていました。 しかし、Vue2からVue3に変わる時にマウント方法が変更されました。 全部書き直さなければいけませんが、これを機会にVueMounter.jsを作って共通化しました。(Vue3に移行後にnpmとしてリリース予定です) マウント方法をこちらに共通化できれば、Vue3のマウント方法への移行はVueMounter.js側の変更だけでいけます。

追加したときのPR

vue componentのマウント方法を変更 by komagata · Pull Request #4961 · fjordllc/bootcamp

旧マウント方法

こんな感じで手動でDOM ElementにComponentをマウントしてた。

<!-- HTMLテンプレート --!>
<div id="js-hello" data-id="1234" />
// hello.vue - マウントされるComponent
<template>
  <div>Hello {{ id }}</div>
</template>
<script>
export default {
  props: {
    id: { type: Number, required: true }
  }
}
</script>
// hello.js - マウントするコード
import Vue from 'vue'
import Hello from 'hello.vue'

document.addEventListener('DOMContentLoaded', () => {
  const selector = '#js-hello'
  const hello = document.querySelector(selector)
  if (hello) {
    // Componentに渡したいpropはdata attributeから渡していた
    const name = Number(bookmark.getAttribute('data-id')) // 型の変換はこのファイルでやっていた
    new Vue({
      render: (h) =>
        h(Hello, {
          props: {
            id: id
          }
        })
    }).$mount(selector)
  }
})

新マウント方法

// hello.vue - マウントされるComponent
<template>
  <div>Hello {{ id }}</div>
</template>
<script>
export default {
  name: 'Hello', // nameを追加
  props: {
    id: { type: Number, required: true }
  }
}
</script>
// application.js - マウントするコード
imoprt VueMounter from 'VueMounter.js'
imoprt Hello from 'hello.vue'

const vueMounter = new VueMounter()
vueMounter.addComponent(Hello)
vueMounter.mount()

data-vue属性を持つelementが自動でマウントされる。data-vueの値がコンポーネント名となる。(この場合はhello.vue) propsを渡したい場合はdata-vue-nameのようにprop名をdata-vue-の後につける。 コンポーネントにはこの名前がcamelCaseになった名前で渡される。

例:current-user-id -> currentUserId

<div data-vue="Hello" data-vue-name="Fjord Boot Camp" />

型指定

propsにString型以外を渡したい場合はattribute名の最後に:型名をつける。

例:data-vue-user-id:number

上記の場合、Component側で対応する定義は下記のようになる。

export default {
  name: "Hello", // nameは必須
  props: {
    userId: { type: Number }
  }
}

指定できる型は下記の通り。 指定しない場合はstring型になる。

  • string
    • 例:data-vue-message="foo"
  • number
    • 例:data-vue-user-id:number="1234"
  • boolean
    • 例:data-vue-is-admin:boolean="true"
  • json
    • 例:data-vue-fruits:json="{\"apple\": 1, \"orange\": 2, \"grape\": 3}"

json型ではJSON.parseを使って変換しているので、[1, 2, 3]のようなArrayや1234のようなNumberでもOKだが、あまり複雑な構造を渡すのはおすすめしない。

Clone this wiki locally