localhost-front/src/components/input/ArrInput.vue

152 lines
4.1 KiB
Vue

<template>
<div class="mb-2 row">
<div class="d-flex">
<label :for="name" class="col-md-2 col-form-label">
{{ title }}
<span :class="isEssential ? 'link-danger' : 'd-none'">*</span>
</label>
<div class="align-content-center col-md-10 text-end ms-auto">
<button type="button" class="btn btn-sm btn-primary" :class="isRow ? '' : 'ms-auto'" @click="openAddressSearch">주소찾기</button>
</div>
</div>
<div :class="isRow ? 'col-md-10 ms-auto' : 'col-md-12'">
<div class="d-flex mb-3">
<input
:id="name"
class="form-control me-2 w-25"
type="text"
v-model="postcode"
placeholder="우편번호"
readonly
/>
<input
class="form-control"
type="text"
v-model="address"
placeholder="기본주소"
readonly
/>
</div>
<div>
<input
class="form-control"
type="text"
v-model="detailAddress"
placeholder="상세주소"
@input="updateDetailAddress"
:maxLength="maxlength"
/>
</div>
<div class="invalid-feedback" :class="isAlert ? 'd-block' : ''">{{ title }} 확인해주세요.</div>
</div>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
const postcode = ref('');
const address = ref('');
const detailAddress = ref('');
const props = defineProps({
title: {
type: String,
default: '라벨',
required: true,
},
name: {
type: String,
default: 'nameplz',
required: true,
},
isEssential: {
type: Boolean,
default: false,
required: false,
},
maxlength: {
type: Number,
default: 30,
required: false,
},
isRow: {
type: Boolean,
default: false,
required: false,
},
isAlert: {
type: Boolean,
default: false,
required: false,
},
modelValue: {
type: Object,
default: () => ({
postcode: '',
address: '',
detailAddress: ''
}),
required: false
}
});
// watch 설정 수정
watch(() => props.modelValue, (newValue) => {
if (newValue) {
postcode.value = newValue.postcode || '';
address.value = newValue.address || '';
detailAddress.value = newValue.detailAddress || '';
}
}, { immediate: true });
const emits = defineEmits(['update:data', 'update:alert', 'update:modelValue']);
// 주소 검색 팝업 열기
const openAddressSearch = () => {
new window.daum.Postcode({
oncomplete: (data) => {
postcode.value = data.zonecode;
address.value = data.address;
// 전체 주소 데이터 내보내기
emitAddressData();
// 상세주소 입력 필드로 포커스 이동
setTimeout(() => {
const detailInput = document.querySelector('input[placeholder="상세주소"]');
if (detailInput) detailInput.focus();
}, 100);
}
}).open();
};
// 상세주소 업데이트
const updateDetailAddress = (event) => {
detailAddress.value = event.target.value;
emitAddressData();
};
// 전체 주소 데이터 내보내기
const emitAddressData = () => {
const fullAddress = {
postcode: postcode.value,
address: address.value,
detailAddress: detailAddress.value,
};
emits('update:data', fullAddress);
emits('update:modelValue', fullAddress); // modelValue도 부모로 전달
};
// isAlert를 false로 설정
watch([postcode, address], ([newPostcode, newAddress]) => {
if (newPostcode && newAddress) {
emits('update:alert', false);
}
});
</script>