はじめに
ボタンをクリックすることでフォームの下部にテキストフィールドが追加されるような挙動を実装してみます。
環境
vue 3.2.13
typescript 4.5.5
naive-ui 2.35.0
実装
一つのフィールドで一つの構造体を表現するようにします。
仮でHogeという構造体を作りました。
<template>
<NFormItem
v-for="(product, index) in productionsRef"
:key="index"
:ref="(el) => setRef(el, index)"
>
<NInput />
</NFormItem>
</template>
<script setup lang="ts">
class Hoge {
}
const productionForms = ref<FormItemInst[]>([])
</script>
フィールドの参照には関数を渡します。
<template>
<NFormItem
v-for="(product, index) in productionsRef"
:key="index"
:ref="(el) => setRef(el, index)"
>
<NInput />
</NFormItem>
</template>
<script setup lang="ts">
const setRef = (el: FormItemInst, index: number) => {
productionForms.value[index] = el
}
</script>
あとはボタンクリック時にフィールドが増えるようにします。
<script setup lang="ts">
const onClickAddField = () => {
productionsRef.value = productionsRef.value.concat(new Hoge())
}
</script>
ソースコードはこちらです。
<template>
<div style="width: 600px;">
<NForm ref="formRef">
<NFormItem
v-for="(product, index) in productionsRef"
:key="index"
:ref="(el) => setRef(el, index)"
>
<NInput />
</NFormItem>
<NRow :gutter="[0, 24]">
<NCol :span="24">
<div style="display: flex; justify-content: flex-end;">
<NButton
round
type="primary"
@click="onClickAddField"
>
ADD FIELD
</NButton>
</div>
</NCol>
</NRow>
</NForm>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import {
FormInst,
FormItemInst,
NForm,
NFormItem,
NInput,
NRow,
NCol,
NButton,
} from 'naive-ui'
class Hoge {
}
const formRef = ref<FormInst | null>(null)
const productionsRef = ref<Hoge[]>([new Hoge()])
const productionForms = ref<FormItemInst[]>([])
const onClickAddField = () => {
productionsRef.value = productionsRef.value.concat(new Hoge())
}
const setRef = (el: FormItemInst, index: number) => {
productionForms.value[index] = el
}
</script>
