Vue.js 3.x LabeledTwoInputsForm コンポーネント
要求
- 2 つのテキスト入力を実装するラベル付きコンポーネント
- v-model 対応
- 再利用可能なコンポーネントとする。
- 指定可能な属性が異なるため、$attr をバインドするが、対応できない場合は別のコンポーネントとしてで作成する。
コード
- LabeledTwoInputsForm.js
import { computed } from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.esm-browser.js'; import LabeledForm from '/_export/code/vuejs/vue3/labeled_form?codeblock=0'; import TwoInputsForm from '/_export/code/vuejs/vue3/two_inputs_form?codeblock=0'; const LabeledTwoInputsForm = { template: ` <labeled-form :errors="errorsCombined" :label-text="labelText" :form-wrapper-classes="formWrapperClasses" :form-wrapper-styles="formWrapperStyles" :label-wrapper-classes="labelWrapperClasses" :label-wrapper-styles="labelWrapperStyles" :form-error-class="formErrorClass" :label-error-class="labelErrorClass" > <template #label v-if="!labelText"> <slot name="label"> </slot> </template> <two-inputs-form v-bind="$attrs" v-model:first-value="firstValue" v-model:second-value="secondValue" @update:first-value="$emit('update:firstValue', $event.target.value)" @update:second-value="$emit('update:secondValue', $event.target.value)" :first-errors="firstErrors" :second-errors="secondErrors" :control-wrapper-classes="controlWrapperClasses" :control-wrapper-styles="controlWrapperStyles" :control-classes="controlClasses" :control-styles="controlStyles" :control-error-class="controlErrorClass" :message-wrapper-classes="messageWrapperClasses" :message-wrapper-styles="messageWrapperStyles" :message-error-class="messageErrorClass" > </two-inputs-form> </labeled-form> `, components: { labeledForm: LabeledForm, twoInputsForm: TwoInputsForm }, props: { firstValue: { type: String }, secondValue: { type: String }, firstErrors: { type: Array, default: [] }, secondErrors: { type: Array, default: [] }, labelText: { type: String }, formWrapperClasses: { type: Array, default: [] }, formWrapperStyles: { type: Object, default: {} }, labelWrapperClasses: { type: Array, default: [] }, labelWrapperStyles: { type: Object, 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: {} }, formErrorClass: { type: String, default: 'has-error' }, labelErrorClass: { type: String, default: 'text-danger' }, controlErrorClass: { type: String, default: 'is-invalid' }, messageErrorClass: { type: String, default: 'text-danger' }, }, setup(props, context) { const errorsCombined = computed(() => { return props.firstErrors.concat(props.secondErrors) }) return { errorsCombined } } }; export default LabeledTwoInputsForm;
Props
type
- type: String
- default: 'text
value
- type: String
errors
- type: Array
- default: []
labelText
- type: String
formWrapperClasses
- type: Array
- default: []
formWrapperStyles
- type: Object
- default: {}
labelWrapperClasses
- type: Array
- default: []
labelWrapperStyles
- type: Object
- default: { paddingTop: '7px' }
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'
formErrorClass
- type: String
- default: 'has-error'
labelErrorClass
- type: String
- default: 'text-danger'
Events
Demo
テーブルライクなレイアウト
<html>
<link rel=“stylesheet” href=“/_export/code/vuejs/vue3/form_styles?codeblock=0”>
<labeled-two-inputs-form v-model:first-value="firstValue" v-model:second-value="secondValue" :first-errors="firstErrors" :second-errors="secondErrors" label-text="Test Label from props" :form-wrapper-classes="['table-form-wrapper']" :label-wrapper-classes="['col-sm-4', 'table-label-wrapper']" :control-wrapper-classes="['col-sm-8', 'table-control-wrapper']" > </labeled-two-inputs-form>
<script type=“module”>
import { createApp } from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.esm-browser.js';
import LabeledTwoInputsForm from '/_export/code/vuejs/vue3/labeled_two_inputs_form?codeblock=0';
const App2 = {
components: {
labeledTwoInputsForm: LabeledTwoInputsForm
},
data() {
return {
testText: 'ABC',
firstValue: 'first',
secondValue: 'second',
firstErrors: ['error message A', 'error message B'],
secondErrors: ['error message A', 'error message B']
}
}
}
createApp(App2).mount('#app2')
</script>
</html>
<html><style>
h2.page-header {
font-weight: 600; font-size: 2.4rem; position: relative; padding: 10px 0 10px 16px; margin-top: 3rem !important; margin-bottom: 2rem !important;
}
h2:before {
content: ""; position: absolute; top: 0; left: 0; width: 6px; height: 100%; background: #ccc;
}
div#disqus__thread {
width: 100% !important;
}
</style></html>