【Nuxt.js】カスタムセレクトフォームを作ってみた
背景
こんにちは、ユウです。
仕事上でselectフォームを使うことになり、でもぐぐってみたら大体の記事はselectフォームにv-modelで初期値を設定してます。
今回はselectフォームのコンポーネントを作成するのが要件で、かつ開発規約上コンポーネントにはdataを持たせないです。そうなるとv-modelは機能できませんし、propsの値もv-modelに指定できないから八方塞がりの状態に...
こうなると、v-modelを使わずにselectフォームのコンポーネントを作るしかないです。
仕様
今回作成するselectコンポーネントの仕様は下記です。
- コンポーネントにdataを持たせない。(これは独自ルールです、実際このルールがなければv-modelでことが足りるでしょう)
- propsでselectの初期値を指定できる。
- selectフォームの横に表示する文字はslotで指定できる。
- selectフォームでの操作処理はemitで親コンポーネントに任す。
3に関してはこういうことです。
親コンポーネントコード
ではまず親コンポーネントから呼び出すコードを見ましょう。
<SelectBox
:id="`min-number`"
:value="defaultMinNumber"
:options="options"
@selected="selected"
> 〜
</SelectBox>
<SelectBox
:id="`max-number`"
:value="defaultMaxNumber"
:options="options"
@selected="selected"
/>
export default {
data() {
return {
defaultMinNumber: '1',
defaultMaxNumber: '5',
options: [
{ code: '1', name: '1名' },
{ code: '2', name: '2名' },
{ code: '3', name: '3名' },
{ code: '4', name: '4名' },
{ code: '5', name: '5名' },
],
};
},
methods: {
selected(value, id) {
// ここで処理select操作後の処理を書く
// idは操作したselectフォームのid、valueは選択した値です
}
}
}
selectコンポーネントに渡すpropsを説明します。
id : 操作したselectフォームはどれなのか特定するため用のidです。これは親コンポーネントがフォーム操作後の処理に使えます。
value : selectフォームの初期値です。optionsのcodeに一致する値があればそれが初期値として設定されます。
options : フォームの選択肢です。codeは選択肢の値で、nameは表示用の文字列です。
selected : selectコンポーネントからemitで呼び出されて、選択操作後の処理用のmethodを呼び出す。
selectコンポーネントのコード
<template>
<span>
<select :value="value" @input="selected">
<option v-for="option in options" :key="option.code" :value="option.code">
{{ option.name }}
</option> </select
><span class="slot-text"><slot></slot></span>
</span>
</template>
<script>
export default {
props: {
id: {
type: String,
default: '',
},
value: {
type: String,
default: '',
required: true,
},
options: {
type: Array,
required: true,
},
},
methods: {
selected($event) {
this.$emit('selected', $event.target.value, this.id);
},
},
};
</script>
v-modelなしで初期値を指定するため、:value="value"でpropsに渡される値を設定する。
注意点としてはイベントは@inputで設定してあること、@changeではありません。
どこかの記事で@changeではうまく動作しない可能性があるから@inputのほうが無難でしょう。
親に値を渡すため、みんな大好きemitを使って、選択されたvalueと操作したselectフォームのidを渡してます。
あとは親コンポーネントで適宜に処理すればOKです。
最後に
独自ルールがあるから色々とselectフォームの実装について調べました。v-selectというものを使えばもっと楽に実装できますが、保守や拡張性を考えるとやはり自前で実装した方が良いですね。
かなりマイナーの内容でしたが、最後まで読んで頂きありがとうございます。
それではまだ。
Discussion