<script lang="ts" setup> import { onMounted, ref, reactive, computed } from 'vue'; // import { date } from 'quasar'; import { isEmpty } from 'src/common/utils'; interface Props { modelValue: any; dense?: boolean; disable?: boolean; readonly?: boolean; config?: any; } const props = withDefaults(defineProps<Props>(), { // modelValue: date.formatDate(Date.now(), 'YYYY/MM/DD HH:mm'), modelValue: null, dense: false, disable: false, readonly: false, config: () => { return {}; }, }); const emit = defineEmits<{ (e: 'update:modelValue', value: any): void; }>(); const myDateRange = ref<any>(null); const dates = computed({ set(value: any) { // console.log('set', value); emit('update:modelValue', value); }, get() { // console.log('get', props.modelValue); let res = null; // 多选 if (props.config?.multiple) { if (isEmpty(props.modelValue)) { res = null; } else { const typeofs = Object.prototype.toString.call(props.modelValue); if (typeofs === '[object Array]') { const rangeList = props.modelValue.map((item: any) => { const str = `${item.from}~${item.to}`; return str; }); res = rangeList.join(','); } else { res = null; } } } // 单选 else { if (isEmpty(props.modelValue)) { res = null; } else { const typeofs = Object.prototype.toString.call(props.modelValue); if (typeofs === '[object Object]') { const from = props.modelValue.from; const to = props.modelValue.to; if (!from || !to) { console.warn('无效时间范围'); res = null; } else { const fromDate = new Date(from); const toDate = new Date(to); if (toDate <= fromDate) { console.warn('结束时间不能大于开始时间'); res = null; } else { res = `${from}~${to}`; } } } else if (typeofs === '[object String]') { res = props.modelValue; } else { res = null; } } } return res; }, }); const dateMask = computed(() => { let obj = { date: 'YYYY/MM/DD', }; if (!isEmpty(props.config) && props.config.dateMask) { const maskList = props.config.dateMask.split(' '); obj.date = maskList[0]; } return obj; }); const dateProxyDate = ref<any>(null); const dateLocale = reactive({ daysShort: '六_日_一_二_三_四_五'.split('_'), months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split( '_' ), monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), firstDayOfWeek: 1, format24h: true, pluralDay: 'dias', }); const toolTipData = computed(() => { let str = ''; // 多选 if (props.config?.multiple) { if (!isEmpty(dates.value)) { str = dates.value.replace(new RegExp(',', 'g'), '<br />'); } } // 单选 else { } return str; }); onMounted(() => { const inputElement = myDateRange.value.$el.firstElementChild.firstElementChild.firstElementChild .firstElementChild; inputElement.setAttribute('unselectable', 'on'); inputElement.setAttribute('readonly', true); }); function updateProxy() { const _dates = dates.value; if (!isEmpty(_dates)) { // 多选 if (props.config?.multiple) { console.log('updateProxy', _dates); const list1 = _dates.split(','); const rangeList = list1.map((item: any) => { const rangeArr = item.split('~'); return { from: rangeArr[0], to: rangeArr[1], }; }); dateProxyDate.value = rangeList; } // 单选 else { const dateList = _dates.split('~'); if (dateList.length === 2) { dateProxyDate.value = { from: dateList[0], to: dateList[1], }; } else if (dateList.length === 1) { dateProxyDate.value = dateList[0]; } else { dateProxyDate.value = null; } } } else { dateProxyDate.value = null; } } function onClickDate() { // console.log('点击确定', dateProxyDate.value); // 多选 if (props.config?.multiple) { if (isEmpty(dateProxyDate.value)) { dates.value = null; } else { dates.value = dateProxyDate.value; } } // 单选 else { if (isEmpty(dateProxyDate.value)) { dates.value = null; } else { dates.value = dateProxyDate.value; } } } </script> <template> <div class="hcy-datetime-pick"> <q-input v-model="dates" v-bind="config" ref="myDateRange" :dense="config.dense === undefined ? props.dense : config.dense" :disable="config.disable === undefined ? props.disable : config.disable" :readonly=" config.readonly === undefined ? props.readonly : config.readonly " > <q-tooltip v-if="!isEmpty(dates) && toolTipData"> <span v-html="toolTipData"></span ></q-tooltip> <template v-slot:append> <q-icon name="event" class="cursor-pointer"> <q-popup-proxy v-if="!props.readonly" @before-show="updateProxy" transition-show="scale" transition-hide="scale" class="row" > <q-date flat square minimal range :multiple="config.multiple" v-model="dateProxyDate" :locale="dateLocale" :mask="dateMask.date" class="my-date" > <div class="row items-center justify-end q-gutter-sm"> <q-btn unelevated label="确定" size="sm" color="primary" @click="onClickDate" v-close-popup /> </div> </q-date> </q-popup-proxy> </q-icon> </template> </q-input> </div> </template> <style lang="scss" scoped> .my-date { :deep(.q-date__main .q-date__content .q-date__view .q-date__navigation) { > .relative-position { color: $primary; } } } .my-time { :deep(.q-time__header) { background-color: white; } :deep(.q-time__main .q-time__content .q-time__container-child .q-time__clock .q-time__clock-circle .q-time__clock-position--active) { color: white !important; } } </style>