mirror of
https://gitee.com/wot-design-uni/wot-design-uni.git
synced 2025-12-06 09:08:51 +08:00
refactor: ♻️ 重构Picker和Cell
This commit is contained in:
parent
e6e2383c30
commit
a4f7748348
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<page-wraper>
|
||||
<wd-toast />
|
||||
<view style="margin: 20px 0">
|
||||
<wd-cell-group border>
|
||||
<wd-calendar label="单个日期选择" v-model="value1" @confirm="handleConfirm1" />
|
||||
<wd-calendar label="多个日期选择" type="dates" v-model="value2" @confirm="handleConfirm2" />
|
||||
<wd-calendar label="日期范围选择" type="daterange" v-model="value3" />
|
||||
<wd-calendar label="日期时间选择" type="datetime" v-model="value4" />
|
||||
<wd-calendar label="日期时间范围选择" type="datetimerange" v-model="value5" />
|
||||
<wd-cell title="单个日期选择" :value="cellValue.value1" is-link @click="visible.visible1 = true" />
|
||||
<wd-cell title="多个日期选择" :value="cellValue.value2" is-link @click="visible.visible2 = true" />
|
||||
<wd-cell title="日期范围选择" :value="cellValue.value3" is-link @click="visible.visible3 = true" />
|
||||
<wd-cell title="日期时间选择" :value="cellValue.value4" is-link @click="visible.visible4 = true" />
|
||||
<wd-cell title="日期时间范围选择" :value="cellValue.value5" is-link @click="visible.visible5 = true" />
|
||||
<wd-cell title="周选择" :value="cellValue.value6" is-link @click="visible.visible6 = true" />
|
||||
|
||||
<wd-calendar label="周选择" type="week" v-model="value6" />
|
||||
<wd-calendar label="月选择" type="month" :min-date="minDate" v-model="value7" />
|
||||
<wd-calendar label="周范围选择" :first-day-of-week="1" type="weekrange" v-model="value8" />
|
||||
@ -34,32 +34,49 @@
|
||||
/>
|
||||
<wd-calendar label="before-confirm" v-model="value14" :before-confirm="beforeConfirm" />
|
||||
</wd-cell-group>
|
||||
</view>
|
||||
|
||||
<demo-block transparent title="自定义选择器">
|
||||
<view style="margin: 0 15px">
|
||||
<view style="margin-bottom: 10px">当前选中日期:{{ formatValue }}</view>
|
||||
<wd-calendar v-model="value15" use-default-slot @confirm="handleConfirm4">
|
||||
<wd-button>选择日期</wd-button>
|
||||
</wd-calendar>
|
||||
</view>
|
||||
</demo-block>
|
||||
<demo-block transparent title="open事件">
|
||||
<wd-calendar v-model="value17" @open="handleOpen" />
|
||||
</demo-block>
|
||||
<wd-calendar v-model:visible="visible.visible1" v-model="value1" @confirm="(result) => handleConfirm({ ...result, index: 1 })" />
|
||||
<wd-calendar v-model:visible="visible.visible2" v-model="value2" type="dates" @confirm="(result) => handleConfirm({ ...result, index: 2 })" />
|
||||
<wd-calendar
|
||||
v-model:visible="visible.visible3"
|
||||
v-model="value3"
|
||||
type="daterange"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 3, connectors: ' 至 ' })"
|
||||
/>
|
||||
<wd-calendar
|
||||
v-model:visible="visible.visible4"
|
||||
v-model="value4"
|
||||
type="datetime"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 4, type: 'datetime' })"
|
||||
/>
|
||||
<wd-calendar
|
||||
v-model:visible="visible.visible5"
|
||||
v-model="value5"
|
||||
type="datetimerange"
|
||||
@confirm="(result) => handleConfirm({ ...result, type: 'datetime', index: 5, connectors: ' 至 ' })"
|
||||
/>
|
||||
<wd-calendar v-model:visible="visible.visible6" v-model="value6" type="week" @confirm="(result) => handleConfirm({ ...result, index: 6 })" />
|
||||
</page-wraper>
|
||||
<wd-message-box />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useToast } from '@/uni_modules/wot-design-uni'
|
||||
import { dayjs } from '@/uni_modules/wot-design-uni'
|
||||
import { isArray } from '@/uni_modules/wot-design-uni/components/common/util'
|
||||
import type { CalendarDayItem, CalendarFormatter } from '@/uni_modules/wot-design-uni/components/wd-calendar-view/types'
|
||||
import type { CalendarOnShortcutsClickOption } from '@/uni_modules/wot-design-uni/components/wd-calendar/types'
|
||||
import { ref } from 'vue'
|
||||
import { useMessage } from '@/uni_modules/wot-design-uni'
|
||||
const message = useMessage()
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
const minDate = ref<number>(new Date(new Date().getFullYear() - 20, new Date().getMonth() - 6, new Date().getDate()).getTime())
|
||||
const visible = reactive({
|
||||
visible1: false,
|
||||
visible2: false,
|
||||
visible3: false,
|
||||
visible4: false,
|
||||
visible5: false,
|
||||
visible6: false,
|
||||
visible7: false,
|
||||
visible8: false,
|
||||
visible9: false,
|
||||
visible10: false
|
||||
})
|
||||
|
||||
const value1 = ref<number>(Date.now())
|
||||
const value2 = ref<number[]>([Date.now() - 24 * 60 * 60 * 1000 * 3, Date.now()])
|
||||
@ -78,7 +95,22 @@ const value14 = ref<number | null>(null)
|
||||
const value15 = ref<number | null>(null)
|
||||
const value16 = ref<number>(Date.now())
|
||||
const value17 = ref<number>(Date.now())
|
||||
const formatValue = ref<string>('')
|
||||
|
||||
const cellValue = reactive<{ [key: PropertyKey]: string }>({
|
||||
value1: formatDate(value1.value),
|
||||
value2: value2.value.map((item) => formatDate(item)).join(','),
|
||||
value3: '',
|
||||
value4: formatDate(value4.value, 'datetime'),
|
||||
value5: value5.value.map((item) => formatDate(item, 'datetime')).join(' 至 '),
|
||||
value6: '',
|
||||
value7: '',
|
||||
value8: '',
|
||||
value9: '',
|
||||
value10: ''
|
||||
})
|
||||
|
||||
const minDate = ref<number>(new Date(new Date().getFullYear() - 20, new Date().getMonth() - 6, new Date().getDate()).getTime())
|
||||
|
||||
const formatter: CalendarFormatter = (day: CalendarDayItem) => {
|
||||
const date = new Date(day.date)
|
||||
const now = new Date()
|
||||
@ -158,21 +190,33 @@ const beforeConfirm = ({ value, resolve }: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
function handleConfirm1({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm2({ value }: any) {
|
||||
console.log(value)
|
||||
function handleConfirm({
|
||||
value,
|
||||
type,
|
||||
index,
|
||||
connectors
|
||||
}: {
|
||||
value: string | number | (string | number)[]
|
||||
type?: 'date' | 'datetime'
|
||||
index: number
|
||||
connectors?: string
|
||||
}) {
|
||||
cellValue[`value${index}`] = (isArray(value) ? value : [value]).map((item) => formatDate(item, type)).join(connectors || ',')
|
||||
}
|
||||
|
||||
function handleConfirm3({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm4({ value }: any) {
|
||||
console.log(new Date(value).toString())
|
||||
formatValue.value = new Date(value).toString()
|
||||
|
||||
function formatDate(date: number | string, type?: 'date' | 'datetime') {
|
||||
switch (type) {
|
||||
case 'date':
|
||||
return dayjs(date).format('YYYY-MM-DD')
|
||||
case 'datetime':
|
||||
return dayjs(date).format('YYYY-MM-DD HH:mm:ss')
|
||||
default:
|
||||
return dayjs(date).format('YYYY-MM-DD')
|
||||
}
|
||||
function handleOpen() {
|
||||
message.alert('打开日历')
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -123,20 +123,10 @@ const cellValue = reactive<{ [key: PropertyKey]: any }>({
|
||||
|
||||
const value1 = ref<string[]>([])
|
||||
const value2 = ref<string[]>([])
|
||||
const value3 = ref<string[]>(['130000', '130200', '130204'])
|
||||
const value4 = ref<string[]>([])
|
||||
const value5 = ref<string[]>([])
|
||||
const value6 = ref<string[]>(['130000', '130200', '130204'])
|
||||
const value7 = ref<string[]>([])
|
||||
const value8 = ref<string[]>([])
|
||||
const value9 = ref<string[]>([])
|
||||
const value10 = ref<string[]>([])
|
||||
const value11 = ref<string[]>([])
|
||||
const value12 = ref<string[]>([])
|
||||
const value13 = ref<string[]>([])
|
||||
const value14 = ref<string[]>([])
|
||||
const value15 = ref<string[]>([])
|
||||
const displayValue = ref<string>('')
|
||||
const areaData1 = ref<ColPickerOption[][]>([
|
||||
colPickerData.map((item) => {
|
||||
return {
|
||||
|
||||
@ -1,67 +1,130 @@
|
||||
<template>
|
||||
<page-wraper>
|
||||
<wd-toast />
|
||||
<demo-block transparent>
|
||||
<wd-cell-group border>
|
||||
<wd-datetime-picker label="日期选择" v-model="value1" @confirm="handleConfirm1" />
|
||||
<wd-datetime-picker label="年月日" v-model="value2" type="date" @confirm="handleConfirm2" />
|
||||
<wd-datetime-picker label="年月" v-model="value3" type="year-month" @confirm="handleConfirm3" />
|
||||
<wd-datetime-picker label="年" v-model="value16" type="year" @confirm="handleConfirm16" />
|
||||
<wd-datetime-picker label="时分" v-model="value4" type="time" @confirm="handleConfirm4" />
|
||||
<wd-datetime-picker label="展示格式" v-model="value5" :display-format="displayFormat" @confirm="handleConfirm5" />
|
||||
<wd-datetime-picker label="内部格式" v-model="value6" :formatter="formatter" @confirm="handleConfirm6" />
|
||||
<wd-datetime-picker label="过滤选项" v-model="value7" :filter="filter" @confirm="handleConfirm7" />
|
||||
<wd-datetime-picker label="before-confirm" v-model="value8" :before-confirm="beforeConfirm" @confirm="handleConfirm8" />
|
||||
<wd-datetime-picker label="错误" v-model="value9" error @confirm="handleConfirm9" />
|
||||
<wd-datetime-picker label="必填" v-model="value10" required @confirm="handleConfirm10" />
|
||||
<wd-datetime-picker label="默认日期" v-model="value2" :default-value="value2" />
|
||||
<wd-datetime-picker label="时间范围一年" :minDate="minDate" :maxDate="maxDate" v-model="value17" @confirm="handleConfirm1" />
|
||||
<wd-cell title="日期选择" :value="cellValue.value1" is-link @click="visible.visible1 = true"></wd-cell>
|
||||
<wd-cell title="年月日" :value="cellValue.value2" is-link @click="visible.visible2 = true"></wd-cell>
|
||||
<wd-cell title="年月" :value="cellValue.value3" is-link @click="visible.visible3 = true"></wd-cell>
|
||||
<wd-cell title="年" :value="cellValue.value4" is-link @click="visible.visible4 = true"></wd-cell>
|
||||
<wd-cell title="时分" :value="cellValue.value5" is-link @click="visible.visible5 = true"></wd-cell>
|
||||
<wd-cell title="过滤选项" :value="cellValue.value6" is-link @click="visible.visible6 = true"></wd-cell>
|
||||
<wd-cell title="before-confirm" :value="cellValue.value7" is-link @click="visible.visible7 = true"></wd-cell>
|
||||
<wd-cell title="时间范围一年" :value="cellValue.value8" is-link @click="visible.visible8 = true"></wd-cell>
|
||||
<wd-cell title="区间选择" :value="cellValue.value9" is-link @click="visible.visible9 = true"></wd-cell>
|
||||
<wd-cell title="范围tab展示格式" :value="cellValue.value10" is-link @click="visible.visible10 = true"></wd-cell>
|
||||
</wd-cell-group>
|
||||
</demo-block>
|
||||
<demo-block title="label 不传" transparent>
|
||||
<wd-datetime-picker v-model="value11" @confirm="handleConfirm11" />
|
||||
</demo-block>
|
||||
<demo-block title="大小" transparent>
|
||||
<wd-datetime-picker label="日期选择" size="large" v-model="value12" @confirm="handleConfirm12" />
|
||||
</demo-block>
|
||||
<demo-block title="值靠右展示" transparent>
|
||||
<wd-datetime-picker label="日期选择" align-right v-model="value13" @confirm="handleConfirm13" />
|
||||
</demo-block>
|
||||
<demo-block title="区域选择" transparent>
|
||||
<wd-datetime-picker label="日期选择" title="请选择区间" v-model="value14" @confirm="handleConfirm14" />
|
||||
</demo-block>
|
||||
<demo-block title="范围tab展示格式" transparent>
|
||||
<wd-datetime-picker label="日期选择" v-model="value15" @confirm="handleConfirm15" :display-format-tab-label="displayFormatTabLabel" />
|
||||
</demo-block>
|
||||
<wd-datetime-picker v-model="value1" v-model:visible="visible.visible1" @confirm="(result) => handleConfirm({ ...result, index: 1 })" />
|
||||
<wd-datetime-picker
|
||||
v-model="value2"
|
||||
v-model:visible="visible.visible2"
|
||||
type="date"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 2, type: 'date' })"
|
||||
/>
|
||||
|
||||
<wd-datetime-picker
|
||||
v-model="value3"
|
||||
v-model:visible="visible.visible3"
|
||||
type="year-month"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 3, type: 'year-month' })"
|
||||
/>
|
||||
|
||||
<wd-datetime-picker
|
||||
v-model="value4"
|
||||
v-model:visible="visible.visible4"
|
||||
type="year"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 4, type: 'year' })"
|
||||
/>
|
||||
|
||||
<wd-datetime-picker
|
||||
v-model="value5"
|
||||
v-model:visible="visible.visible5"
|
||||
type="time"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 5, type: 'time' })"
|
||||
/>
|
||||
|
||||
<wd-datetime-picker
|
||||
v-model="value6"
|
||||
v-model:visible="visible.visible6"
|
||||
:filter="filter"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 6 })"
|
||||
/>
|
||||
|
||||
<wd-datetime-picker
|
||||
v-model="value7"
|
||||
v-model:visible="visible.visible7"
|
||||
:before-confirm="beforeConfirm"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 7 })"
|
||||
/>
|
||||
|
||||
<wd-datetime-picker
|
||||
v-model="value8"
|
||||
v-model:visible="visible.visible8"
|
||||
:minDate="minDate"
|
||||
:maxDate="maxDate"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 8 })"
|
||||
/>
|
||||
|
||||
<wd-datetime-picker
|
||||
v-model:visible="visible.visible9"
|
||||
title="请选择区间"
|
||||
v-model="value9"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 9 })"
|
||||
/>
|
||||
|
||||
<wd-datetime-picker
|
||||
v-model:visible="visible.visible10"
|
||||
v-model="value10"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 10 })"
|
||||
:display-format-tab-label="displayFormatTabLabel"
|
||||
/>
|
||||
</page-wraper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useToast } from '@/uni_modules/wot-design-uni'
|
||||
import type { DatetimePickerViewFilter, DatetimePickerViewFormatter } from '@/uni_modules/wot-design-uni/components/wd-datetime-picker-view/types'
|
||||
import { useToast, dayjs } from '@/uni_modules/wot-design-uni'
|
||||
import { isArray } from '@/uni_modules/wot-design-uni/components/common/util'
|
||||
import type {
|
||||
DatetimePickerDisplayFormat,
|
||||
DatetimePickerDisplayFormatTabLabel,
|
||||
DatetimePickerInstance
|
||||
} from '@/uni_modules/wot-design-uni/components/wd-datetime-picker/types'
|
||||
import { ref } from 'vue'
|
||||
DatetimePickerViewFilter,
|
||||
DatetimePickerViewFormatter,
|
||||
DateTimeType
|
||||
} from '@/uni_modules/wot-design-uni/components/wd-datetime-picker-view/types'
|
||||
import type { DatetimePickerDisplayFormatTabLabel, DatetimePickerInstance } from '@/uni_modules/wot-design-uni/components/wd-datetime-picker/types'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
const visible = reactive({
|
||||
visible1: false,
|
||||
visible2: false,
|
||||
visible3: false,
|
||||
visible4: false,
|
||||
visible5: false,
|
||||
visible6: false,
|
||||
visible7: false,
|
||||
visible8: false,
|
||||
visible9: false,
|
||||
visible10: false
|
||||
})
|
||||
|
||||
const value1 = ref<string>('')
|
||||
const value2 = ref<number>(Date.now())
|
||||
const value3 = ref<number>(Date.now())
|
||||
const value4 = ref<string>('09:20')
|
||||
const value5 = ref<number>(Date.now())
|
||||
const value4 = ref<number>(Date.now())
|
||||
const value5 = ref<string>('09:20')
|
||||
const value6 = ref<number>(Date.now())
|
||||
const value7 = ref<number>(Date.now())
|
||||
const value8 = ref<number>(Date.now())
|
||||
const value9 = ref<number>(Date.now())
|
||||
const value10 = ref<number>(Date.now())
|
||||
const value11 = ref<string>('')
|
||||
const value12 = ref<string>('')
|
||||
const value13 = ref<number>(Date.now())
|
||||
const value14 = ref<any[]>(['', ''])
|
||||
const value15 = ref<any[]>(['', Date.now()])
|
||||
const value16 = ref(Date.now())
|
||||
const value17 = ref(Date.now())
|
||||
const value9 = ref<any[]>(['', ''])
|
||||
const value10 = ref<any[]>(['', ''])
|
||||
|
||||
const cellValue = reactive<{ [key: PropertyKey]: any }>({
|
||||
value1: '',
|
||||
value2: formatDate(value2.value, 'date'),
|
||||
value3: formatDate(value3.value, 'year-month'),
|
||||
value4: formatDate(value4.value, 'year'),
|
||||
value5: '09:20',
|
||||
value6: formatDate(value6.value),
|
||||
value7: formatDate(value7.value),
|
||||
value8: formatDate(value8.value),
|
||||
value9: '',
|
||||
value10: ''
|
||||
})
|
||||
|
||||
const minDate = ref<number>(Date.now())
|
||||
const maxDate = ref<number>(new Date(new Date().getFullYear() + 1, new Date().getMonth(), new Date().getDate()).getTime())
|
||||
@ -88,9 +151,7 @@ const filter: DatetimePickerViewFilter = (type, values) => {
|
||||
}
|
||||
return values
|
||||
}
|
||||
const displayFormat: DatetimePickerDisplayFormat = (items) => {
|
||||
return `${items[0].label}年${items[1].label}月${items[2].label}日 ${items[3].label}:${items[4].label}`
|
||||
}
|
||||
|
||||
const toast = useToast()
|
||||
const beforeConfirm = (value: number | string | (number | string)[], resolve: (isPass: boolean) => void, picker: DatetimePickerInstance) => {
|
||||
picker.setLoading(true)
|
||||
@ -108,57 +169,25 @@ const displayFormatTabLabel: DatetimePickerDisplayFormatTabLabel = (items) => {
|
||||
return `${items[0].label}年${items[1].label}月${items[2].label}日 ${items[3].label}:${items[4].label}`
|
||||
}
|
||||
|
||||
/** picker触发confirm事件,同步触发confirm事件 */
|
||||
function handleConfirm1({ value }: any) {
|
||||
console.log(new Date(value))
|
||||
}
|
||||
function handleConfirm2({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm3({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm4({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm5({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm6({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm7({ value }: any) {
|
||||
console.log(value)
|
||||
function handleConfirm({ value, index, type }: { value: string | number | (string | number)[]; index: number; type?: DateTimeType }) {
|
||||
cellValue[`value${index}`] = (isArray(value) ? value : [value]).map((item) => formatDate(item, type)).join('至')
|
||||
}
|
||||
|
||||
function handleConfirm8({ value }: any) {
|
||||
console.log(value)
|
||||
function formatDate(date: number | string, type?: DateTimeType) {
|
||||
switch (type) {
|
||||
case 'date':
|
||||
return dayjs(date).format('YYYY-MM-DD')
|
||||
case 'year-month':
|
||||
return dayjs(date).format('YYYY-MM')
|
||||
case 'time':
|
||||
return date
|
||||
case 'datetime':
|
||||
return dayjs(date).format('YYYY-MM-DD HH:mm')
|
||||
case 'year':
|
||||
return dayjs(date).format('YYYY')
|
||||
default:
|
||||
return dayjs(date).format('YYYY-MM-DD HH:mm')
|
||||
}
|
||||
function handleConfirm9({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm10({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm11({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm12({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm13({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm14({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm15({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
function handleConfirm16({ value }: any) {
|
||||
console.log(value)
|
||||
}
|
||||
/** picker触发cancel事件,同步触发cancel事件 */
|
||||
function onCancel() {}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -1,49 +1,65 @@
|
||||
<template>
|
||||
<page-wraper>
|
||||
<wd-toast />
|
||||
<demo-block transparent>
|
||||
<wd-cell-group border>
|
||||
<wd-picker label="单列选项" v-model="value0" :columns="columns0" />
|
||||
<wd-picker label="禁用" disabled v-model="value1" :columns="columns1" />
|
||||
<wd-picker label="只读" readonly v-model="value2" :columns="columns2" />
|
||||
<wd-picker label="loading" v-model="value3" loading :columns="columns3" />
|
||||
<wd-picker label="多列" v-model="value4" :columns="columns4" />
|
||||
<wd-picker label="多级联动" v-model="value5" :columns="columns5" :column-change="onChangeDistrict" />
|
||||
<wd-picker label="分隔符" v-model="value6" :columns="columns6" :display-format="displayFormat" />
|
||||
<wd-picker label="标题" v-model="value9" :columns="columns7" title="文案标题" />
|
||||
<wd-picker label="before-confirm" :columns="columns0" v-model="value7" :before-confirm="beforeConfirm" />
|
||||
<wd-picker label="错误" v-model="value10" error :columns="columns0" />
|
||||
<wd-picker label="必填" v-model="value11" :columns="columns0" required />
|
||||
<wd-picker label="可清空" :clearable="true" v-model="value15" :columns="columns5" :column-change="onChangeDistrict" />
|
||||
<wd-cell title="单列选项" :value="cellValue.value1" is-link @click="visible.visible1 = true"></wd-cell>
|
||||
<wd-cell title="loading" :value="cellValue.value2" is-link @click="visible.visible2 = true"></wd-cell>
|
||||
<wd-cell title="多列" :value="cellValue.value3" is-link @click="visible.visible3 = true"></wd-cell>
|
||||
<wd-cell title="多级联动" :value="cellValue.value4" is-link @click="visible.visible4 = true"></wd-cell>
|
||||
<wd-cell title="自定义标题" :value="cellValue.value5" is-link @click="visible.visible5 = true" />
|
||||
<wd-cell title="before-confirm" :value="cellValue.value6" is-link @click="visible.visible6 = true" />
|
||||
</wd-cell-group>
|
||||
</demo-block>
|
||||
<demo-block title="label 不传" transparent>
|
||||
<wd-picker :columns="columns0" v-model="value12" />
|
||||
</demo-block>
|
||||
<demo-block title="大小" transparent>
|
||||
<wd-picker label="单列选项" v-model="value13" size="large" :columns="columns0" />
|
||||
</demo-block>
|
||||
<demo-block title="值靠右显示" transparent>
|
||||
<wd-picker label="单列选项" v-model="value14" align-right :columns="columns0" />
|
||||
</demo-block>
|
||||
<demo-block title="默认插槽" transparent>
|
||||
<view class="default-slot">
|
||||
<view class="default-slot-txt">
|
||||
选中值:
|
||||
<text style="color: #34d19d">{{ value8 }}</text>
|
||||
</view>
|
||||
<wd-picker :columns="columns0" v-model="value8" use-default-slot @confirm="handleConfirm">
|
||||
<wd-button>插槽唤起</wd-button>
|
||||
</wd-picker>
|
||||
</view>
|
||||
</demo-block>
|
||||
<wd-picker
|
||||
v-model:visible="visible.visible1"
|
||||
v-model="value1"
|
||||
:columns="columns0"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 1 })"
|
||||
/>
|
||||
<wd-picker
|
||||
v-model:visible="visible.visible2"
|
||||
v-model="value2"
|
||||
loading
|
||||
:columns="columns1"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 2 })"
|
||||
/>
|
||||
<wd-picker
|
||||
v-model="value3"
|
||||
v-model:visible="visible.visible3"
|
||||
:columns="columns2"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 3 })"
|
||||
/>
|
||||
<wd-picker
|
||||
v-model="value4"
|
||||
v-model:visible="visible.visible4"
|
||||
:columns="columns3"
|
||||
:column-change="onChangeDistrict"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 4 })"
|
||||
/>
|
||||
|
||||
<wd-picker
|
||||
v-model="value5"
|
||||
v-model:visible="visible.visible5"
|
||||
:columns="columns4"
|
||||
title="文案标题"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 5 })"
|
||||
/>
|
||||
|
||||
<wd-picker
|
||||
v-model="value6"
|
||||
v-model:visible="visible.visible6"
|
||||
:columns="columns0"
|
||||
:before-confirm="beforeConfirm"
|
||||
@confirm="(result) => handleConfirm({ ...result, index: 6 })"
|
||||
/>
|
||||
</page-wraper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useToast } from '@/uni_modules/wot-design-uni'
|
||||
import type { ColumnItem, PickerViewColumnChange } from '@/uni_modules/wot-design-uni/components/wd-picker-view/types'
|
||||
import type { PickerBeforeConfirm, PickerDisplayFormat } from '@/uni_modules/wot-design-uni/components/wd-picker/types'
|
||||
import { ref } from 'vue'
|
||||
import { isArray } from '@/uni_modules/wot-design-uni/components/common/util'
|
||||
import type { PickerViewColumnChange } from '@/uni_modules/wot-design-uni/components/wd-picker-view/types'
|
||||
import type { PickerBeforeConfirm } from '@/uni_modules/wot-design-uni/components/wd-picker/types'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
@ -89,44 +105,20 @@ const district: Record<string, Array<{ label: string; value: string }>> = {
|
||||
}
|
||||
|
||||
const columns0 = ref(['选项1选项1选项1选项1选项1选项1选项1选项1选项1选项1选项1选项1选项1', '选项2', '选项3', '选项4', '选项5', '选项6', '选项7'])
|
||||
const value0 = ref('')
|
||||
|
||||
const value1 = ref('选项3')
|
||||
const columns1 = ref(['选项1', '选项2', '选项3', '选项4', '选项5', '选项6', '选项7'])
|
||||
const columns2 = ref([
|
||||
['中山大学', '中南大学', '华南理工大学'],
|
||||
['计算机科学与技术', '软件工程', '通信工程', '法学', '经济学']
|
||||
])
|
||||
const columns3 = ref([district[0], district[district[0][0].value], district[district[district[0][0].value][0].value]])
|
||||
const columns4 = ref(['选项1', '选项2', '选项3', '选项4', '选项5', '选项6', '选项7'])
|
||||
|
||||
const value1 = ref('')
|
||||
const value2 = ref('选项4')
|
||||
const columns2 = ref(['选项1', '选项2', '选项3', '选项4', '选项5', '选项6', '选项7'])
|
||||
|
||||
const columns3 = ref(['选项1', '选项2', '选项3', '选项4', '选项5', '选项6', '选项7'])
|
||||
const value3 = ref('选项4')
|
||||
|
||||
const value3 = ref([])
|
||||
const value4 = ref([])
|
||||
const columns4 = ref([
|
||||
['中山大学', '中南大学', '华南理工大学'],
|
||||
['计算机科学与技术', '软件工程', '通信工程', '法学', '经济学']
|
||||
])
|
||||
|
||||
const value5 = ref(['110000', '110100', '110102'])
|
||||
const value15 = ref(['110000', '110100', '110102'])
|
||||
const columns5 = ref([district[0], district[district[0][0].value], district[district[district[0][0].value][0].value]])
|
||||
|
||||
const value6 = ref(['中南大学', '软件工程'])
|
||||
const value8 = ref('选项2')
|
||||
const value9 = ref('选项1')
|
||||
const value10 = ref('选项2')
|
||||
|
||||
const value11 = ref('选项3')
|
||||
const value12 = ref('选项3')
|
||||
const value13 = ref('选项3')
|
||||
const value14 = ref('选项3')
|
||||
|
||||
const columns6 = ref([
|
||||
['中山大学', '中南大学', '华南理工大学'],
|
||||
['计算机科学与技术', '软件工程', '通信工程', '法学', '经济学']
|
||||
])
|
||||
|
||||
const columns7 = ref(['选项1', '选项2', '选项3', '选项4', '选项5', '选项6', '选项7'])
|
||||
|
||||
const value7 = ref('')
|
||||
const value5 = ref('选项1')
|
||||
const value6 = ref('')
|
||||
|
||||
const onChangeDistrict: PickerViewColumnChange = (pickerView, value, columnIndex, resolve) => {
|
||||
const item = (value as Record<string, any>[])[columnIndex]
|
||||
@ -139,14 +131,6 @@ const onChangeDistrict: PickerViewColumnChange = (pickerView, value, columnIndex
|
||||
resolve()
|
||||
}
|
||||
|
||||
const displayFormat: PickerDisplayFormat = (items) => {
|
||||
return (items as ColumnItem[])
|
||||
.map((item) => {
|
||||
return item.label
|
||||
})
|
||||
.join('-')
|
||||
}
|
||||
|
||||
const beforeConfirm: PickerBeforeConfirm = (value, resolve, picker) => {
|
||||
picker.setLoading(true)
|
||||
setTimeout(() => {
|
||||
@ -160,26 +144,30 @@ const beforeConfirm: PickerBeforeConfirm = (value, resolve, picker) => {
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
function handleConfirm({ value }: any) {
|
||||
value8.value = value
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.wot-theme-dark {
|
||||
.default-slot {
|
||||
background: $-dark-background2;
|
||||
}
|
||||
.default-slot-txt {
|
||||
color: $-dark-color3;
|
||||
}
|
||||
}
|
||||
.default-slot {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
function handleConfirm({ selectedItems, index }: { selectedItems: Record<string, any> | Record<string, any>[]; index: number }) {
|
||||
cellValue[`value${index}`] = (isArray(selectedItems) ? selectedItems : [selectedItems])
|
||||
.map((item) => {
|
||||
return item.label
|
||||
})
|
||||
.join('/')
|
||||
}
|
||||
|
||||
.default-slot-txt {
|
||||
margin-bottom: 10px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
</style>
|
||||
const visible = reactive({
|
||||
visible1: false,
|
||||
visible2: false,
|
||||
visible3: false,
|
||||
visible4: false,
|
||||
visible5: false,
|
||||
visible6: false
|
||||
})
|
||||
|
||||
const cellValue = reactive<{ [key: PropertyKey]: any }>({
|
||||
value1: '',
|
||||
value2: '选项4',
|
||||
value3: '',
|
||||
value4: '',
|
||||
value5: '选项1',
|
||||
value6: ''
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* @Author: weisheng
|
||||
* @Date: 2024-03-15 20:40:34
|
||||
* @LastEditTime: 2024-11-13 13:18:15
|
||||
* @LastEditTime: 2024-12-03 13:29:49
|
||||
* @LastEditors: weisheng
|
||||
* @Description:
|
||||
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-calendar\types.ts
|
||||
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-calendar/types.ts
|
||||
* 记得注释
|
||||
*/
|
||||
import type { PropType } from 'vue'
|
||||
@ -110,7 +110,11 @@ export const calendarProps = {
|
||||
/**
|
||||
* 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
||||
*/
|
||||
immediateChange: makeBooleanProp(false)
|
||||
immediateChange: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否显示
|
||||
*/
|
||||
visible: makeBooleanProp(false)
|
||||
}
|
||||
|
||||
export type CalendarDisplayFormat = (value: number | number[], type: CalendarType) => string
|
||||
|
||||
@ -4,14 +4,17 @@
|
||||
v-model="pickerShow"
|
||||
:duration="250"
|
||||
:close-on-click-modal="closeOnClickModal"
|
||||
:safe-area-inset-bottom="safeAreaInsetBottom"
|
||||
:hide-when-close="false"
|
||||
:z-index="zIndex"
|
||||
@close="close"
|
||||
:safe-area-inset-bottom="safeAreaInsetBottom"
|
||||
@close="handlePickerClose"
|
||||
@closed="handlePickerClosed"
|
||||
@opened="handlePickerOpened"
|
||||
>
|
||||
<view class="wd-calendar__header">
|
||||
<view v-if="!showTypeSwitch && shortcuts.length === 0" class="wd-calendar__title">{{ title || translate('title') }}</view>
|
||||
<view v-if="showTypeSwitch" class="wd-calendar__tabs">
|
||||
<wd-tabs ref="calendarTabs" v-model="currentTab" @change="handleTypeChange">
|
||||
<wd-tabs ref="tabsRef" v-model="currentTab" @change="handleTypeChange">
|
||||
<wd-tab :title="translate('day')" :name="translate('day')" />
|
||||
<wd-tab :title="translate('week')" :name="translate('week')" />
|
||||
<wd-tab :title="translate('month')" :name="translate('month')" />
|
||||
@ -32,10 +35,7 @@
|
||||
</view>
|
||||
<wd-icon custom-class="wd-calendar__close" name="add" @click="close" />
|
||||
</view>
|
||||
<view
|
||||
v-if="inited"
|
||||
:class="`wd-calendar__view ${currentType.indexOf('range') > -1 ? 'is-range' : ''} ${showConfirm ? 'is-show-confirm' : ''}`"
|
||||
>
|
||||
<view :class="`wd-calendar__view ${currentType.indexOf('range') > -1 ? 'is-range' : ''} ${showConfirm ? 'is-show-confirm' : ''}`">
|
||||
<view v-if="range(type)" :class="`wd-calendar__range-label ${type === 'monthrange' ? 'is-monthrange' : ''}`">
|
||||
<view
|
||||
:class="`wd-calendar__range-label-item ${!calendarValue || !isArray(calendarValue) || !calendarValue[0] ? 'is-placeholder' : ''}`"
|
||||
@ -49,7 +49,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<wd-calendar-view
|
||||
ref="calendarView"
|
||||
ref="calendarViewRef"
|
||||
v-model="calendarValue"
|
||||
:type="currentType"
|
||||
:min-date="minDate"
|
||||
@ -93,11 +93,12 @@ import wdActionSheet from '../wd-action-sheet/wd-action-sheet.vue'
|
||||
import wdButton from '../wd-button/wd-button.vue'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { dayjs } from '../common/dayjs'
|
||||
import { deepClone, isArray, isEqual, padZero, requestAnimationFrame } from '../common/util'
|
||||
import { deepClone, isArray, isEqual, padZero } from '../common/util'
|
||||
import { getWeekNumber, isRange } from '../wd-calendar-view/utils'
|
||||
import { useTranslate } from '../composables/useTranslate'
|
||||
import { calendarProps, type CalendarExpose } from './types'
|
||||
import type { CalendarType } from '../wd-calendar-view/types'
|
||||
import type { CalendarType, CalendarViewInstance } from '../wd-calendar-view/types'
|
||||
import type { TabsInstance } from '../wd-tabs/types'
|
||||
const { translate } = useTranslate('calendar')
|
||||
|
||||
const formatRange = (value: number, rangeType: 'start' | 'end', type: CalendarType) => {
|
||||
@ -130,20 +131,21 @@ const formatRange = (value: number, rangeType: 'start' | 'end', type: CalendarTy
|
||||
}
|
||||
|
||||
const props = defineProps(calendarProps)
|
||||
const emit = defineEmits(['cancel', 'change', 'update:modelValue', 'confirm', 'open'])
|
||||
const emit = defineEmits(['cancel', 'change', 'update:modelValue', 'confirm', 'open', 'update:visible', 'close'])
|
||||
|
||||
const pickerShow = ref<boolean>(false)
|
||||
const calendarValue = ref<null | number | number[]>(null)
|
||||
const lastCalendarValue = ref<null | number | number[]>(null)
|
||||
const panelHeight = ref<number>(338)
|
||||
const confirmBtnDisabled = ref<boolean>(true)
|
||||
const confirmBtnDisabled = computed(() => {
|
||||
return getConfirmBtnStatus(calendarValue.value)
|
||||
})
|
||||
const currentTab = ref<number>(0)
|
||||
const lastTab = ref<number>(0)
|
||||
const currentType = ref<CalendarType>('date')
|
||||
const lastCurrentType = ref<CalendarType>()
|
||||
const inited = ref<boolean>(false)
|
||||
const calendarView = ref()
|
||||
const calendarTabs = ref()
|
||||
const calendarViewRef = ref<CalendarViewInstance>() // 日历组件实例
|
||||
const tabsRef = ref<TabsInstance>() // tabs组件实例
|
||||
|
||||
const rangeLabel = computed(() => {
|
||||
const [start, end] = deepClone(isArray(calendarValue.value) ? calendarValue.value : [])
|
||||
@ -157,13 +159,24 @@ watch(
|
||||
(val, oldVal) => {
|
||||
if (isEqual(val, oldVal)) return
|
||||
calendarValue.value = deepClone(val)
|
||||
confirmBtnDisabled.value = getConfirmBtnStatus(val)
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
open()
|
||||
} else {
|
||||
close()
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.type,
|
||||
(newValue) => {
|
||||
@ -201,11 +214,11 @@ const range = computed(() => {
|
||||
})
|
||||
|
||||
function scrollIntoView() {
|
||||
calendarView.value && calendarView.value && calendarView.value.$.exposed.scrollIntoView()
|
||||
calendarViewRef.value && calendarViewRef.value && calendarViewRef.value!.scrollIntoView()
|
||||
}
|
||||
|
||||
// 对外暴露方法
|
||||
function open() {
|
||||
inited.value = true
|
||||
pickerShow.value = true
|
||||
lastCalendarValue.value = deepClone(calendarValue.value)
|
||||
lastTab.value = currentTab.value
|
||||
@ -213,50 +226,65 @@ function open() {
|
||||
requestAnimationFrame(() => {
|
||||
scrollIntoView()
|
||||
})
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (props.showTypeSwitch) {
|
||||
calendarTabs.value.scrollIntoView()
|
||||
calendarTabs.value.updateLineStyle(false)
|
||||
/**
|
||||
* 弹出框打开后
|
||||
*/
|
||||
function handlePickerOpened() {
|
||||
if (props.showTypeSwitch && tabsRef.value) {
|
||||
tabsRef.value.scrollIntoView()
|
||||
tabsRef.value.updateLineStyle(false)
|
||||
}
|
||||
}, 250)
|
||||
emit('open')
|
||||
}
|
||||
|
||||
// 对外暴露方法
|
||||
function close() {
|
||||
pickerShow.value = false
|
||||
setTimeout(() => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框关闭时
|
||||
*/
|
||||
function handlePickerClose() {
|
||||
emit('update:visible', false)
|
||||
emit('close')
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框关闭后
|
||||
*/
|
||||
function handlePickerClosed() {
|
||||
calendarValue.value = deepClone(lastCalendarValue.value)
|
||||
currentTab.value = lastTab.value
|
||||
currentType.value = lastCurrentType.value || 'date'
|
||||
confirmBtnDisabled.value = getConfirmBtnStatus(lastCalendarValue.value)
|
||||
}, 250)
|
||||
emit('cancel')
|
||||
scrollIntoView()
|
||||
}
|
||||
|
||||
function handleTypeChange({ index }: { index: number }) {
|
||||
const tabs = ['date', 'week', 'month']
|
||||
const rangeTabs = ['daterange', 'weekrange', 'monthrange']
|
||||
const tabs: CalendarType[] = ['date', 'week', 'month']
|
||||
const rangeTabs: CalendarType[] = ['daterange', 'weekrange', 'monthrange']
|
||||
const type = props.type.indexOf('range') > -1 ? rangeTabs[index] : tabs[index]
|
||||
currentTab.value = index
|
||||
currentType.value = type as CalendarType
|
||||
currentType.value = type
|
||||
}
|
||||
|
||||
function getConfirmBtnStatus(value: number | number[] | null) {
|
||||
let confirmBtnDisabled = false
|
||||
let disabled = false
|
||||
// 范围选择未选择满,或者多日期选择未选择日期,按钮置灰不可点击
|
||||
if (
|
||||
(props.type.indexOf('range') > -1 && (!isArray(value) || !value[0] || !value[1] || !value)) ||
|
||||
(props.type === 'dates' && (!isArray(value) || value.length === 0 || !value)) ||
|
||||
!value
|
||||
) {
|
||||
confirmBtnDisabled = true
|
||||
disabled = true
|
||||
}
|
||||
|
||||
return confirmBtnDisabled
|
||||
return disabled
|
||||
}
|
||||
|
||||
function handleChange({ value }: { value: number | number[] | null }) {
|
||||
calendarValue.value = deepClone(value)
|
||||
confirmBtnDisabled.value = getConfirmBtnStatus(value)
|
||||
|
||||
emit('change', {
|
||||
value
|
||||
})
|
||||
@ -265,6 +293,7 @@ function handleChange({ value }: { value: number | number[] | null }) {
|
||||
handleConfirm()
|
||||
}
|
||||
}
|
||||
|
||||
function handleConfirm() {
|
||||
if (props.beforeConfirm) {
|
||||
props.beforeConfirm({
|
||||
@ -280,10 +309,13 @@ function handleConfirm() {
|
||||
function onConfirm() {
|
||||
pickerShow.value = false
|
||||
lastCurrentType.value = currentType.value
|
||||
lastCalendarValue.value = deepClone(calendarValue.value)
|
||||
lastTab.value = currentTab.value
|
||||
emit('update:modelValue', calendarValue.value)
|
||||
emit('confirm', {
|
||||
value: calendarValue.value
|
||||
})
|
||||
emit('update:visible', false)
|
||||
}
|
||||
|
||||
function handleShortcutClick(index: number) {
|
||||
@ -294,9 +326,7 @@ function handleShortcutClick(index: number) {
|
||||
index
|
||||
})
|
||||
)
|
||||
confirmBtnDisabled.value = getConfirmBtnStatus(calendarValue.value)
|
||||
}
|
||||
|
||||
if (!props.showConfirm) {
|
||||
handleConfirm()
|
||||
}
|
||||
|
||||
@ -66,15 +66,7 @@ export const colPickerProps = {
|
||||
/**
|
||||
* 弹出面板是否设置底部安全距离(iphone X 类型的机型)
|
||||
*/
|
||||
safeAreaInsetBottom: makeBooleanProp(true),
|
||||
/**
|
||||
* 底部条宽度,单位像素
|
||||
*/
|
||||
lineWidth: numericProp,
|
||||
/**
|
||||
* 底部条高度,单位像素
|
||||
*/
|
||||
lineHeight: numericProp
|
||||
safeAreaInsetBottom: makeBooleanProp(true)
|
||||
}
|
||||
|
||||
export type ColPickerProps = ExtractPropTypes<typeof colPickerProps>
|
||||
@ -87,7 +79,6 @@ export type ColPickerColumnChangeOption = {
|
||||
finish: (isOk?: boolean) => void
|
||||
}
|
||||
export type ColPickerColumnChange = (option: ColPickerColumnChangeOption) => void
|
||||
export type ColPickerDisplayFormat = (selectedItems: ColPickerOption[]) => string
|
||||
export type ColPickerBeforeConfirm = (value: (string | number)[], selectedItems: ColPickerOption[], resolve: (isPass: boolean) => void) => void
|
||||
|
||||
export type ColPickerExpose = {
|
||||
|
||||
@ -5,14 +5,14 @@
|
||||
:duration="250"
|
||||
:title="title || translate('title')"
|
||||
:close-on-click-modal="closeOnClickModal"
|
||||
:hideWhenClose="false"
|
||||
:hide-when-close="false"
|
||||
:z-index="zIndex"
|
||||
:safe-area-inset-bottom="safeAreaInsetBottom"
|
||||
@opened="handlePickerOpened"
|
||||
@close="handlePickerClose"
|
||||
@closed="handlePickerClosed"
|
||||
>
|
||||
<wd-tabs ref="tabs" v-model="currentCol" :animated="animated" slidable="always">
|
||||
<wd-tabs ref="tabsRef" v-model="currentCol" :animated="animated" slidable="always">
|
||||
<wd-tab v-for="(col, colIndex) in innerColumns" :key="colIndex" :title="`${currentColumn[colIndex] || translate('select')}`" :name="colIndex">
|
||||
<view class="wd-col-picker__list-container">
|
||||
<view class="wd-col-picker__list">
|
||||
@ -62,7 +62,7 @@ import { colPickerProps, type ColPickerExpose, type ColPickerOption } from './ty
|
||||
import type { TabsInstance } from '../wd-tabs/types'
|
||||
|
||||
const { translate } = useTranslate('col-picker')
|
||||
const tabs = ref<TabsInstance>()
|
||||
const tabsRef = ref<TabsInstance>()
|
||||
|
||||
const props = defineProps(colPickerProps)
|
||||
const emit = defineEmits(['close', 'update:modelValue', 'update:visible', 'confirm'])
|
||||
@ -70,7 +70,6 @@ const innerValue = ref(props.modelValue) // 当前选择值
|
||||
const innerColumns = ref<ColPickerOption[][]>(props.columns) // 全部列数据
|
||||
const currentColumn = ref<ColPickerOption[]>([]) // 当前展示列数据
|
||||
const animated = ref<boolean>(false) // 是否开启切换动画 弹窗打开后开启
|
||||
|
||||
const pickerShow = ref<boolean>(false)
|
||||
const currentCol = ref<number>(0)
|
||||
const loading = ref<boolean>(false)
|
||||
@ -134,8 +133,8 @@ function updateInnerValue() {
|
||||
* 弹出框打开后
|
||||
*/
|
||||
function handlePickerOpened() {
|
||||
if (isDef(tabs.value)) {
|
||||
tabs.value?.updateLineStyle(false)
|
||||
if (isDef(tabsRef.value)) {
|
||||
tabsRef.value?.updateLineStyle(false)
|
||||
animated.value = true
|
||||
}
|
||||
}
|
||||
@ -153,17 +152,15 @@ function handlePickerClose() {
|
||||
*/
|
||||
function handlePickerClosed() {
|
||||
animated.value = false
|
||||
setTimeout(() => {
|
||||
innerColumns.value = lastSelectList.value.slice(0)
|
||||
innerValue.value = lastPickerColSelected.value.slice(0)
|
||||
currentColumn.value = lastPickerColSelected.value.map((item, colIndex) => {
|
||||
return getSelectedItem(item, colIndex, lastSelectList.value)[props.labelKey]
|
||||
})
|
||||
currentCol.value = lastSelectList.value.length - 1
|
||||
if (isDef(tabs.value)) {
|
||||
tabs.value.updateLineStyle(false)
|
||||
if (isDef(tabsRef.value)) {
|
||||
tabsRef.value.updateLineStyle(false)
|
||||
}
|
||||
}, 250)
|
||||
}
|
||||
|
||||
function getSelectedItem(value: string | number, colIndex: number, innerColumns: ColPickerOption[][]) {
|
||||
|
||||
@ -90,10 +90,6 @@ export const datetimePickerProps = {
|
||||
* 在区域选择模式下,自定义展示tab标签文案的格式化函数,返回一个字符串
|
||||
*/
|
||||
displayFormatTabLabel: Function as PropType<DatetimePickerDisplayFormatTabLabel>,
|
||||
/**
|
||||
* 默认日期,类型保持与 value 一致,打开面板时面板自动选到默认日期
|
||||
*/
|
||||
defaultValue: [String, Number, Array] as PropType<string | number | Array<string | number>>,
|
||||
/**
|
||||
* 弹窗层级
|
||||
*/
|
||||
@ -105,7 +101,11 @@ export const datetimePickerProps = {
|
||||
/**
|
||||
* 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
||||
*/
|
||||
immediateChange: makeBooleanProp(false)
|
||||
immediateChange: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否显示
|
||||
*/
|
||||
visible: makeBooleanProp(false)
|
||||
}
|
||||
|
||||
export type DatetimePickerDisplayFormat = (items: Record<string, any>[]) => string
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<view :class="`wd-picker ${customClass}`" :style="customStyle">
|
||||
<!--弹出层,picker-view 在隐藏时修改值,会触发多次change事件,从而导致所有列选中第一项,因此picker在关闭时不隐藏 -->
|
||||
<wd-popup
|
||||
v-model="popupShow"
|
||||
position="bottom"
|
||||
@ -8,24 +7,20 @@
|
||||
:close-on-click-modal="closeOnClickModal"
|
||||
:safe-area-inset-bottom="safeAreaInsetBottom"
|
||||
:z-index="zIndex"
|
||||
@close="onCancel"
|
||||
@leave="handlePickerClose"
|
||||
@after-leave="handlePickerClosed"
|
||||
custom-class="wd-picker__popup"
|
||||
>
|
||||
<view class="wd-picker__wraper">
|
||||
<!--toolBar-->
|
||||
<view class="wd-picker__toolbar" @touchmove="noop">
|
||||
<!--取消按钮-->
|
||||
<view class="wd-picker__action wd-picker__action--cancel" @click="onCancel">
|
||||
<view class="wd-picker__action wd-picker__action--cancel" @click="close">
|
||||
{{ cancelButtonText || translate('cancel') }}
|
||||
</view>
|
||||
<!--标题-->
|
||||
<view v-if="title" class="wd-picker__title">{{ title }}</view>
|
||||
<!--确定按钮-->
|
||||
<view :class="`wd-picker__action ${loading || isLoading ? 'is-loading' : ''}`" @click="onConfirm">
|
||||
{{ confirmButtonText || translate('confirm') }}
|
||||
</view>
|
||||
</view>
|
||||
<!-- 区域选择tab展示 -->
|
||||
<view v-if="region" class="wd-picker__region-tabs">
|
||||
<view :class="`wd-picker__region ${showStart ? 'is-active' : ''} `" @click="tabChange">
|
||||
<view>{{ translate('start') }}</view>
|
||||
@ -36,7 +31,6 @@
|
||||
<view class="wd-picker__region-time">{{ showTabLabel[1] }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!--datetimePickerView-->
|
||||
<view :class="showStart ? 'wd-picker__show' : 'wd-picker__hidden'">
|
||||
<wd-datetime-picker-view
|
||||
:custom-class="customViewClass"
|
||||
@ -123,7 +117,7 @@ import { datetimePickerProps, type DatetimePickerExpose } from './types'
|
||||
import { dayjs } from '../common/dayjs'
|
||||
|
||||
const props = defineProps(datetimePickerProps)
|
||||
const emit = defineEmits(['change', 'open', 'toggle', 'cancel', 'confirm', 'update:modelValue'])
|
||||
const emit = defineEmits(['change', 'open', 'toggle', 'cancel', 'confirm', 'update:modelValue', 'update:visible', 'close'])
|
||||
|
||||
const { translate } = useTranslate('datetime-picker')
|
||||
|
||||
@ -166,6 +160,18 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
open()
|
||||
} else {
|
||||
close()
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.displayFormat,
|
||||
(fn) => {
|
||||
@ -227,22 +233,6 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.defaultValue,
|
||||
(val) => {
|
||||
if (isArray(val) || region.value) {
|
||||
innerValue.value = deepClone(getDefaultInnerValue(true))
|
||||
endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
|
||||
} else {
|
||||
innerValue.value = deepClone(getDefaultInnerValue())
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* @description 自定义列项筛选规则,对每列单项进行禁用校验,最终返回传入PickerView的columns数组
|
||||
* @param {Component} picker datetimePickerView对象
|
||||
@ -317,34 +307,20 @@ function getSelects(picker: 'before' | 'after') {
|
||||
function noop() {}
|
||||
|
||||
function getDefaultInnerValue(isRegion?: boolean, isEnd?: boolean): string | number {
|
||||
const { modelValue: value, defaultValue, maxDate, minDate, type } = props
|
||||
const { modelValue: value, maxDate, minDate, type } = props
|
||||
if (isRegion) {
|
||||
const index = isEnd ? 1 : 0
|
||||
const targetValue = isArray(value) ? (value[index] as string) : ''
|
||||
const targetDefault = isArray(defaultValue) ? (defaultValue[index] as string) : ''
|
||||
const maxValue = type === 'time' ? dayjs(maxDate).format('HH:mm') : maxDate
|
||||
const minValue = type === 'time' ? dayjs(minDate).format('HH:mm') : minDate
|
||||
return targetValue || targetDefault || (isEnd ? maxValue : minValue)
|
||||
return targetValue || (isEnd ? maxValue : minValue)
|
||||
} else {
|
||||
return isDef(value || defaultValue) ? (value as string) || (defaultValue as string) : ''
|
||||
return isDef(value) ? (value as string) : ''
|
||||
}
|
||||
}
|
||||
|
||||
// 对外暴露接口,打开弹框
|
||||
// 打开弹框
|
||||
function open() {
|
||||
showPopup()
|
||||
}
|
||||
|
||||
// 对外暴露接口,关闭弹框
|
||||
function close() {
|
||||
onCancel()
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 展示popup,小程序有个bug,在picker-view弹出时设置value,会触发change事件,而且会将picker-view的value多次触发change重置为第一项
|
||||
*/
|
||||
function showPopup() {
|
||||
emit('open')
|
||||
if (region.value) {
|
||||
popupShow.value = true
|
||||
showStart.value = true
|
||||
@ -357,6 +333,34 @@ function showPopup() {
|
||||
setShowValue(true, false, true)
|
||||
}
|
||||
|
||||
// 关闭弹框
|
||||
function close() {
|
||||
popupShow.value = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框关闭后
|
||||
*/
|
||||
function handlePickerClosed() {
|
||||
let timer = setTimeout(() => {
|
||||
clearTimeout(timer)
|
||||
if (region.value) {
|
||||
innerValue.value = deepClone(getDefaultInnerValue(true))
|
||||
endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
|
||||
} else {
|
||||
innerValue.value = deepClone(getDefaultInnerValue())
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框关闭时
|
||||
*/
|
||||
function handlePickerClose() {
|
||||
emit('update:visible', false)
|
||||
emit('close')
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 区域选择时tab标签切换时触发
|
||||
*/
|
||||
@ -401,23 +405,6 @@ function onChangeEnd({ value }: { value: number | string }) {
|
||||
datetimePickerView1.value && datetimePickerView1.value.setColumns(datetimePickerView1.value.updateColumns())
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 点击取消按钮触发。关闭popup,触发cancel事件。
|
||||
*/
|
||||
function onCancel() {
|
||||
popupShow.value = false
|
||||
setTimeout(() => {
|
||||
if (region.value) {
|
||||
innerValue.value = deepClone(getDefaultInnerValue(true))
|
||||
endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
|
||||
} else {
|
||||
innerValue.value = deepClone(getDefaultInnerValue())
|
||||
}
|
||||
}, 200)
|
||||
|
||||
emit('cancel')
|
||||
}
|
||||
|
||||
/** picker触发confirm事件,同步触发confirm事件 */
|
||||
function onConfirm() {
|
||||
if (props.loading || isLoading.value) return
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
|
||||
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props'
|
||||
import { baseProps, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props'
|
||||
import type { ColumnItem, PickerViewColumnChange } from '../wd-picker-view/types'
|
||||
import type { FormItemRule } from '../wd-form/types'
|
||||
|
||||
export const pickerProps = {
|
||||
...baseProps,
|
||||
@ -72,10 +71,6 @@ export const pickerProps = {
|
||||
* 接收 pickerView 实例、选中项、当前修改列的下标、resolve 作为入参,根据选中项和列下标进行判断,通过 pickerView 实例暴露出来的 setColumnData 方法修改其他列的数据源。
|
||||
*/
|
||||
columnChange: Function as PropType<PickerViewColumnChange>,
|
||||
/**
|
||||
* 自定义展示文案的格式化函数,返回一个字符串
|
||||
*/
|
||||
displayFormat: Function as PropType<PickerDisplayFormat>,
|
||||
/**
|
||||
* 自定义层级
|
||||
*/
|
||||
@ -83,13 +78,15 @@ export const pickerProps = {
|
||||
/**
|
||||
* 是否在手指松开时立即触发 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
||||
*/
|
||||
immediateChange: makeBooleanProp(false)
|
||||
immediateChange: makeBooleanProp(false),
|
||||
/**
|
||||
* 是否显示
|
||||
*/
|
||||
visible: makeBooleanProp(false)
|
||||
}
|
||||
|
||||
export type PickerProps = ExtractPropTypes<typeof pickerProps>
|
||||
|
||||
export type PickerDisplayFormat = (item: ColumnItem | ColumnItem[], vl: { valueKey: string; labelKey: string }) => string
|
||||
|
||||
export type PickerBeforeConfirm = (
|
||||
value: string | number | boolean | string[] | number[] | boolean[],
|
||||
resolve: (isPass: boolean) => void,
|
||||
|
||||
@ -7,12 +7,13 @@
|
||||
:close-on-click-modal="closeOnClickModal"
|
||||
:z-index="zIndex"
|
||||
:safe-area-inset-bottom="safeAreaInsetBottom"
|
||||
@close="onCancel"
|
||||
@leave="handlePickerClose"
|
||||
@after-leave="handlePickerClosed"
|
||||
custom-class="wd-picker__popup"
|
||||
>
|
||||
<view class="wd-picker__wraper">
|
||||
<view class="wd-picker__toolbar" @touchmove="noop">
|
||||
<view class="wd-picker__action wd-picker__action--cancel" @click="onCancel">
|
||||
<view class="wd-picker__action wd-picker__action--cancel" @click="close">
|
||||
{{ cancelButtonText || translate('cancel') }}
|
||||
</view>
|
||||
<view v-if="title" class="wd-picker__title">{{ title }}</view>
|
||||
@ -21,7 +22,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<wd-picker-view
|
||||
ref="pickerViewWd"
|
||||
ref="pickerViewRef"
|
||||
:custom-class="customViewClass"
|
||||
v-model="pickerValue"
|
||||
:columns="displayColumns"
|
||||
@ -55,17 +56,17 @@ export default {
|
||||
<script lang="ts" setup>
|
||||
import wdPopup from '../wd-popup/wd-popup.vue'
|
||||
import wdPickerView from '../wd-picker-view/wd-picker-view.vue'
|
||||
import { getCurrentInstance, onBeforeMount, ref, watch, computed, onMounted, nextTick } from 'vue'
|
||||
import { deepClone, getType, isArray, isDef, isFunction } from '../common/util'
|
||||
import { type ColumnItem, formatArray, type PickerViewInstance } from '../wd-picker-view/types'
|
||||
import { getCurrentInstance, onBeforeMount, ref, watch, computed } from 'vue'
|
||||
import { deepClone, isDef, isFunction } from '../common/util'
|
||||
import { type ColumnItem, type PickerViewInstance } from '../wd-picker-view/types'
|
||||
import { useTranslate } from '../composables/useTranslate'
|
||||
import { pickerProps, type PickerExpose } from './types'
|
||||
const { translate } = useTranslate('picker')
|
||||
|
||||
const props = defineProps(pickerProps)
|
||||
const emit = defineEmits(['confirm', 'open', 'cancel', 'clear', 'update:modelValue'])
|
||||
const emit = defineEmits(['confirm', 'open', 'cancel', 'update:modelValue', 'update:visible', 'close'])
|
||||
|
||||
const pickerViewWd = ref<PickerViewInstance | null>(null)
|
||||
const pickerViewRef = ref<PickerViewInstance | null>(null)
|
||||
|
||||
const innerLoading = ref<boolean>(false) // 内部控制是否loading
|
||||
|
||||
@ -82,28 +83,10 @@ const isLoading = computed(() => {
|
||||
return props.loading || innerLoading.value
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.displayFormat,
|
||||
(fn) => {
|
||||
if (fn && !isFunction(fn)) {
|
||||
console.error('The type of displayFormat must be Function')
|
||||
}
|
||||
if (pickerViewWd.value && pickerViewWd.value.getSelectedIndex().length !== 0) {
|
||||
handleShowValueUpdate(props.modelValue)
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newValue) => {
|
||||
pickerValue.value = newValue
|
||||
// 获取初始选中项,并展示初始选中文案
|
||||
handleShowValueUpdate(newValue)
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
@ -111,13 +94,23 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
open()
|
||||
} else {
|
||||
close()
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.columns,
|
||||
(newValue) => {
|
||||
displayColumns.value = deepClone(newValue)
|
||||
resetColumns.value = deepClone(newValue)
|
||||
// 获取初始选中项,并展示初始选中文案
|
||||
handleShowValueUpdate(props.modelValue)
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
@ -140,106 +133,41 @@ watch(
|
||||
|
||||
const { proxy } = getCurrentInstance() as any
|
||||
|
||||
onMounted(() => {
|
||||
handleShowValueUpdate(props.modelValue)
|
||||
})
|
||||
|
||||
onBeforeMount(() => {
|
||||
displayColumns.value = deepClone(props.columns)
|
||||
resetColumns.value = deepClone(props.columns)
|
||||
})
|
||||
|
||||
/**
|
||||
* 值变更时更新显示内容
|
||||
* @param value
|
||||
*/
|
||||
function handleShowValueUpdate(value: string | number | Array<string | number>) {
|
||||
// 获取初始选中项,并展示初始选中文案
|
||||
if ((isArray(value) && value.length > 0) || (isDef(value) && !isArray(value) && value !== '')) {
|
||||
if (pickerViewWd.value) {
|
||||
nextTick(() => {
|
||||
// setShowValue(pickerViewWd.value!.getSelects())
|
||||
})
|
||||
} else {
|
||||
// setShowValue(getSelects(value)!)
|
||||
}
|
||||
} else {
|
||||
// showValue.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 根据传入的value,picker组件获取当前cell展示值。
|
||||
* @param {String|Number|Array<String|Number|Array<any>>}value
|
||||
*/
|
||||
function getSelects(value: string | number | Array<string | number | Array<any>>) {
|
||||
const formatColumns = formatArray(props.columns, props.valueKey, props.labelKey)
|
||||
if (props.columns.length === 0) return
|
||||
|
||||
// 使其默认选中首项
|
||||
if (value === '' || !isDef(value) || (isArray(value) && value.length === 0)) {
|
||||
return
|
||||
}
|
||||
const valueType = getType(value)
|
||||
const type = ['string', 'number', 'boolean', 'array']
|
||||
if (type.indexOf(valueType) === -1) return []
|
||||
/**
|
||||
* 1.单key转为Array<key>
|
||||
* 2.根据formatColumns的长度截取Array<String>,保证下面的遍历不溢出
|
||||
* 3.根据每列的key值找到选项中value为此key的下标并记录
|
||||
*/
|
||||
value = isArray(value) ? value : [value]
|
||||
value = value.slice(0, formatColumns.length)
|
||||
|
||||
if (value.length === 0) {
|
||||
value = formatColumns.map(() => 0)
|
||||
}
|
||||
let selected: number[] = []
|
||||
value.forEach((target, col) => {
|
||||
let row = formatColumns[col].findIndex((row) => {
|
||||
return row[props.valueKey].toString() === target.toString()
|
||||
})
|
||||
row = row === -1 ? 0 : row
|
||||
selected.push(row)
|
||||
})
|
||||
|
||||
const selects = selected.map((row, col) => formatColumns[col][row])
|
||||
// 单列选择器,则返回单项
|
||||
if (selects.length === 1) {
|
||||
return selects[0]
|
||||
}
|
||||
return selects
|
||||
}
|
||||
|
||||
// 对外暴露方法,打开弹框
|
||||
// 打开弹框
|
||||
function open() {
|
||||
showPopup()
|
||||
}
|
||||
// 对外暴露方法,关闭弹框
|
||||
function close() {
|
||||
onCancel()
|
||||
}
|
||||
/**
|
||||
* 展示popup
|
||||
*/
|
||||
function showPopup() {
|
||||
emit('open')
|
||||
popupShow.value = true
|
||||
pickerValue.value = props.modelValue
|
||||
displayColumns.value = resetColumns.value
|
||||
}
|
||||
// 关闭弹框
|
||||
function close() {
|
||||
popupShow.value = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击取消按钮触发。关闭popup,触发cancel事件。
|
||||
* 弹出框关闭后
|
||||
*/
|
||||
function onCancel() {
|
||||
popupShow.value = false
|
||||
emit('cancel')
|
||||
let timmer = setTimeout(() => {
|
||||
clearTimeout(timmer)
|
||||
isDef(pickerViewWd.value) && pickerViewWd.value.resetColumns(resetColumns.value)
|
||||
function handlePickerClosed() {
|
||||
let timer = setTimeout(() => {
|
||||
clearTimeout(timer)
|
||||
isDef(pickerViewRef.value) && pickerViewRef.value.resetColumns(resetColumns.value)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框关闭时
|
||||
*/
|
||||
function handlePickerClose() {
|
||||
emit('update:visible', false)
|
||||
emit('close')
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击确定按钮触发。展示选中值,触发cancel事件。
|
||||
*/
|
||||
@ -271,15 +199,13 @@ function handleConfirm() {
|
||||
return
|
||||
}
|
||||
|
||||
const selects = pickerViewWd.value!.getSelects()
|
||||
const values = pickerViewWd.value!.getValues()
|
||||
const selects = pickerViewRef.value!.getSelects()
|
||||
const values = pickerViewRef.value!.getValues()
|
||||
// 获取当前的数据源,并设置给 resetColumns,用于取消时可以回退数据源
|
||||
const columns = pickerViewWd.value!.getColumnsData()
|
||||
const columns = pickerViewRef.value!.getColumnsData()
|
||||
popupShow.value = false
|
||||
resetColumns.value = deepClone(columns)
|
||||
emit('update:modelValue', values)
|
||||
|
||||
// setShowValue(selects)
|
||||
emit('confirm', {
|
||||
value: values,
|
||||
selectedItems: selects
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user