Vue.js 3.x ComboForm コンポーネント
要求
- 以下のタイプを実装するボタンとエラーメッセージ表示付き input コンポーネント (但し、ボタン部分はエラー色にならない)
- text
- password
- email
- url
- number
- date
- time
fileデザイン的に無理だった。。。
- v-model 対応
- 指定可能な属性が異なるため、$attr をバインドし、それだけで対応できない入力 (checkbox, radio 等) は別のコンポーネントとしてで作成する。
設計
- ボタンをクリックすると、Prop で指定されたイベントを送出する。
- 親コンポーネントで変更された値は、v-model 経由で反映される。
コード
- ComboForm.js
import { computed } from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.esm-browser.js'; import { getWrapClass } from 'https://wws.jp/_export/code/vuejs/vue3/form_utils?codeblock=0'; const ComboForm = { template: ` <div :class="computedControlWrapperClasses" :style="controlWrapperStyles"> <div class="input-group"> <input class="form-control" :type="type" :class="controlClasses" :style="controlStyles" :value="value" v-bind="$attrs" @input="updateValue($event.target.value)" > <span class="input-group-btn has-error"> <button class="btn btn-default" type="button" @click="emitButtonEvent">{{ buttonLabel }}</button> </span> </div> <div :class="computedMessageWrapperClasses" :style="messageWrapperStyles"> <template v-for="msg in errors"> <span>{{ msg }}</span><br> </template> </div> </div> `, props: { type: { type: String, default: 'text' }, value: { type: String }, buttonLabel: { type: String, default: 'submit' }, buttonEvent: { type: String, default: 'comboclick' }, errors: { type: Array, default: [] }, controlWrapperClasses: { type: Array, default: [] }, controlWrapperStyles: { type: Object, default: {} }, controlClasses: { type: Array, default: [] }, controlStyles: { type: Object, default: {} }, messageWrapperClasses: { type: Array, default: [] }, messageWrapperStyles: { type: Object, default: {} }, controlErrorClass: { type: String, default: 'has-error' }, messageErrorClass: { type: String, default: 'text-danger' }, }, setup(props, context) { const computedControlWrapperClasses = computed(() => { return getWrapClass( props.errors, props.controlWrapperClasses, props.controlErrorClass ) }) const computedMessageWrapperClasses = computed(() => { return getWrapClass( props.errors, props.messageWrapperClasses, props.messageErrorClass ) }) function emitButtonEvent() { context.emit(props.buttonEvent, 'dummy') } function updateValue(v) { context.emit('update:value', v) } return { computedControlWrapperClasses, computedMessageWrapperClasses, emitButtonEvent, updateValue } } }; export default ComboForm;
Props
Property | Type | Default | Description |
---|---|---|---|
type | String | 'text' | input タグの type 指定 (text, password, email, url, date, time) |
value | String | v-model プロパティとして value を持つ | |
buttonEvent | String | コンボボタンをクリックした際の、イベント名を指定する | |
controlWrapperClasses | Array | [] | select を囲う div タグに反映するクラス |
controlWrapperStyles | Object | {} | select を囲う div タグに反映するスタイル |
controlClasses | Array | [] | 入力コントロールに反映するクラス |
controlStyles | Object | {} | 入力コントロールに反映するスタイル |
messageWrapperClasses | Array | [] | エラーメッセージを囲う div タグに反映するクラス |
errors | Array | [] | エラーメッセージの配列 |
controlErrorClass | String | 'has-error' | コントロールに反映するエラークラス |
messageErrorClass | String | 'text-danger' | エラーメッセージに反映するエラークラス |
※ ここで記述されていない number や date, time などに指定可能なプロパティ min, max, step などは $attrs で input タグに自動的にバインドする.
Events
Event | Value |
---|---|
update:value | 選択された値 |
Demo