133 lines
3.9 KiB
Vue
133 lines
3.9 KiB
Vue
<template>
|
|
<div class="mb-2">
|
|
<label :for="name" class="col-md-2 col-form-label">
|
|
{{ title }}
|
|
<span :class="isEssential ? 'link-danger' : 'd-none'">*</span>
|
|
</label>
|
|
<div class="col-md-12">
|
|
<div v-if="useInputGroup" class="input-group mb-1">
|
|
<input
|
|
:id="name"
|
|
class="form-control"
|
|
:type="type"
|
|
@input="updateInput"
|
|
:value="computedValue"
|
|
:disabled="disabled"
|
|
:maxLength="maxlength"
|
|
:placeholder="title"
|
|
@blur="$emit('blur')"
|
|
/>
|
|
<span class="input-group-text">@ localhost.co.kr</span>
|
|
</div>
|
|
<div v-else>
|
|
<input
|
|
:id="name"
|
|
class="form-control"
|
|
:type="type"
|
|
:max="type === 'date' ? today : null"
|
|
@input="updateInput"
|
|
:value="computedValue"
|
|
:disabled="disabled"
|
|
:maxLength="maxlength"
|
|
:placeholder="title"
|
|
@blur="$emit('blur')"
|
|
@click="handleDateClick"
|
|
ref="inputElement"
|
|
/>
|
|
</div>
|
|
<div class="invalid-feedback" :class="isAlert ? 'd-block' : ''">{{ title }}를 확인해주세요.</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { inject, computed, ref } from 'vue';
|
|
|
|
const props = defineProps({
|
|
title: {
|
|
type: String,
|
|
default: '라벨',
|
|
required: true,
|
|
},
|
|
name: {
|
|
type: String,
|
|
default: 'nameplz',
|
|
required: true,
|
|
},
|
|
isEssential: {
|
|
type: Boolean,
|
|
default: false,
|
|
required: false,
|
|
},
|
|
type: {
|
|
type: String,
|
|
default: 'text',
|
|
required: false,
|
|
},
|
|
value: {
|
|
type: String,
|
|
default: '',
|
|
required: false,
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false,
|
|
required: false,
|
|
},
|
|
maxlength: {
|
|
type: Number,
|
|
default: 30,
|
|
required: false,
|
|
},
|
|
isAlert: {
|
|
type: Boolean,
|
|
default: false,
|
|
required: false,
|
|
},
|
|
useInputGroup: {
|
|
type: Boolean,
|
|
default: false,
|
|
required: false,
|
|
},
|
|
});
|
|
|
|
const emits = defineEmits(['update:data', 'update:alert', 'blur']);
|
|
const inputElement = ref(null);
|
|
|
|
// dayjs 인스턴스 가져오기
|
|
const dayjs = inject('dayjs');
|
|
|
|
// 오늘 날짜를 YYYY-MM-DD 형식으로 변환
|
|
const today = dayjs().format('YYYY-MM-DD');
|
|
|
|
// date인 경우 기본값 -> 오늘 날짜
|
|
const computedValue = computed(() => {
|
|
return props.type === 'date' ? props.value || today : props.value;
|
|
});
|
|
|
|
// 입력값 업데이트
|
|
const updateInput = event => {
|
|
const newValue = event.target.value.slice(0, props.maxlength);
|
|
|
|
// date인 경우 날짜 형식 유지
|
|
if (props.type === 'date') {
|
|
emits('update:data', newValue.replace(/[^0-9-]/g, ''));
|
|
} else {
|
|
emits('update:data', newValue);
|
|
}
|
|
|
|
// 값이 입력될 때 isAlert를 false로 설정
|
|
if (newValue.trim() !== '') {
|
|
emits('update:alert', false);
|
|
}
|
|
};
|
|
|
|
// date 타입일 때 input 클릭 시 달력 열기
|
|
const handleDateClick = (event) => {
|
|
if (props.type === 'date' && inputElement.value) {
|
|
// 프로그래매틱하게 달력 열기: 날짜 선택기 UI를 표시
|
|
inputElement.value.showPicker();
|
|
}
|
|
};
|
|
</script>
|