| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- <template>
- <view class="wd-year-panel">
- <view v-if="showPanelTitle" class="wd-year-panel__title">{{ title }}</view>
- <scroll-view class="wd-year-panel__container" :style="`height: ${scrollHeight}px`" scroll-y @scroll="yearScroll" :scroll-top="scrollTop">
- <view v-for="(item, index) in years" :key="index" :id="`year${index}`">
- <year
- :type="type"
- :date="item.date"
- :value="value"
- :min-date="minDate"
- :max-date="maxDate"
- :max-range="maxRange"
- :formatter="formatter"
- :range-prompt="rangePrompt"
- :allow-same-day="allowSameDay"
- :default-time="defaultTime"
- :showTitle="index !== 0"
- @change="handleDateChange"
- />
- </view>
- </scroll-view>
- </view>
- </template>
- <script lang="ts">
- export default {
- options: {
- addGlobalClass: true,
- virtualHost: true,
- styleIsolation: 'shared'
- }
- }
- </script>
- <script lang="ts" setup>
- import { computed, ref, onMounted } from 'vue'
- import { compareYear, formatYearTitle, getYears } from '../utils'
- import { isArray, isNumber, pause } from '../../common/util'
- import Year from '../year/year.vue'
- import { yearPanelProps, type YearInfo, type YearPanelExpose } from './types'
- const props = defineProps(yearPanelProps)
- const emit = defineEmits(['change'])
- const scrollTop = ref<number>(0) // 滚动位置
- const scrollIndex = ref<number>(0) // 当前显示的年份索引
- // 滚动区域的高度
- const scrollHeight = computed(() => {
- const scrollHeight: number = props.panelHeight + (props.showPanelTitle ? 26 : 16)
- return scrollHeight
- })
- // 年份信息
- const years = computed<YearInfo[]>(() => {
- return getYears(props.minDate, props.maxDate).map((year, index) => {
- return {
- date: year,
- height: index === 0 ? 200 : 245
- }
- })
- })
- // 标题
- const title = computed(() => {
- return formatYearTitle(years.value[scrollIndex.value].date)
- })
- onMounted(() => {
- scrollIntoView()
- })
- async function scrollIntoView() {
- await pause()
- let activeDate: number | null = null
- if (isArray(props.value)) {
- activeDate = props.value![0]
- } else if (isNumber(props.value)) {
- activeDate = props.value
- }
- if (!activeDate) {
- activeDate = Date.now()
- }
- let top: number = 0
- for (let index = 0; index < years.value.length; index++) {
- if (compareYear(years.value[index].date, activeDate) === 0) {
- break
- }
- top += years.value[index] ? Number(years.value[index].height) : 0
- }
- scrollTop.value = 0
- if (top > 0) {
- await pause()
- scrollTop.value = top + 45
- }
- }
- const yearScroll = (event: { detail: { scrollTop: number } }) => {
- if (years.value.length <= 1) {
- return
- }
- const scrollTop = Math.max(0, event.detail.scrollTop)
- doSetSubtitle(scrollTop)
- }
- /**
- * 设置小标题
- * scrollTop 滚动条位置
- */
- function doSetSubtitle(scrollTop: number) {
- let height: number = 0 // 月份高度和
- for (let index = 0; index < years.value.length; index++) {
- height = height + years.value[index].height
- if (scrollTop < height) {
- scrollIndex.value = index
- return
- }
- }
- }
- function handleDateChange({ value }: { value: number[] }) {
- emit('change', {
- value
- })
- }
- defineExpose<YearPanelExpose>({
- scrollIntoView
- })
- </script>
- <style lang="scss" scoped>
- @import './index.scss';
- </style>
|