Study/Vue3
[Vue3] 자식컴포넌트 input value값 가져오기 (defineModel)
hyjang
2024. 12. 10. 16:48
728x90
input 태그를 컴포넌트화하여 form 섹션 안에 포함시키려고 한다.
각각의 input 컴포넌트 value값을 가져와서 부모 컴포넌트에서 사용하려면 어떻게 해야할까?

원래는 자식 컴포넌트에서 emit으로 value값을 부모한테 보내고 부모는 그 value값을 가져오는 과정을 거쳐야하지만,
defineModel을 이용하면 다른 함수 없이 바로 value값을 가져올 수 있다.
자식 컴포넌트
#inputText.vue
<template>
<input
v-model="modelValue"
type="text"
/>
</template>
<script lang="ts" setup>
const modelValue = defineModel();
</script>
부모 컴포넌트
<template
<InputText
v-model="title"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const title = ref('');
</script>
이렇게하면 부모 컴포넌트에 있는 변수 title에 InputText 컴포넌트에서 input 태그에 입력한 value값이 저장된다.
radio나 select input도 가져올 수 있다.
input[type="radio"]
# inputRadio.vue
<template>
<label
>
{{ labelText }}
<input
v-for="item in radioArray"
:key="item.inputValue"
type="radio"
:value="item.inputValue"
:checked="item.checkedBoolean"
v-model="modelValue"
/>
</label>
</template>
<script lang="ts" setup>
import { inputRadioData } from '@/common.type';
defineProps<{
labelText: string;
radioArray: inputRadioData[];
}>();
const modelValue = defineModel();
</script>
radio 버튼은 여러개가 필요하기 때문에 v-for를 이용해서 배열로 전달해준다.
특이한점은 input이 여러개라 그런지 :value와 v-model을 둘다 써줘야 한다.
:value에는 현재 input값의 value값이 있고 v-model은 선택이 되었을때 그 값을 부모 컴포넌트로 전달하는 것으로 보인다.
부모 컴포넌트
<template>
<InputRadio
:labelText="'중요도'"
:radioArray="importantRadio"
v-model="important"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const important = ref<string>('important1');
const importantRadio = ref<inputRadioData[]>([
{
inputValue: 'important1',
checkedBoolean: true,
},
{
inputValue: 'important2',
},
{
inputValue: 'important3',
},
]);
</script>
inputValue로 각각 전달한 :value값을 선택하면 "important"에 저장되어 important.value로 값을 가져올 수 있다.
input[type="select"]
#inputSelect.vue
<template>
<select
v-model="modelValue"
@change="handleChange"
>
<option
:value="item.optionValue"
:selected="item.selectedBoolean"
v-for="item in optionDataArray"
:key="item.toString"
>
{{ item.optionText }}
</option>
</select>
</template>
<script setup lang="ts">
import { optionData } from '@/common.type';
defineProps<{
className: string;
handleChange?: () => void;
optionDataArray: optionData[];
}>();
const modelValue = defineModel();
</script>
select 태그는 @change 이벤트가 필요하고 v-model를 추가해주며, option 태그에 :value를 추가해준다.
부모 컴포넌트
<template>
<FbSelect
:className="'filter__searchSelect'"
:handleChange="sortTodo"
:optionDataArray="sortOption"
v-model:="filterSortTodo"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const filterSortTodo = ref('latest');
const sortOption = ref<optionData[]>([
{
optionValue: 'latest',
optionText: '최신순',
selectedBoolean: true,
},
{
optionValue: 'oldest',
optionText: '오래된순',
},
{
optionValue: 'important',
optionText: '중요도순',
},
]);
/**
* 정렬 함수
*/
const sortTodo = () => {
emit('sortTodo', filterSortTodo.value);
};
</script>
select를 선택하면 v-model로 해당 option의 value값을 가져온다.
@change 함수를 연결하여 이벤트를 줄 수도 있다.