コンポーネント名は常に複数単語にする
HTML要素は1単語になっている
コンポーネント名を1単語で定義すると、知らなかったHTML要素の名前とかぶったり、将来追加される要素と衝突が起こる可能性がある
そのため、コンポーネント名を定義する際は以下のように複数単語のパスカルケースで設定する
Todo // ×
TodoList // 〇
props
にtype
を定義する
props
の名前から一目で型が分かるようにすることは前提であるとして、意図していない方の変数を渡された場合に警告を投げるようにすることができる
defineProps({
name: {
type: String, // TypeScriptのstringではないことに注意
},
});
String
のほかにもArray
、Number
、Object
、Boolean
などがある
props
にでデフォルト値を設定する
たとえコンポーネントに値が渡されていない場合でもとりあえず使えるようにしておくためにデフォルト値を設定したいとき
デフォルト値の設定には以下の方法がある
チーム間でどちらを使うのか決めておくとよいだろう
-
withDefault
を使う
withDeaults(defineProps(), {
name: "名無し" // デフォルト値
})
-
defineProps
のdefault
を使う
defineProps({
name: {
type: String,
default: "名無し" // デフォルト値
}
})
// 同じ構文でdefineModelでもデフォルト値が設定できる
watch
でイベントリスナーを管理する
イベントリスナーの設定・破棄によく使われるonMounted
とonUnmounted
をwatch
で代用することができる
処理が1つのスコープに収まるので管理しやすくなる
/**
element: ref(監視対象)
el: 新しい値
_: 古い値(ここでは使用しないためアンダースコア)
onCleanup: watchから渡される、監視対象が更新・破棄された場合の処理を記述できる関数
listener: イベント発火時の処理
*/
watch(element, (el, _, onCleanup) => {
// 要素が存在する場合にイベント設定
el && el.addEventListener("click", listener)
// onUnmountedをonCleanupで代用
onCleanup(() => el && el.removeEventListener(name, listener))
})
computed
でHTML属性を動的に変更する
HTML要素の属性を動的に変更する際よく使われるのが、ref
で真偽値を持ち、タグ内で三項演算子を用いて状態毎に属性を付けたり外したりするもの
処理が使われている場所と処理自身の所在が同じになるという利点があるが、複雑になったり、長い変数名を使ったりするとコードの見通しが悪くなる
そんな時にcomputed
を用いることで処理の見通しを良くし、かつタグ内のコード量を減らすことができる
<div :class="{
invalid: !isValid,
valid: isValid,
error: isError
}">
const myComputedClasses = computed(() => {
return {
invalid: !isValid.value,
valid: isValid.value,
error: isError.value
}
})
defineAsyncComponent
でJSバンドルを減らして高速化する
使うときは使うがいつも必要ではないコンポーネントがよく出てくる
にもかかわらず、なにもしないとVueは使わないコンポーネントまでも一緒にバンドルされてしまう
defineAsyncComponent
を使うと、初期状態では呼び出さないが、必要になったらロードするコンポーネントを指定できる
// コード上部にimport文は書かなくていい
const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))