Vue.jsを使っていてhtmlファイルやtemplate内部でディレクティブを描く順番はどうすればいいんだろうか?や、コンポーネントを定義する際にはpropsやcomputed、templateはどんな順番で書けば良いのだろうとお持ったことはないですか?
このような細かいことはプログラムに支障が出ることはさることながら、そうでないものも可読性をあげる意味で統一した方がベターです。Vue.jsではこのような疑問に対してスタイルガイドを提供しています。本記事ではこのスタイルガイドを例も挙げてわかりやすく書いてみました。是非参考にしてみてください。
Vueインスタンスのオプションの書き順について
コンポーネント/インスタンス オプションは、一貫した順序になるべき
- 副作用 (コンポーネント外への影響)
el - グローバルな認識 (コンポーネントを超えた知識が必要)
name
parent - コンポーネントの種類 (コンポーネントの種類を変更)
functional - テンプレートの修飾子 (テンプレートのコンパイル方法を変更)
delimiters
comments - テンプレートの依存関係 (テンプレートで使用されるアセット)
components
directives
filters - 合成 (プロパティをオプションにマージ)
extends
mixins - インタフェース (コンポーネントへのインタフェース)
inheritAttrs
model
props/propsData - ローカルの状態 (ローカル リアクティブ プロパティ)
data
computed - イベント (リアクティブなイベントによって引き起こされたコールバック)
watch - ライフサイクルイベント (呼び出される順)
beforeCreate
created
beforeMountmounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed - リアクティブではないプロパティ (リアクティブシステムから独立したインスタンス プロパティ)
methods - レンダリング (コンポーネント出力の宣言的な記述)
template/render
renderError
Vueの要素の属性の順番について
Vueの要素の属性 (コンポーネントを含む) は、一貫した順序になるべき
- 定義 (コンポーネントオプションを提供)
is - リスト描画 (同じ要素の複数のバリエーションを作成する)
v-for - 条件 (要素が描画/表示されているかどうか)
v-if
v-else-if
v-else
v-show
v-cloak - 描画修飾子 (要素の描画方法を変更)
v-pre
v-once - グローバルな認識 (コンポーネントを超えた知識が必要)
id - 一意の属性 (一意の値を必要とする属性)
ref
key - 双方向バインディング (バインディングとイベントの結合)
v-model - その他の属性 (すべての指定されていないバインドされた属性とバインドされていない属性)
- イベント (コンポーネントのイベントリスナ)
v-on - コンテンツ (要素のコンテンツを上書きする)
v-html
v-text
ディレクティブに関すること
常にv-forに対してはkeyを設定する
data: function () { return { todos: [ { id: 1, text: 'Learn to use v-for' }, { id: 2, text: 'Learn to use key' } ] } }
<ul> <li v-for="todo in todos" :key="todo.id" > {{ todo.text }} </li> </ul>
v-forとv-ifを一緒に使うのを避ける
(ダメな例)
<ul> <li v-for="user in users" v-if="user.isActive" :key="user.id" > {{ user.name }} </li> </ul>
(いい例)
<ul v-if="shouldShowUsers"> <li v-for="user in users" :key="user.id" > {{ user.name }} </li> </ul>
プロパティ名は、定義の時は常にキャメルケース(camelCase)にするべき
props: { greetingText: String }
プロパティ名は、テンプレートではケバブケース(kebab-case)にするべき
<WelcomeMessage greeting-text="hi"/>
複数の属性をもつ要素は、1 行に 1 要素ずつ、複数の行にわたって書くべき
(ダメな例)
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo">
(いい例)
<img
src="https://vuejs.org/images/logo.png"
alt="Vue Logo"
>
複雑な式は算出プロパティかメソッドにリファクタリングして、コンポーネントのテンプレートには単純な式だけを含むようにするべき
(ダメな例)
{{ fullName.split(' ').map(function (word) { return word[0].toUpperCase() + word.slice(1) }).join(' ') }}
(いい例)
<!-- テンプレート内 --> {{ normalizedFullName }} // 複雑な式を算出プロパティに移動 computed: { normalizedFullName: function () { return this.fullName.split(' ').map(function (word) { return word[0].toUpperCase() + word.slice(1) }).join(' ') } }
複雑な算出プロパティは、できる限りたくさんの単純なプロパティに分割するべき
(ダメな例)
computed: { price: function () { var basePrice = this.manufactureCost / (1 - this.profitMargin) return ( basePrice - basePrice * (this.discountPercent || 0) ) } }
(いい例)
computed: { basePrice: function () { return this.manufactureCost / (1 - this.profitMargin) }, discount: function () { return this.basePrice * (this.discountPercent || 0) }, finalPrice: function () { return this.basePrice - this.discount } }
空ではない HTML 属性の値は常に引用符(シングルコーテーションかダブルコーテーション、 JS の中で使われていない方)でくくるべき
<input type="text"> <AppSidebar :style="{ width: sidebarWidth + 'px' }">
ディレクティブの短縮記法 (v-bind: に対する : 、 v-on: に対する @ 、 v-slot: に対する #)は、常に使うか、まったく使わないかのどちらかにするべき
コンポーネントに関すること(コンポーネントを使わない場合は読まなくても良い)
コンポーネント名は一部を除き常に複数単語にするべき
Vue.component('todo-item', { // ... }) export default { name: 'TodoItem', // ... }
コンポーネントのデータは関数でなくてはならない
Vue.component('some-comp', { data: function () { return { foo: 'bar' } } })
プロパティの定義はできるだけ詳細にする(statusのみで大丈夫)
props: { status: String }
各コンポーネントは別のファイルに書く(ファイルを統合できるビルドシステムがある時なのでWebpackなどを扱わない問題は不要)
components/ |- TodoList.js |- TodoItem.js
コンポーネントのファイル名は全てパスカルケースかケバブケースにする
components/ |- MyComponent.vue
または
components/ |- my-component.vue
コンポーネント名はケバブケースで記述する(パスカルケースは使い分けがめんどくさいので使用しない)
<!-- どこでも --> <my-component></my-component>
中身を持たないコンポーネントは、 単一ファイルコンポーネント 、文字列テンプレート、および JSX の中では自己終了形式で書く
<my-component/>
中身を持たないコンポーネントは、DOMテンプレート中(HTMLファイルに直接各形式)では自己終了形式で書くことができないので空の要素として記述する
<my-component></my-component>
コンポーネント名には、略語よりも完全な単語を使うべき
(ダメな例)
components/ |- SdSettings.vue |- UProfOpts.vue
(いい例)
components/ |- StudentDashboardSettings.vue |- UserProfileOptions.vue
単一ファイルコンポーネントでは、 <script> 、 <template> 、 <style> タグを一貫した順序にするべき <style> は最後
親子間のやりとりは、this.$parent や変化するプロパティよりも、プロパティとイベントが推奨される
グローバル状態管理には、this.$root やグローバルイベントバスよりも、Vuex が推奨される
さいごに
本記事ではVue.jsのスタイルガイドについて紹介しました。全て覚えるのは大変ですが、一度読んでおくと後から参照もできるのでいいでしょう。皆さんも読みやすいコード書いていきましょう!