127 lines
3.2 KiB
Vue
127 lines
3.2 KiB
Vue
<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 icon="ArrowLeft" size="small" circle @click="prevYear" />
|
||
<span class="current-year">{{ currentYear }}年</span>
|
||
<el-button icon="ArrowRight" size="small" circle @click="nextYear" />
|
||
</div>
|
||
<!-- 四个季度按钮 -->
|
||
<div class="quarter-buttons">
|
||
<el-button
|
||
v-for="q in 4"
|
||
:key="q"
|
||
style="margin: 0"
|
||
:type="isSelected(currentYear, q) ? 'primary' : ''"
|
||
:disabled="isDisabledQuarter(currentYear, q)"
|
||
@click="handleSelect(currentYear, q)"
|
||
>
|
||
第{{ q }}季度
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
<!-- 触发源 -->
|
||
<template #reference>
|
||
<el-input
|
||
:model-value="displayText"
|
||
placeholder="请选择季度"
|
||
readonly
|
||
suffix-icon="Calendar"
|
||
@click="popoverVisible = true"
|
||
clearable
|
||
@clear="handleClear"
|
||
/>
|
||
</template>
|
||
</el-popover>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
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);
|
||
console.log(currentYear.value, typeof currentYear.value);
|
||
|
||
// 输入框展示文本
|
||
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>
|