ガイド
基本的な使い方
- インストール
- はじめに
- Vue インスタンス
- テンプレート構文
- 算出プロパティとウォッチャ
- クラスとスタイルのバインディング
- 条件付きレンダリング
- リストレンダリング
- イベントハンドリング
- フォーム入力バインディング
- コンポーネントの基本
コンポーネントの詳細
- コンポーネントの登録
- プロパティ
- カスタムイベント
- スロット
- 動的 & 非同期コンポーネント
- 特別な問題に対処する
トランジションとアニメーション
- Enter/Leave とトランジション一覧
- 状態のトランジション
再利用と構成
- ミックスイン
- カスタムディレクティブ
- 描画関数とJSX
- プラグイン
- フィルター
ツール
- 単一ファイルコンポーネント
- テスト
- TypeScript のサポート
- プロダクション環境への配信
スケールアップ
- ルーティング
- 状態管理
- サーバサイドレンダリング
- セキュリティ
内部
- リアクティブの探求
移行
- Vue 1.x からの移行
- Vue Router 0.7.x からの移行
- Vuex 0.6.x から 1.0 への移行
その他
- 他のフレームワークとの比較
- Vue.js コミュニティへ参加しましょう!
- チームに会おう
v2.x 以前のドキュメントです。 v3.x のドキュメントを見たい場合はこちら
コンポーネントの登録
最終更新日: 2019年7月22日
このページは コンポーネントの基本 を読まれていることが前提になっています。コンポーネントを扱った事のない場合はこちらのページを先に読んでください。
コンポーネント名
コンポーネントを登録するときは、いつでも名前が与えられます。例えば、グローバル登録の場合:
Vue.component('my-component-name', { /* ... */ })
コンポーネント名は Vue.component
の第一引数です。
コンポーネントの命名は、コンポーネントの使用箇所に左右されます。(文字列テンプレート、または単一ファイルコンポーネントではなく) DOM 上で直接コンポーネントを使用する場合は、W3C rules に従ったカスタムタグ名(全て小文字で、ハイフンが含まれていること)を推奨します。これは、既に存在する、そして将来定義される HTML 要素との衝突を防止するのに役立ちます。
スタイルガイドでは、コンポーネント名についてのその他の推奨項目を見ることができます。
命名のケース (Name Casing)
コンポーネント名を定義する時、2 つの選択肢があります:
ケバブケース (kebab-case)
Vue.component('my-component-name', { /* ... */ })
ケバブケースでコンポーネント名を定義する場合、そのカスタム要素を参照する時も同様に、 <my-component-name>
のように、ケバブケースを用いなければいけません。
パスカルケース (PascalCase)
Vue.component('MyComponentName', { /* ... */ })
パスカルケースでコンポーネントを定義する場合、そのカスタム要素の参照には、どちらのケースも用いることができます。これは、 <my-component-name>
と <MyComponentName>
のどちらも許容されることを意味します。ただし、DOM 内 (すなわち、文字列でないテンプレート) に直接使用する場合には、ケバブケースの名前のみが有効なので注意してください。
グローバル登録
ここまでは Vue.component
だけを使ってコンポーネントを作成しました:
Vue.component('my-component-name', {
// ... options ...
})
これらのコンポーネントは グローバル登録 されています。これは、登録後に作成された、全てのルート Vue インスタンス(new Vue
)のテンプレート内で使用できることを意味します。例えば:
Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })
new Vue({ el: '#app' })
<div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>
これは全てのサブコンポーネントにも適用されます。これら 3 つのコンポーネント全てが 内部で相互に 使用可能になることを意味します。
ローカル登録
多くの場合、グローバル登録は理想的ではありません。例えば Webpack のようなビルドシステムを利用しているときに、グローバルに登録した全てのコンポーネントは、たとえ使用しなくなっても、依然として最終ビルドに含まれてしまうことでしょう。これは、ユーザがダウンロードしなくてはならない JavaScript のファイルサイズを不要に増加させてしまいます。
このような場合に、コンポーネントを素の JavaScript オブジェクトとして定義することができます:
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
次に、components
オプション内に使いたいコンポーネントを定義します:
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
components
オブジェクトのそれぞれのプロパティは、キーはカスタム要素の名前になり、一方、値はコンポーネントのオプションオブジェクトを含みます。
ローカル登録されたコンポーネントは、他のサブコンポーネント内では使用できない ことに注意して下さい。例えば、ComponentA
を ComponentB
内で使用可能にしたいときは、このように使う必要があります:
var ComponentA = { /* ... */ }
var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}
もしくは、Babel と Webpack のようなものを用いて ES2015 モジュールを利用しているならば、このようになるでしょう:
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
},
// ...
}
ES2015+ では ComponentA
のような変数名をオブジェクト内部に配置することは ComponentA: ComponentA
の省略記法にあたり、変数の名前は次のどちらも意味することに注意して下さい:
- テンプレート内で使われるカスタム要素名
- コンポーネントオプションを含んだ変数の名前
モジュールシステム
もし、 import
/require
を用いたモジュールシステムを使用しないなら、このセクションをスキップすることができます。使用する場合、いくつかの特別な手順とヒントを用意しています。
モジュールシステム内のローカル登録
ここを見ているということは、おそらくあなたは Babel と Webpack のようなものを用いて、モジュールシステムを使用していることでしょう。もしそうなら、それぞれのコンポーネントをファイルとして配置する components
ディレクトリを作成することを推奨します。
ローカル登録をする前に、使いたいコンポーネントごとにインポートする必要があります。例えば、ComponentB.js
または ComponentB.vue
ファイルを仮定して:
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
これで ComponentA
と ComponentC
の両方が ComponentB
のテンプレート内で使えるようになります。
基底コンポーネントの自動グローバル登録
コンポーネントのうち多くは比較的共通して、 input や button のような要素をラップするだけです。時にこれらを 基底コンポーネント と呼び、これらは複数のコンポーネントを横断して頻繁に用いられます。
多数のコンポーネントが多数の基底コンポーネントを含めた結果:
import BaseButton from './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput from './BaseInput.vue'
export default {
components: {
BaseButton,
BaseIcon,
BaseInput
}
}
テンプレートでは、比較的少ないマークアップをサポートします:
<BaseInput
v-model="searchText"
@keydown.enter="search"
/>
<BaseButton @click="search">
<BaseIcon name="search"/>
</BaseButton>
幸いにも、Webpack (または 内部的に Webpack を利用している Vue CLI 3+ ) を使用しているなら、 このような非常に汎用的な基底コンポーネントのグローバル登録に require.context
を用いることができます。次に示す例は、アプリケーションのエントリファイル(例: src/main.js
)で、基底コンポーネントをグローバルにインポートするコードです:
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
const requireComponent = require.context(
// コンポーネントフォルダの相対パス
'./components',
// サブフォルダ内を調べるかどうか
false,
// 基底コンポーネントのファイル名に一致させるのに使う正規表現
/Base[A-Z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
// コンポーネント設定を取得する
const componentConfig = requireComponent(fileName)
// コンポーネント名をパスカルケース (PascalCase) で取得する
const componentName = upperFirst(
camelCase(
// フォルダの深さに関わらずファイル名を取得する
fileName
.split('/')
.pop()
.replace(/\.\w+$/, '')
)
)
// コンポーネントをグローバル登録する
Vue.component(
componentName,
// `export default` を使ってコンポーネントがエクスポートされた場合に存在する
// `.default` でコンポーネントオプションを期待していて
// 存在しない場合にはモジュールのルートにフォールバックします。
componentConfig.default || componentConfig
)
})
(new Vue
を使って)ルート Vue インスタンスを作成するより前に、グローバル登録を行う必要があることを 覚えておいてください。この例は実際のプロジェクトの文脈における、このパターンの一例です。