Files
estate/src/components/QuarterSelect/index.vue
2026-08-31 18:00:11 +08:00

126 lines
3.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="quarter-select">
<!-- 输入框,点击弹出popover -->
<el-popover v-model:visible="popoverVisible" placement="bottom-start" trigger="manual" width="240">
<div class="quarter-panel">
<!-- 年份切换 -->
<div class="year-header">
<el-button circle icon="ArrowLeft" size="small" @click="prevYear" />
<span class="current-year">{{ currentYear }}年</span>
<el-button circle icon="ArrowRight" size="small" @click="nextYear" />
</div>
<!-- 四个季度按钮 -->
<div class="quarter-buttons">
<el-button
v-for="q in 4"
:key="q"
:disabled="isDisabledQuarter(currentYear, q)"
:type="isSelected(currentYear, q) ? 'primary' : ''"
style="margin: 0"
@click="handleSelect(currentYear, q)"
>
第{{ q }}季度
</el-button>
</div>
</div>
<!-- 触发源 -->
<template #reference>
<el-input
:model-value="displayText"
clearable
placeholder="请选择季度"
readonly
suffix-icon="Calendar"
@clear="handleClear"
@click="popoverVisible = true"
/>
</template>
</el-popover>
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
// 外部v‑model绑定
const props = defineProps({
modelValue: {
type: String,
default: '' // "2026‑1"
}
});
const emit = defineEmits(['update:modelValue', 'change']);
// popover弹窗
const popoverVisible = ref(false);
// 解析回显的季度值 2026‑1
const parseQuarter = (str) => {
if (!str) return { year: new Date().getFullYear(), quarter: null };
const [y, q] = str.split('-').map(Number);
return { year: y, quarter: q };
};
const { year: initYear } = parseQuarter(props.modelValue);
const currentYear = ref(initYear);
// 输入框展示文本
const displayText = computed(() => {
if (!props.modelValue) return '';
console.log(props.modelValue, props.modelValue.trim().split('-'));
const [y, q] = props.modelValue.split('-').map(Number);
return `${y}年${q}季度`;
});
// 是否选中该季度
const isSelected = (y, q) => {
return props.modelValue === `${y}-${q}`;
};
// --------------------------
// 【这里写你的禁用逻辑】仿照 disabled‑date
// return true 禁用该季度
// --------------------------
const isDisabledQuarter = () => {
return false;
};
// 切换年份
const prevYear = () => currentYear.value--;
const nextYear = () => currentYear.value++;
// 选中季度
const handleSelect = (y, q) => {
const val = `${y}-${q}`;
emit('update:modelValue', val);
emit('change', val);
popoverVisible.value = false;
};
// 清空
const handleClear = () => {
emit('update:modelValue', '');
emit('change', '');
};
</script>
<style scoped>
.quarter-panel {
padding: 12px;
}
.year-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}
.current-year {
font-weight: 500;
}
.quarter-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
</style>