feat: Picker组件优化性能

This commit is contained in:
xuqingkai 2023-08-21 20:25:03 +08:00
parent 09c75d4878
commit 24dd43f3a0
44 changed files with 1614 additions and 1234 deletions

View File

@ -222,7 +222,7 @@ function handleChange({ value }) {
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
| ----------------- | ---------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------- | --------------------- | -------- | | ----------------- | ---------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------- | --------------------- | -------- |
| v-model | 选中值,为 13 位时间戳或时间戳数组 | null / number / array | - | - | - | | v-model | 选中值,为 13 位时间戳或时间戳数组 | null / number / array | - | - | - |
| type | 日期类型 | string | date / dates / datetime / week / month / daterange / datetimerange / weekrange / monthrange | date | - | | type | 日期类型 | string | date / dates / datetime / week / month / daterange / datetimerange / weekrange / monthrange | date | - |
| min-date | 最小日期,为 13 位时间戳 | number | - | 当前日期往前推 6 个月 | - | | min-date | 最小日期,为 13 位时间戳 | number | - | 当前日期往前推 6 个月 | - |
| max-date | 最大日期,为 13 位时间戳 | number | - | 当前日期往后推 6 个月 | - | | max-date | 最大日期,为 13 位时间戳 | number | - | 当前日期往后推 6 个月 | - |
@ -239,15 +239,15 @@ function handleChange({ value }) {
## Events ## Events
| 事件名称 | 说明 | 参数 | 最低版本 | | 事件名称 | 说明 | 参数 | 最低版本 |
| -------- | ---------------- | ------------------------ | -------- | | -------- | ---------------- | ----------- | -------- |
| change | 绑定值变化时触发 | `{ value }` | - | | change | 绑定值变化时触发 | `{ value }` | - |
## Methods ## Methods
| 方法名称 | 说明 | 参数 | 最低版本 | | 方法名称 | 说明 | 参数 | 最低版本 |
| -------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | -------- | | -------------- | ------------------------------------------------------------------------------------------------------------ | ---- | -------- |
| scrollIntoView | 使当前日期或者选中日期滚动到可视区域,并监听滚动,在面板从 隐藏状态(如 display: none 切换为展示状态时调用 | thresholds数字数组具体使用见 [Intersection Observer](https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver) | - | | scrollIntoView | 使当前日期或者选中日期滚动到可视区域,并监听滚动,在面板从 隐藏状态(如 display: none 切换为展示状态时调用 | - |
## 外部样式类 ## 外部样式类

View File

@ -52,19 +52,20 @@
"upload:mp-dingtalk": "uni build -p mp-dingtalk && minici --platform dd" "upload:mp-dingtalk": "uni build -p mp-dingtalk && minici --platform dd"
}, },
"dependencies": { "dependencies": {
"@dcloudio/uni-app": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-app": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-app-plus": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-app-plus": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-components": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-components": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-h5": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-h5": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-mp-alipay": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-alipay": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-mp-baidu": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-baidu": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-mp-jd": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-jd": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-mp-lark": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-lark": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-mp-qq": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-qq": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-weixin": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-mp-xhs": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3081220230802001",
"vitepress": "^1.0.0-beta.6", "vitepress": "^1.0.0-beta.6",
"vue": "^3.2.45", "vue": "^3.2.45",
"vue-i18n": "^9.1.9" "vue-i18n": "^9.1.9"
@ -73,10 +74,10 @@
"@commitlint/cli": "^17.4.4", "@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4", "@commitlint/config-conventional": "^17.4.4",
"@dcloudio/types": "^3.3.2", "@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-automator": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-cli-shared": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-cli-shared": "3.0.0-alpha-3081220230802001",
"@dcloudio/uni-stacktracey": "3.0.0-alpha-3080220230511001", "@dcloudio/uni-stacktracey": "3.0.0-alpha-3081220230802001",
"@dcloudio/vite-plugin-uni": "3.0.0-alpha-3080220230511001", "@dcloudio/vite-plugin-uni": "3.0.0-alpha-3081220230802001",
"@types/node": "^18.14.6", "@types/node": "^18.14.6",
"@typescript-eslint/eslint-plugin": "^5.55.0", "@typescript-eslint/eslint-plugin": "^5.55.0",
"@typescript-eslint/parser": "^5.55.0", "@typescript-eslint/parser": "^5.55.0",

View File

@ -358,7 +358,7 @@
"mp-alipay": { "mp-alipay": {
"allowsBounceVertical": "NO" "allowsBounceVertical": "NO"
}, },
"navigationBarTitleText": "Picker 选择器视图" "navigationBarTitleText": "Picker 选择器"
} }
}, },
{ {

View File

@ -9,7 +9,7 @@
<wd-calendar label="日期时间选择" type="datetime" v-model="value4" /> <wd-calendar label="日期时间选择" type="datetime" v-model="value4" />
<wd-calendar label="日期时间范围选择" type="datetimerange" v-model="value5" /> <wd-calendar label="日期时间范围选择" type="datetimerange" v-model="value5" />
<wd-calendar label="周选择" type="week" v-model="value6" /> <wd-calendar label="周选择" type="week" v-model="value6" />
<wd-calendar label="月选择" type="month" v-model="value7" /> <wd-calendar label="月选择" type="month" :min-date="minDate" v-model="value7" />
<wd-calendar label="周范围选择" :first-day-of-week="1" type="weekrange" v-model="value8" /> <wd-calendar label="周范围选择" :first-day-of-week="1" type="weekrange" v-model="value8" />
<wd-calendar label="月范围选择" type="monthrange" v-model="value9" /> <wd-calendar label="月范围选择" type="monthrange" v-model="value9" />
<wd-calendar label="日周月切换" :first-day-of-week="1" show-type-switch v-model="value10" /> <wd-calendar label="日周月切换" :first-day-of-week="1" show-type-switch v-model="value10" />
@ -51,6 +51,8 @@ import { useToast } from '@/uni_modules/wot-design-uni'
import { dayjs } from '@/uni_modules/wot-design-uni' import { dayjs } from '@/uni_modules/wot-design-uni'
import { ref } from 'vue' import { ref } from 'vue'
const minDate = ref<number>(new Date(new Date().getFullYear() - 20, new Date().getMonth() - 6, new Date().getDate()).getTime())
const value1 = ref<number>(Date.now()) const value1 = ref<number>(Date.now())
const value2 = ref<number[]>([Date.now() - 24 * 60 * 60 * 1000 * 3, Date.now()]) const value2 = ref<number[]>([Date.now() - 24 * 60 * 60 * 1000 * 3, Date.now()])
const value3 = ref<number[]>([]) const value3 = ref<number[]>([])

View File

@ -23,7 +23,7 @@
</demo-block> </demo-block>
<demo-block title="自定义菜单选项" transparent> <demo-block title="自定义菜单选项" transparent>
<view class="custom-menu"> <view class="custom-menu">
<wd-drop-menu style="flex: 1; min-width: 0"> <wd-drop-menu custom-style="flex: 1; min-width: 0">
<wd-drop-menu-item v-model="value4" :options="option1" @change="handleChange4" /> <wd-drop-menu-item v-model="value4" :options="option1" @change="handleChange4" />
</wd-drop-menu> </wd-drop-menu>
<view style="flex: 1"> <view style="flex: 1">

View File

@ -69,6 +69,7 @@ onReady(() => {
}) })
function handleResize(detail: Record<string, string | number>) { function handleResize(detail: Record<string, string | number>) {
console.log(detail)
const { height, width, top, right, bottom, left } = detail const { height, width, top, right, bottom, left } = detail
lastHeight.value = sizeHeight.value lastHeight.value = sizeHeight.value
lastTop.value = sizeTop.value lastTop.value = sizeTop.value

View File

@ -42,6 +42,10 @@
} }
} }
:deep(.wd-action-sheet__popup){
border-radius: $-action-sheet-radius $-action-sheet-radius 0 0;
}
@include b(action-sheet) { @include b(action-sheet) {
background-color: $-color-white; background-color: $-color-white;
padding-bottom: 1px; padding-bottom: 1px;

View File

@ -1,57 +1,59 @@
<template> <template>
<wd-popup <view>
custom-class="wd-action-sheet__popup" <wd-popup
:custom-style="`${(actions && actions.length) || (panels && panels.length) ? 'background: transparent;' : ''}`" custom-class="wd-action-sheet__popup"
v-model="showPopup" :custom-style="`${(actions && actions.length) || (panels && panels.length) ? 'background: transparent;' : ''}`"
:duration="duration" v-model="showPopup"
position="bottom" :duration="duration"
:close-on-click-modal="closeOnClickModal" position="bottom"
:safe-area-inset-bottom="safeAreaInsetBottom" :close-on-click-modal="closeOnClickModal"
:lazy-render="lazyRender" :safe-area-inset-bottom="safeAreaInsetBottom"
@enter="handleOpen" :lazy-render="lazyRender"
@close="close" @enter="handleOpen"
@after-enter="handleOpened" @close="close"
@after-leave="handleClosed" @after-enter="handleOpened"
@clickmodal="handleClickModal" @after-leave="handleClosed"
:z-index="zIndex" @clickmodal="handleClickModal"
> :z-index="zIndex"
<view
class="wd-action-sheet"
:style="`${(actions && actions.length) || (panels && panels.length) ? 'margin: 0 10px 10px; border-radius: 16px;' : ''}`"
> >
<view v-if="title" :class="`wd-action-sheet__header ${customHeaderClass}`"> <view
{{ title }} class="wd-action-sheet"
<wd-icon custom-class="wd-action-sheet__close" name="add" @click="close" /> :style="`${(actions && actions.length) || (panels && panels.length) ? 'margin: 0 10px 10px; border-radius: 16px;' : ''}`"
</view> >
<view class="wd-action-sheet__actions" v-if="actions && actions.length"> <view v-if="title" :class="`wd-action-sheet__header ${customHeaderClass}`">
<button {{ title }}
v-for="(action, rowIndex) in actions" <wd-icon custom-class="wd-action-sheet__close" name="add" @click="close" />
:key="rowIndex" </view>
:class="`wd-action-sheet__action ${action.disabled ? 'wd-action-sheet__action--disabled' : ''} ${ <view class="wd-action-sheet__actions" v-if="actions && actions.length">
action.loading ? 'wd-action-sheet__action--loading' : '' <button
}`" v-for="(action, rowIndex) in actions"
:style="`color: ${action.color}`" :key="rowIndex"
@click="select(rowIndex, 'action')" :class="`wd-action-sheet__action ${action.disabled ? 'wd-action-sheet__action--disabled' : ''} ${
> action.loading ? 'wd-action-sheet__action--loading' : ''
<wd-loading v-if="action.loading" size="20px" /> }`"
<view v-else class="wd-action-sheet__name">{{ action.name }}</view> :style="`color: ${action.color}`"
<view v-if="!action.loading && action.subname" class="wd-action-sheet__subname">{{ action.subname }}</view> @click="select(rowIndex, 'action')"
</button> >
</view> <wd-loading v-if="action.loading" size="20px" />
<view v-if="formatPanels && formatPanels.length"> <view v-else class="wd-action-sheet__name">{{ action.name }}</view>
<view v-for="(panel, rowIndex) in formatPanels" :key="rowIndex" class="wd-action-sheet__panels"> <view v-if="!action.loading && action.subname" class="wd-action-sheet__subname">{{ action.subname }}</view>
<view class="wd-action-sheet__panels-content"> </button>
<view v-for="(col, colIndex) in panel" :key="colIndex" class="wd-action-sheet__panel" @click="select(rowIndex, 'panels', colIndex)"> </view>
<image class="wd-action-sheet__panel-img" :src="(col as any).iconUrl" /> <view v-if="formatPanels && formatPanels.length">
<view class="wd-action-sheet__panel-title">{{ (col as any).title }}</view> <view v-for="(panel, rowIndex) in formatPanels" :key="rowIndex" class="wd-action-sheet__panels">
<view class="wd-action-sheet__panels-content">
<view v-for="(col, colIndex) in panel" :key="colIndex" class="wd-action-sheet__panel" @click="select(rowIndex, 'panels', colIndex)">
<image class="wd-action-sheet__panel-img" :src="(col as any).iconUrl" />
<view class="wd-action-sheet__panel-title">{{ (col as any).title }}</view>
</view>
</view> </view>
</view> </view>
</view> </view>
<slot />
<button v-if="cancelText" class="wd-action-sheet__cancel" @click="handleCancel">{{ cancelText }}</button>
</view> </view>
<slot /> </wd-popup>
<button v-if="cancelText" class="wd-action-sheet__cancel" @click="handleCancel">{{ cancelText }}</button> </view>
</view>
</wd-popup>
</template> </template>
<script lang="ts"> <script lang="ts">
export default { export default {
@ -114,7 +116,7 @@ const props = withDefaults(defineProps<Props>(), {
closeOnClickModal: true, closeOnClickModal: true,
duration: 200, duration: 200,
zIndex: 10, zIndex: 10,
lazyRender: false, lazyRender: true,
safeAreaInsetBottom: true safeAreaInsetBottom: true
}) })
const formatPanels = ref<Array<Panel> | Array<Array<Panel>>>([]) const formatPanels = ref<Array<Panel> | Array<Array<Panel>>>([])

View File

@ -23,8 +23,10 @@
@include b(month) { @include b(month) {
@include e(title) { @include e(title) {
padding: 13px 0; display: flex;
text-align: center; align-items: center;
justify-content: center;
height: 45px;
font-size: $-calendar-panel-title-fs; font-size: $-calendar-panel-title-fs;
color: $-calendar-panel-title-color; color: $-calendar-panel-title-color;
} }

View File

@ -82,7 +82,7 @@ const monthTitle = computed(() => {
} }
}) })
const firstDayStyle = computed(() => { const firstDayStyle = computed(() => {
return (index, date, firstDayOfWeek) => { return (index: number, date: number, firstDayOfWeek: number) => {
return getFirstDayStyle(index, date, firstDayOfWeek) return getFirstDayStyle(index, date, firstDayOfWeek)
} }
}) })

View File

@ -8,16 +8,17 @@
</view> </view>
<scroll-view <scroll-view
:class="`wd-month-panel__container ${!!timeType ? 'wd-month-panel__container--time' : ''}`" :class="`wd-month-panel__container ${!!timeType ? 'wd-month-panel__container--time' : ''}`"
:style="`height: ${!!timeType ? (panelHeight || 378) - 125 : panelHeight || 378}px`" :style="`height: ${scrollHeight}px`"
scroll-y scroll-y
:scroll-into-view="scrollIntoViewValue" @scroll="monthScroll"
:scroll-top="scrollTop"
> >
<view v-for="(item, index) in months(minDate, maxDate)" :key="index" :id="`month${index}`"> <view v-for="(item, index) in months(minDate, maxDate)" :key="index" :id="`month${index}`">
<month <month
class="month" class="month"
:type="type" :type="type"
:date="item" :date="item.date"
:data-date="item" :data-date="item.date"
:value="value" :value="value"
:min-date="minDate" :min-date="minDate"
:max-date="maxDate" :max-date="maxDate"
@ -41,7 +42,6 @@
v-model="timeValue" v-model="timeValue"
:columns="timeData" :columns="timeData"
:columns-height="125" :columns-height="125"
:show-picker="showPicker"
@change="handleTimeChange" @change="handleTimeChange"
@pickstart="handlePickStart" @pickstart="handlePickStart"
@pickend="handlePickEnd" @pickend="handlePickEnd"
@ -64,8 +64,9 @@ export default {
<script lang="ts" setup> <script lang="ts" setup>
import { computed, getCurrentInstance, nextTick, onMounted, ref, watch } from 'vue' import { computed, getCurrentInstance, nextTick, onMounted, ref, watch } from 'vue'
import { debounce, getType, isEqual } from '../../common/util' import { debounce, getType, isEqual } from '../../common/util'
import { compareMonth, formatMonthTitle, getMonths, getTimeData, getWeekLabel } from '../utils' import { compareMonth, formatMonthTitle, getMonthEndDay, getMonths, getTimeData, getWeekLabel } from '../utils'
import Month from '../month/month.vue' import Month from '../month/month.vue'
import { MonthInfo } from './type'
interface Props { interface Props {
type: string type: string
@ -84,35 +85,44 @@ interface Props {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
timeFilter?: Function timeFilter?: Function
hideSecond: boolean hideSecond: boolean
// picker
showPicker: boolean
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
showPicker: true,
allowSameDay: false, allowSameDay: false,
showPanelTitle: false, showPanelTitle: false,
hideSecond: false hideSecond: false
}) })
const title = ref<string>('') const title = ref<string>('')
const scrollIntoViewValue = ref<string>('') const scrollTop = ref<number>(0) //
const timeValue = ref<Array<string>>([]) const timeValue = ref<Array<string>>([])
const timeData = ref<Array<string | string[]>>([]) const timeData = ref<Array<string | string[]>>([])
const timeType = ref<string>('') // const timeType = ref<string>('') //
const innerValue = ref<string | number[]>('') // const innerValue = ref<string | number[]>('') //
let contentObserver: null | UniApp.IntersectionObserver = null
const instance = getCurrentInstance() as any
const weekLabel = computed(() => { const weekLabel = computed(() => {
return (index: number) => { return (index: number) => {
return getWeekLabel(index) return getWeekLabel(index - 1)
} }
}) })
//
const scrollHeight = computed(() => {
const scrollHeight: number = timeType.value ? (props.panelHeight || 378) - 125 : props.panelHeight || 378
return scrollHeight
})
//
const months = computed(() => { const months = computed(() => {
return (minDate, maxDate) => { return (minDate: number, maxDate: number): MonthInfo[] => {
return getMonths(minDate, maxDate) let months = getMonths(minDate, maxDate).map((month) => {
const offset = (7 + new Date(month).getDay() - props.firstDayOfWeek) % 7
const totalDay = getMonthEndDay(new Date(month).getFullYear(), new Date(month).getMonth() + 1)
return {
height: (offset + totalDay > 35 ? 64 * 6 : 64 * 5) + 45,
date: month
}
})
return months
} }
}) })
@ -148,7 +158,6 @@ watch(
) )
onMounted(() => { onMounted(() => {
initRect()
scrollIntoView() scrollIntoView()
}) })
@ -160,26 +169,6 @@ const handleChange = debounce((value) => {
}) })
}, 50) }, 50)
function initRect(thresholds = [0, 0.7, 0.8, 0.9, 1]) {
if (!props.showPanelTitle) return
if (contentObserver != null) {
contentObserver.disconnect()
}
contentObserver = uni.createIntersectionObserver(instance, {
thresholds,
observeAll: true,
dataset: true
} as any)
contentObserver.relativeTo('.wd-month-panel__container')
contentObserver.observe('.month', (res: any) => {
if (res.boundingClientRect.top <= res.relativeRect.top) {
title.value = formatMonthTitle(res.dataset.date)
}
})
}
function scrollIntoView() { function scrollIntoView() {
setTimeout(() => { setTimeout(() => {
let activeDate let activeDate
@ -194,17 +183,18 @@ function scrollIntoView() {
activeDate = Date.now() activeDate = Date.now()
} }
const months = getMonths(props.minDate, props.maxDate) const monthsInfo = months.value(props.minDate, props.maxDate)
months.some((month, index) => { let top: number = 0
if (compareMonth(month, activeDate) === 0) { for (let index = 0; index < monthsInfo.length; index++) {
scrollIntoViewValue.value = '' if (compareMonth(monthsInfo[index].date, activeDate) === 0) {
nextTick(() => { break
scrollIntoViewValue.value = `month${index}`
})
return true
} }
return false top += monthsInfo[index] ? Number(monthsInfo[index].height) : 0
}
scrollTop.value = 0
nextTick(() => {
scrollTop.value = top
}) })
}, 50) }, 50)
} }
@ -275,10 +265,6 @@ function setTime(value, type) {
timeData.value = getTime(value, type) || [] timeData.value = getTime(value, type) || []
timeValue.value = getTimeValue(value, type) timeValue.value = getTimeValue(value, type)
timeType.value = type timeType.value = type
nextTick(() => {
initRect([0, 0.58, 0.69, 0.83, 1])
})
} }
function handleDateChange({ value, type }) { function handleDateChange({ value, type }) {
if (!isEqual(value, props.value)) { if (!isEqual(value, props.value)) {
@ -335,8 +321,31 @@ function handlePickEnd() {
emit('pickend') emit('pickend')
} }
const monthScroll = (event: { detail: { scrollTop: number } }) => {
const monthsInfo = months.value(props.minDate, props.maxDate)
if (monthsInfo.length <= 1) {
return
}
const scrollTop = Math.max(0, event.detail.scrollTop)
doSetSubtitle(scrollTop, monthsInfo)
}
/**
* 设置小标题
* scrollTop 滚动条位置
*/
function doSetSubtitle(scrollTop: number, monthsInfo: MonthInfo[]) {
let height: number = 0 //
for (let index = 0; index < monthsInfo.length; index++) {
height = height + monthsInfo[index].height
if (scrollTop < height + 45) {
title.value = formatMonthTitle(monthsInfo[index].date)
return
}
}
}
defineExpose({ defineExpose({
initRect,
scrollIntoView scrollIntoView
}) })
</script> </script>

View File

@ -0,0 +1,7 @@
/**
*
*/
export interface MonthInfo {
date: number
height: number
}

View File

@ -112,15 +112,14 @@ export function getWeekLabel(index) {
* @param {timestamp} date * @param {timestamp} date
* @param {number} firstDayOfWeek * @param {number} firstDayOfWeek
*/ */
export function getFirstDayStyle(index, date, firstDayOfWeek) { export function getFirstDayStyle(index: number, date: number, firstDayOfWeek: number) {
if (firstDayOfWeek >= 7) { if (firstDayOfWeek >= 7) {
firstDayOfWeek = firstDayOfWeek % 7 firstDayOfWeek = firstDayOfWeek % 7
} }
if (index !== 0) return '' if (index !== 0) return ''
date = new Date(date) const offset = (7 + new Date(date).getDay() - firstDayOfWeek) % 7
const offset = (7 + date.getDay() - firstDayOfWeek) % 7
return 'margin-left: ' + (100 / 7) * offset + '%' return 'margin-left: ' + (100 / 7) * offset + '%'
} }
@ -129,10 +128,8 @@ export function getFirstDayStyle(index, date, firstDayOfWeek) {
* *
* @param {timestamp} date * @param {timestamp} date
*/ */
export function formatYearTitle(date) { export function formatYearTitle(date: number) {
date = new Date(date) const year = new Date(date).getFullYear()
const year = date.getFullYear()
return year + '年' return year + '年'
} }
@ -160,7 +157,7 @@ export function getMonths(minDate, maxDate) {
* @param {timestamp} minDate * @param {timestamp} minDate
* @param {timestamp} maxDate * @param {timestamp} maxDate
*/ */
export function getYears(minDate, maxDate) { export function getYears(minDate: number, maxDate: number) {
const years: number[] = [] const years: number[] = []
const year = new Date(minDate) const year = new Date(minDate)
year.setMonth(0) year.setMonth(0)

View File

@ -33,7 +33,6 @@
:panel-height="panelHeight" :panel-height="panelHeight"
:time-filter="timeFilter" :time-filter="timeFilter"
:hide-second="hideSecond" :hide-second="hideSecond"
:show-picker="showPicker"
@change="handleChange" @change="handleChange"
@pickstart="handlePickStart" @pickstart="handlePickStart"
@pickend="handlePickEnd" @pickend="handlePickEnd"
@ -43,7 +42,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-calendar-view', name: 'wd-calendar-view',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,
@ -92,8 +90,6 @@ interface Props {
timeFilter?: Function timeFilter?: Function
// type 'datetime' 'datetimerange' // type 'datetime' 'datetimerange'
hideSecond: boolean hideSecond: boolean
// picker
showPicker: boolean
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
customClass: '', customClass: '',
@ -105,8 +101,7 @@ const props = withDefaults(defineProps<Props>(), {
showPanelTitle: true, showPanelTitle: true,
defaultTime: '00:00:00', defaultTime: '00:00:00',
panelHeight: 378, panelHeight: 378,
hideSecond: false, hideSecond: false
showPicker: true
}) })
const formatDefauleTime = ref<number[]>([]) const formatDefauleTime = ref<number[]>([])
@ -128,9 +123,8 @@ watch(
const emit = defineEmits(['change', 'update:modelValue', 'pickstart', 'pickend']) const emit = defineEmits(['change', 'update:modelValue', 'pickstart', 'pickend'])
// //
function scrollIntoView(thresholds) { function scrollIntoView() {
const panel = getPanel() const panel = getPanel()
panel.initRect && panel.initRect(thresholds)
panel.scrollIntoView && panel.scrollIntoView() panel.scrollIntoView && panel.scrollIntoView()
} }

View File

@ -24,8 +24,10 @@
@include b(year) { @include b(year) {
@include e(title) { @include e(title) {
padding: 13px 0; display: flex;
text-align: center; align-items: center;
justify-content: center;
height: 45px;
font-size: $-calendar-panel-title-fs; font-size: $-calendar-panel-title-fs;
color: $-calendar-panel-title-color; color: $-calendar-panel-title-color;
} }

View File

@ -0,0 +1,7 @@
/**
*
*/
export interface YearInfo {
date: number
height: number
}

View File

@ -1,18 +1,13 @@
<template> <template>
<view class="wd-year-panel"> <view class="wd-year-panel">
<view v-if="showPanelTitle" class="wd-year-panel__title">{{ title }}</view> <view v-if="showPanelTitle" class="wd-year-panel__title">{{ title }}</view>
<scroll-view <scroll-view class="wd-year-panel__container" :style="`height: ${scrollHeight}px`" scroll-y @scroll="yearScroll" :scroll-top="scrollTop">
class="wd-year-panel__container"
:style="`height: ${(panelHeight || 378) + (showPanelTitle ? 26 : 16)}px`"
scroll-y
:scroll-into-view="scrollIntoViewValue"
>
<view v-for="(item, index) in years(minDate, maxDate)" :key="index" :id="`year${index}`"> <view v-for="(item, index) in years(minDate, maxDate)" :key="index" :id="`year${index}`">
<year <year
class="year" class="year"
:type="type" :type="type"
:date="item" :date="item.date"
:data-date="item" :data-date="item.date"
:value="value" :value="value"
:min-date="minDate" :min-date="minDate"
:max-date="maxDate" :max-date="maxDate"
@ -42,6 +37,7 @@ import { computed, getCurrentInstance, onMounted, ref, nextTick } from 'vue'
import { compareYear, formatYearTitle, getYears } from '../utils' import { compareYear, formatYearTitle, getYears } from '../utils'
import { getType } from '../../common/util' import { getType } from '../../common/util'
import Year from '../year/year.vue' import Year from '../year/year.vue'
import { YearInfo } from './type'
interface Props { interface Props {
type: string type: string
@ -63,21 +59,34 @@ const props = withDefaults(defineProps<Props>(), {
}) })
const title = ref<string>('') const title = ref<string>('')
const scrollTop = ref<number>(0) //
const scrollIntoViewValue = ref<string>('') const scrollIntoViewValue = ref<string>('')
let contentObserver: null | UniApp.IntersectionObserver = null let contentObserver: null | UniApp.IntersectionObserver = null
const instance = getCurrentInstance() as any const instance = getCurrentInstance() as any
//
const scrollHeight = computed(() => {
const scrollHeight: number = (props.panelHeight || 378) + (props.showPanelTitle ? 26 : 16)
return scrollHeight
})
const years = computed(() => { const years = computed(() => {
return (minDate, maxDate) => { return (minDate: number, maxDate: number): YearInfo[] => {
return getYears(minDate, maxDate) let years = getYears(minDate, maxDate).map((year) => {
return {
date: year,
height: 237
}
})
return years
} }
}) })
const emit = defineEmits(['change']) const emit = defineEmits(['change'])
onMounted(() => { onMounted(() => {
initRect()
scrollIntoView() scrollIntoView()
}) })
@ -94,25 +103,6 @@ const requestAnimationFrame = (cb = () => void 0) => {
}) })
} }
function initRect(thresholds = [0, 0.15, 0.7, 0.8, 0.9, 1]) {
if (!props.showPanelTitle) return
if (contentObserver != null) {
contentObserver.disconnect()
}
contentObserver = uni.createIntersectionObserver(instance, {
thresholds,
observeAll: true
})
contentObserver.relativeTo('.wd-year-panel__container')
contentObserver.observe('.year', (res: any) => {
if (res.boundingClientRect.top <= res.relativeRect.top) {
title.value = formatYearTitle(res.dataset.date)
}
})
}
function scrollIntoView() { function scrollIntoView() {
requestAnimationFrame().then(() => { requestAnimationFrame().then(() => {
let activeDate let activeDate
@ -127,21 +117,46 @@ function scrollIntoView() {
activeDate = Date.now() activeDate = Date.now()
} }
const years = getYears(props.minDate, props.maxDate) const yearsInfo = years.value(props.minDate, props.maxDate)
years.some((year, index) => { let top: number = 0
if (compareYear(year, activeDate) === 0) { for (let index = 0; index < yearsInfo.length; index++) {
scrollIntoViewValue.value = '' if (compareYear(yearsInfo[index].date, activeDate) === 0) {
nextTick(() => { break
scrollIntoViewValue.value = `year${index}`
})
return true
} }
top += yearsInfo[index] ? Number(yearsInfo[index].height) : 0
return false }
scrollTop.value = 0
nextTick(() => {
scrollTop.value = top
}) })
}) })
} }
const yearScroll = (e: Event) => {
const yearsInfo = years.value(props.minDate, props.maxDate)
if (yearsInfo.length <= 1) {
return
}
const scrollTop = Math.max(0, (e.target as Element).scrollTop)
doSetSubtitle(scrollTop, yearsInfo)
}
/**
* 设置小标题
* scrollTop 滚动条位置
*/
function doSetSubtitle(scrollTop: number, yearsInfo: YearInfo[]) {
let height: number = 0 //
for (let index = 0; index < yearsInfo.length; index++) {
height = height + yearsInfo[index].height
if (scrollTop < height + 45) {
title.value = formatYearTitle(yearsInfo[index].date)
return
}
}
}
function handleDateChange({ value }) { function handleDateChange({ value }) {
emit('change', { emit('change', {
value value
@ -149,7 +164,6 @@ function handleDateChange({ value }) {
} }
defineExpose({ defineExpose({
initRect,
scrollIntoView scrollIntoView
}) })
</script> </script>

View File

@ -31,8 +31,6 @@
:safe-area-inset-bottom="safeAreaInsetBottom" :safe-area-inset-bottom="safeAreaInsetBottom"
:z-index="zIndex" :z-index="zIndex"
@close="close" @close="close"
@opened="setShowPicker(true)"
@closed="setShowPicker(false)"
> >
<view class="wd-calendar__header"> <view class="wd-calendar__header">
<view v-if="!showTypeSwitch && shortcuts.length === 0" class="wd-calendar__title">{{ title || '选择日期' }}</view> <view v-if="!showTypeSwitch && shortcuts.length === 0" class="wd-calendar__title">{{ title || '选择日期' }}</view>
@ -86,7 +84,6 @@
:default-time="defaultTime" :default-time="defaultTime"
:time-filter="timeFilter" :time-filter="timeFilter"
:hide-second="hideSecond" :hide-second="hideSecond"
:show-picker="showPicker"
:show-panel-title="!range(type)" :show-panel-title="!range(type)"
@change="handleChange" @change="handleChange"
/> />
@ -101,7 +98,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-calendar', name: 'wd-calendar',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,
@ -274,7 +270,6 @@ const currentType = ref<CalendarType>('date')
const lastCurrentType = ref<CalendarType>('date') const lastCurrentType = ref<CalendarType>('date')
const inited = ref<boolean>(false) const inited = ref<boolean>(false)
const rangeLabel = ref<Array<string>>([]) const rangeLabel = ref<Array<string>>([])
const showPicker = ref<boolean>(false)
const cell = useCell() const cell = useCell()
@ -342,10 +337,6 @@ const range = computed(() => {
const emit = defineEmits(['cancel', 'change', 'update:modelValue', 'confirm']) const emit = defineEmits(['cancel', 'change', 'update:modelValue', 'confirm'])
const setShowPicker = debounce(function (show: boolean) {
showPicker.value = show
}, 100)
function scrollIntoView() { function scrollIntoView() {
calendarView.value && calendarView.value && calendarView.value.$.exposed.scrollIntoView() calendarView.value && calendarView.value && calendarView.value.$.exposed.scrollIntoView()
} }

View File

@ -6,7 +6,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-checkbox-group', name: 'wd-checkbox-group',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,

View File

@ -33,7 +33,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-checkbox', name: 'wd-checkbox',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,

View File

@ -80,7 +80,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-col-picker', name: 'wd-col-picker',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,
@ -217,8 +216,6 @@ watch(
selectShowList.value = pickerColSelected.value.map((item, colIndex) => { selectShowList.value = pickerColSelected.value.map((item, colIndex) => {
return getSelectedItem(item, colIndex, newSelectedList)[props.labelKey] return getSelectedItem(item, colIndex, newSelectedList)[props.labelKey]
}) })
console.log(selectShowList.value, 'watch props.columns')
lastSelectList.value = newSelectedList lastSelectList.value = newSelectedList
if (newSelectedList.length > 0) { if (newSelectedList.length > 0) {
@ -372,8 +369,6 @@ function handleColChange(colIndex, item, index, callback?) {
selectShowList.value = pickerColSelected.value.map((item, colIndex) => { selectShowList.value = pickerColSelected.value.map((item, colIndex) => {
return getSelectedItem(item, colIndex, selectList.value)[props.labelKey] return getSelectedItem(item, colIndex, selectList.value)[props.labelKey]
}) })
console.log(selectShowList.value, 'handleColChange')
callback() callback()
} }
}, },
@ -509,6 +504,11 @@ function handleAutoComplete() {
} }
} }
} }
defineExpose({
close,
open
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -0,0 +1,24 @@
export type DateTimeType = 'date' | 'year-month' | 'time' | 'datetime'
/**
* @description 便 pickerView
* @param value
* @param type picker类型
* @return {Array} pickerValue
*/
export function getPickerValue(value, type) {
const values: number[] = []
const date = new Date(value)
if (type === 'time') {
const pair = value.split(':')
values.push(parseInt(pair[0]), parseInt(pair[1]))
} else {
values.push(date.getFullYear(), date.getMonth() + 1)
if (type === 'date') {
values.push(date.getDate())
} else if (type === 'datetime') {
values.push(date.getDate(), date.getHours(), date.getMinutes())
}
}
return values
}

View File

@ -9,7 +9,6 @@
:columnChange="columnChange" :columnChange="columnChange"
:loading="loading" :loading="loading"
:loading-color="loadingColor" :loading-color="loadingColor"
:show-picker="showPicker"
@change="onChange" @change="onChange"
@pickstart="onPickStart" @pickstart="onPickStart"
@pickend="onPickEnd" @pickend="onPickEnd"
@ -19,7 +18,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-datetime-picker-view', name: 'wd-datetime-picker-view',
behaviors: ['uni://form-field'],
virtualHost: true, virtualHost: true,
addGlobalClass: true, addGlobalClass: true,
styleIsolation: 'shared' styleIsolation: 'shared'
@ -29,6 +27,7 @@ export default {
<script lang="ts" setup> <script lang="ts" setup>
import { getCurrentInstance, onBeforeMount, onMounted, ref, watch } from 'vue' import { getCurrentInstance, onBeforeMount, onMounted, ref, watch } from 'vue'
import { debounce, getType, isDef, padZero, range } from '../common/util' import { debounce, getType, isDef, padZero, range } from '../common/util'
import { DateTimeType, getPickerValue } from './type'
// //
/** @description 判断时间戳是否合法 */ /** @description 判断时间戳是否合法 */
@ -58,15 +57,11 @@ const getMonthEndDay = (year, month) => {
return 32 - new Date(year, month - 1, 32).getDate() return 32 - new Date(year, month - 1, 32).getDate()
} }
type DateTimeType = 'date' | 'year-month' | 'time' | 'datetime'
interface Props { interface Props {
customClass?: string customClass?: string
// type time Date // type time Date
modelValue: string | number | Date modelValue: string | number | Date
// PickerViewProps // PickerViewProps
// picker
showPicker: boolean
// //
loading: boolean loading: boolean
loadingColor: string loadingColor: string
@ -106,7 +101,6 @@ interface Props {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
customClass: '', customClass: '',
// PickerViewProps // PickerViewProps
showPicker: true,
// //
loading: false, loading: false,
loadingColor: '#4D80F0', loadingColor: '#4D80F0',
@ -131,7 +125,7 @@ const datePickerview = ref()
// //
const innerValue = ref<null | number>(null) const innerValue = ref<null | number>(null)
// pickerViewcolumns // pickerViewcolumns
const columns = ref<Array<string | string[]>>([]) const columns = ref<Array<string | number>>([])
// pickerViewvalue // pickerViewvalue
const pickerValue = ref<string | number | boolean | Array<string | number | boolean>>([]) const pickerValue = ref<string | number | boolean | Array<string | number | boolean>>([])
// created hook // created hook
@ -432,29 +426,6 @@ function getBoundary(type, innerValue) {
} }
} }
/**
* @description 根据传入的值和类型获取当前的选项数组便于传入 pickerView
* @param value
* @param type picker类型
* @return {Array} pickerValue
*/
function getPickerValue(value, type) {
const values: number[] = []
const date = new Date(value)
if (type === 'time') {
const pair = value.split(':')
values.push(parseInt(pair[0]), parseInt(pair[1]))
} else {
values.push(date.getFullYear(), date.getMonth() + 1)
if (type === 'date') {
values.push(date.getDate())
} else if (type === 'datetime') {
values.push(date.getDate(), date.getHours(), date.getMinutes())
}
}
return values
}
/** /**
* @description 根据传入的value以及type初始化innerValue期间会使用format格式化数据 * @description 根据传入的value以及type初始化innerValue期间会使用format格式化数据
* @param value * @param value
@ -571,7 +542,7 @@ function onPickEnd() {
} }
function getSelects() { function getSelects() {
return datePickerview.value.getSelects() return datePickerview.value && datePickerview.value.getSelects ? datePickerview.value.getSelects() : undefined
} }
defineExpose({ defineExpose({

View File

@ -33,14 +33,11 @@
<wd-popup <wd-popup
v-model="popupShow" v-model="popupShow"
position="bottom" position="bottom"
:lazyRender="false" :hide-when-close="false"
:hide-when-close="true"
:close-on-click-modal="closeOnClickModal" :close-on-click-modal="closeOnClickModal"
:safe-area-inset-bottom="safeAreaInsetBottom" :safe-area-inset-bottom="safeAreaInsetBottom"
:z-index="zIndex" :z-index="zIndex"
@close="onCancel" @close="onCancel"
@enter="setShowPicker(true)"
@leave="setShowPicker(false)"
custom-class="wd-picker__popup" custom-class="wd-picker__popup"
> >
<!--toolBar--> <!--toolBar-->
@ -89,7 +86,6 @@
:max-minute="maxMinute" :max-minute="maxMinute"
:min-minute="minMinute" :min-minute="minMinute"
:start-symbol="true" :start-symbol="true"
:show-picker="showPicker"
@change="onChangeStart" @change="onChangeStart"
@pickstart="onPickStart" @pickstart="onPickStart"
@pickend="onPickEnd" @pickend="onPickEnd"
@ -116,7 +112,6 @@
:max-minute="maxMinute" :max-minute="maxMinute"
:min-minute="minMinute" :min-minute="minMinute"
:start-symbol="false" :start-symbol="false"
:show-picker="showPicker"
@change="onChangeEnd" @change="onChangeEnd"
@pickstart="onPickStart" @pickstart="onPickStart"
@pickend="onPickEnd" @pickend="onPickEnd"
@ -129,7 +124,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-datetime-picker', name: 'wd-datetime-picker',
behaviors: ['uni://form-field'],
options: { options: {
virtualHost: true, virtualHost: true,
addGlobalClass: true, addGlobalClass: true,
@ -140,14 +134,14 @@ export default {
<script lang="ts" setup> <script lang="ts" setup>
import { getCurrentInstance, onBeforeMount, onMounted, ref, watch, nextTick } from 'vue' import { getCurrentInstance, onBeforeMount, onMounted, ref, watch, nextTick } from 'vue'
import { debounce, deepClone, getType, isArray, isDef, isEqual, padZero } from '../common/util' import { deepClone, getType, isArray, isDef, isEqual, padZero } from '../common/util'
import { useCell } from '../mixins/useCell' import { useCell } from '../mixins/useCell'
type DateTimeType = 'date' | 'year-month' | 'time' | 'datetime' import { DateTimeType, getPickerValue } from '../wd-datetime-picker-view/type'
interface Props { interface Props {
customClass?: string customClass: string
customViewClass?: string customViewClass: string
customLabelClass?: string customLabelClass: string
customValueClass?: string customValueClass: string
// //
label?: string label?: string
// //
@ -220,7 +214,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
customClass: '', customClass: '',
customViewClass: '', customViewClass: '',
customLabelVlass: '', customLabelClass: '',
customValueClass: '', customValueClass: '',
// //
placeholder: '请选择', placeholder: '请选择',
@ -273,7 +267,6 @@ const datetimePickerView1 = ref()
const showValue = ref<string | Date | Array<string | Date>>([]) const showValue = ref<string | Date | Array<string | Date>>([])
const popupShow = ref<boolean>(false) const popupShow = ref<boolean>(false)
const showPicker = ref<boolean>(false)
const showStart = ref<boolean>(true) const showStart = ref<boolean>(true)
const region = ref<boolean>(false) const region = ref<boolean>(false)
const showTabLabel = ref<string[]>([]) const showTabLabel = ref<string[]>([])
@ -288,10 +281,6 @@ const { proxy } = getCurrentInstance() as any
const cell = useCell() const cell = useCell()
const setShowPicker = debounce(function (show: boolean) {
showPicker.value = show
}, 100)
watch( watch(
() => props.modelValue, () => props.modelValue,
(val, oldVal) => { (val, oldVal) => {
@ -377,7 +366,7 @@ watch(
watch( watch(
() => props.defaultValue, () => props.defaultValue,
(val) => { (val) => {
if (getType(val) === 'array') { if (getType(val) === 'array' || region.value) {
innerValue.value = deepClone(getDefaultInnerValue(true)) innerValue.value = deepClone(getDefaultInnerValue(true))
endInnerValue.value = deepClone(getDefaultInnerValue(true, true)) endInnerValue.value = deepClone(getDefaultInnerValue(true, true))
} else { } else {
@ -428,14 +417,11 @@ const customColumnFormatter = (picker) => {
}) })
}) })
} }
console.log(mapColumns(columns))
return mapColumns(columns) return mapColumns(columns)
} }
onBeforeMount(() => { onBeforeMount(() => {
const { modelValue: value } = props const { modelValue: value } = props
if (getType(value) === 'array') { if (getType(value) === 'array') {
region.value = true region.value = true
innerValue.value = deepClone(getDefaultInnerValue(true)) innerValue.value = deepClone(getDefaultInnerValue(true))
@ -446,9 +432,28 @@ onBeforeMount(() => {
}) })
onMounted(() => { onMounted(() => {
setShowValue() setShowValue(false, false, true)
}) })
/**
* @description 根据传入的pickerpicker组件获取当前cell展示值
*/
function getSelects(picker: 'before' | 'after') {
let value = picker === 'before' ? innerValue.value : endInnerValue.value
let selected: number[] = []
if (value) {
selected = getPickerValue(value, props.type)
}
let selects = selected.map((value) => {
return {
[props.labelKey]: padZero(value),
[props.valueKey]: value
}
})
return selects
}
function noop() {} function noop() {}
function getDefaultInnerValue(isRegion?: boolean, isEnd?: boolean) { function getDefaultInnerValue(isRegion?: boolean, isEnd?: boolean) {
@ -491,7 +496,7 @@ function showPopup() {
popupShow.value = true popupShow.value = true
innerValue.value = deepClone(getDefaultInnerValue()) innerValue.value = deepClone(getDefaultInnerValue())
} }
setShowValue(true, false) setShowValue(true, false, true)
} }
/** /**
@ -531,6 +536,7 @@ function onChangeStart({ value }) {
*/ */
function onChangeEnd({ value }) { function onChangeEnd({ value }) {
endInnerValue.value = deepClone(value) endInnerValue.value = deepClone(value)
showTabLabel.value = [deepClone(showTabLabel.value[0]), setTabLabel(1)] showTabLabel.value = [deepClone(showTabLabel.value[0]), setTabLabel(1)]
// emit('update:modelValue', [innerValue.value, value]) // emit('update:modelValue', [innerValue.value, value])
emit('change', { emit('change', {
@ -620,9 +626,13 @@ function setTabLabel(index: number = 0) {
if (region.value) { if (region.value) {
let items = [] let items = []
if (index === 0) { if (index === 0) {
items = (datetimePickerView.value && datetimePickerView.value.getSelects()) || [] items =
(datetimePickerView.value && datetimePickerView.value.getSelects && datetimePickerView.value.getSelects()) ||
(innerValue.value && getSelects('before'))
} else { } else {
items = (datetimePickerView1.value && datetimePickerView1.value.getSelects()) || [] items =
(datetimePickerView1.value && datetimePickerView1.value.getSelects && datetimePickerView1.value.getSelects()) ||
(endInnerValue.value && getSelects('after'))
} }
return defaultDisplayFormat(items, true) return defaultDisplayFormat(items, true)
} }
@ -633,16 +643,25 @@ function setTabLabel(index: number = 0) {
* @param {Boolean} tab 是否修改tab展示值尽在区域选择情况下生效 * @param {Boolean} tab 是否修改tab展示值尽在区域选择情况下生效
* @param {Boolean} isConfirm 是否提交当前修改 * @param {Boolean} isConfirm 是否提交当前修改
*/ */
function setShowValue(tab = false, isConfirm = false) { function setShowValue(tab: boolean = false, isConfirm: boolean = false, beforeMount: boolean = false) {
if (region.value) { if (region.value) {
const items = (datetimePickerView.value && datetimePickerView.value.getSelects()) || [] const items = beforeMount
const endItems = (datetimePickerView1.value && datetimePickerView1.value.getSelects()) || [] ? (innerValue.value && getSelects('before')) || []
: (datetimePickerView.value && datetimePickerView.value.getSelects && datetimePickerView.value.getSelects()) || []
const endItems = beforeMount
? (endInnerValue.value && getSelects('after')) || []
: (datetimePickerView1.value && datetimePickerView1.value.getSelects && datetimePickerView1.value.getSelects()) || []
showValue.value = tab showValue.value = tab
? showValue.value ? showValue.value
: [props.modelValue[0] || isConfirm ? defaultDisplayFormat(items) : '', props.modelValue[1] || isConfirm ? defaultDisplayFormat(endItems) : ''] : [props.modelValue[0] || isConfirm ? defaultDisplayFormat(items) : '', props.modelValue[1] || isConfirm ? defaultDisplayFormat(endItems) : '']
showTabLabel.value = [defaultDisplayFormat(items, true), defaultDisplayFormat(endItems, true)] showTabLabel.value = [defaultDisplayFormat(items, true), defaultDisplayFormat(endItems, true)]
} else { } else {
const items = (datetimePickerView.value && datetimePickerView.value.getSelects()) || [] const items = beforeMount
? (innerValue.value && getSelects('before')) || []
: (datetimePickerView.value && datetimePickerView.value.getSelects && datetimePickerView.value.getSelects()) || []
showValue.value = deepClone(props.modelValue || isConfirm ? defaultDisplayFormat(items) : '') showValue.value = deepClone(props.modelValue || isConfirm ? defaultDisplayFormat(items) : '')
} }
} }

View File

@ -1,5 +1,5 @@
<template> <template>
<view :class="`wd-drop-menu ${customClass}`" @click.stop="noop"> <view :style="customStyle" :class="`wd-drop-menu ${customClass}`" @click.stop="noop">
<view class="wd-drop-menu__list"> <view class="wd-drop-menu__list">
<view <view
v-for="(item, index) in titleList" v-for="(item, index) in titleList"
@ -34,7 +34,8 @@ import { getRect } from '../common/util'
type DropDirction = 'up' | 'down' type DropDirction = 'up' | 'down'
interface Props { interface Props {
customClass?: string customClass: string
customStyle: string
zIndex: number zIndex: number
direction: DropDirction direction: DropDirction
modal: boolean modal: boolean
@ -44,6 +45,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
customClass: '', customClass: '',
customStyle: '',
zIndex: 12, zIndex: 12,
direction: 'down', direction: 'down',
modal: true, modal: true,
@ -126,7 +128,7 @@ function fold(child?: any) {
const { top, bottom } = rect const { top, bottom } = rect
if (props.direction === 'down') { if (props.direction === 'down') {
offset.value = bottom + 44 offset.value = bottom
// #ifdef H5 // #ifdef H5
// H5沿 // H5沿
// H544px // H544px

View File

@ -26,7 +26,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-input-number', name: 'wd-input-number',
behaviors: ['uni://form-field'],
options: { options: {
virtualHost: true, virtualHost: true,
addGlobalClass: true, addGlobalClass: true,

View File

@ -127,7 +127,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-input', name: 'wd-input',
behaviors: ['uni://form-field'],
options: { options: {
virtualHost: true, virtualHost: true,
addGlobalClass: true, addGlobalClass: true,

View File

@ -21,6 +21,11 @@
} }
} }
:deep(.wd-message-box){
border-radius: $-message-box-radius;
overflow: hidden;
}
@include bdeep(message-box) { @include bdeep(message-box) {
border-radius: $-message-box-radius; border-radius: $-message-box-radius;
overflow: hidden; overflow: hidden;

View File

@ -1,49 +1,51 @@
<template> <template>
<wd-popup <view>
transition="zoom-in" <wd-popup
v-model="show" transition="zoom-in"
:close-on-click-modal="closeOnClickModal" v-model="show"
:lazy-render="lazyRender" :close-on-click-modal="closeOnClickModal"
custom-class="wd-message-box" :lazy-render="lazyRender"
@clickmodal="toggleModal('modal')" custom-class="wd-message-box"
:z-index="zIndex" @clickmodal="toggleModal('modal')"
:duration="200" :z-index="zIndex"
> :duration="200"
<view :class="rootClass"> >
<!--内容部分--> <view :class="rootClass">
<view :class="bodyClass"> <!--内容部分-->
<!--公共title--> <view :class="bodyClass">
<view v-if="title" class="wd-message-box__title"> <!--公共title-->
{{ title }} <view v-if="title" class="wd-message-box__title">
{{ title }}
</view>
<!--其它类型-->
<view class="wd-message-box__content">
<!--prompt类型-->
<block v-if="type === 'prompt'">
<!--输入框-->
<wd-input v-model="inputValue" :type="inputType" size="large" :placeholder="inputPlaceholder || '请输入'" @input="inputValChange" />
<!--错误提示-->
<view v-if="showErr" class="wd-message-box__input-error">
{{ inputError || '输入的数据不合法' }}
</view>
</block>
<!--使用插槽-->
<slot v-if="useSlot"></slot>
<!--使用文本-->
<block v-else>{{ msg }}</block>
</view>
</view> </view>
<!--其它类型--> <!--action按钮组合-->
<view class="wd-message-box__content"> <view :class="`wd-message-box__actions ${showCancelButton ? 'wd-message-box__flex' : 'wd-message-box__block'}`">
<!--prompt类型--> <wd-button type="info" block v-if="showCancelButton" custom-style="margin-right: 16px;" @click="toggleModal('cancel')">
<block v-if="type === 'prompt'"> {{ cancelButtonText || '取消' }}
<!--输入框--> </wd-button>
<wd-input v-model="inputValue" :type="inputType" size="large" :placeholder="inputPlaceholder || '请输入'" @input="inputValChange" /> <wd-button block @click="toggleModal('confirm')">
<!--错误提示--> {{ confirmButtonText || '确定' }}
<view v-if="showErr" class="wd-message-box__input-error"> </wd-button>
{{ inputError || '输入的数据不合法' }}
</view>
</block>
<!--使用插槽-->
<slot v-if="useSlot"></slot>
<!--使用文本-->
<block v-else>{{ msg }}</block>
</view> </view>
</view> </view>
<!--action按钮组合--> </wd-popup>
<view :class="`wd-message-box__actions ${showCancelButton ? 'wd-message-box__flex' : 'wd-message-box__block'}`"> </view>
<wd-button type="info" block v-if="showCancelButton" custom-style="margin-right: 16px;" @click="toggleModal('cancel')">
{{ cancelButtonText || '取消' }}
</wd-button>
<wd-button block @click="toggleModal('confirm')">
{{ confirmButtonText || '确定' }}
</wd-button>
</view>
</view>
</wd-popup>
</template> </template>
<script lang="ts"> <script lang="ts">
export default { export default {

View File

@ -0,0 +1,81 @@
/*
* @Author: weisheng
* @Date: 2023-08-21 13:03:42
* @LastEditTime: 2023-08-21 17:24:57
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-picker-view\type.ts
*
*/
import { getType } from '../common/util'
export type ColumnItem = {
value?: string | number | boolean
label?: string
disabled?: boolean
}
/**
* @description props的value为array类型时提供format
* @param {Array<String|Number|Object>} array
* @param {string} valueKey valueKey
* @param {string} labelKey labelKey
*/
export function formatArray(array: Array<string | number | ColumnItem | Array<string | number | ColumnItem>>, valueKey: string, labelKey: string) {
let tempArray: Array<string | number | ColumnItem | Array<string | number | ColumnItem>> = array instanceof Array ? array : [array]
// 检测第一层的type
const firstLevelTypeList = new Set(array.map(getType))
/**
*
* 1.
* 2.object
* 3.
*/
if (firstLevelTypeList.size !== 1 && firstLevelTypeList.has('object')) {
// 原始值和引用类型不用混用
throw Error('The columns are correct')
}
/**
* array
* 便
*/
if (!(array[0] instanceof Array)) {
tempArray = [tempArray as Array<string | number | ColumnItem>]
}
// 经过上述处理都已经变成了二维数组再把每一项二维元素包装成object
const result: Array<Array<ColumnItem>> = (tempArray as Array<Array<string | number | ColumnItem>>).map((col) => {
return col.map((row) => {
const isObj = getType(row)
/* 针对原始值,包装成{valueKey,labelKey} */
if (isObj !== 'object') {
return {
[valueKey]: row,
[labelKey]: row
}
}
/**
* object的{valueKey,labelKey}
* labelKeyvalueKey代替
* valueKeylabelKey代替
* valueKey,labelKey都没有
*/
// eslint-disable-next-line no-prototype-builtins
if (!row.hasOwnProperty(valueKey) && !row.hasOwnProperty(labelKey)) {
// eslint-disable-next-line prettier/prettier
throw Error('Can\'t find valueKey and labelKey in columns')
}
// eslint-disable-next-line no-prototype-builtins
if (!row.hasOwnProperty(labelKey)) {
row[labelKey] = row[valueKey]
}
// eslint-disable-next-line no-prototype-builtins
if (!row.hasOwnProperty(valueKey)) {
row[valueKey] = row[labelKey]
}
return row as ColumnItem
})
})
return result
}

View File

@ -5,7 +5,6 @@
</view> </view>
<view :style="`height: ${columnsHeight - 20}px;`"> <view :style="`height: ${columnsHeight - 20}px;`">
<picker-view <picker-view
v-if="showPicker"
mask-class="wd-picker-view__mask" mask-class="wd-picker-view__mask"
indicator-class="wd-picker-view__roller" indicator-class="wd-picker-view__roller"
:indicator-style="`height: ${itemHeight}px;`" :indicator-style="`height: ${itemHeight}px;`"
@ -45,17 +44,10 @@ export default {
<script lang="ts" setup> <script lang="ts" setup>
import { getCurrentInstance, ref, watch, nextTick } from 'vue' import { getCurrentInstance, ref, watch, nextTick } from 'vue'
import { deepClone, getType, isEqual, range } from '../common/util' import { deepClone, getType, isEqual, range } from '../common/util'
import { ColumnItem, formatArray } from './type'
type ColumnItem = {
value?: string | number | boolean
label: string
disabled?: boolean
}
interface Props { interface Props {
customClass?: string customClass?: string
// picker
showPicker: boolean
// //
loading: boolean loading: boolean
loadingColor: string loadingColor: string
@ -68,7 +60,7 @@ interface Props {
// //
modelValue: string | number | boolean | Array<string | number | boolean> modelValue: string | number | boolean | Array<string | number | boolean>
// //
columns: Array<string | string[] | ColumnItem> columns: Array<string | number | ColumnItem | Array<string | number | ColumnItem>>
// //
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
columnChange?: Function columnChange?: Function
@ -77,7 +69,6 @@ interface Props {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
customClass: '', customClass: '',
loading: false, loading: false,
showPicker: true,
loadingColor: '#4D80F0', loadingColor: '#4D80F0',
columnsHeight: 217, columnsHeight: 217,
valueKey: 'value', valueKey: 'value',
@ -86,7 +77,7 @@ const props = withDefaults(defineProps<Props>(), {
}) })
// render // render
const formatColumns = ref<Array<Record<string, any>[]>>([]) const formatColumns = ref<Array<Array<Record<string, any>>>>([])
const itemHeight = ref<number>(35) const itemHeight = ref<number>(35)
const selectedIndex = ref<Array<number>>([]) // const selectedIndex = ref<Array<number>>([]) //
const preSelectedIndex = ref<Array<number>>([]) const preSelectedIndex = ref<Array<number>>([])
@ -108,7 +99,7 @@ watch(
() => props.columns, () => props.columns,
(newValue) => { (newValue) => {
// propsformatColumnsvalueobserver // propsformatColumnsvalueobserver
formatColumns.value = formatArray(newValue) formatColumns.value = formatArray(newValue, props.valueKey, props.labelKey)
/** /**
* 每次改变都要重置选中项 * 每次改变都要重置选中项
* 1.选中每列的第一个 * 1.选中每列的第一个
@ -172,7 +163,7 @@ function selectWithValue(value) {
if (type.indexOf(valueType) === -1) throw Error(`value must be one of ${type.toString()}`) if (type.indexOf(valueType) === -1) throw Error(`value must be one of ${type.toString()}`)
// propsformatColumns/ISSUE.md // propsformatColumns/ISSUE.md
if (formatColumns.value.length === 0) { if (formatColumns.value.length === 0) {
formatColumns.value = formatArray(props.columns) formatColumns.value = formatArray(props.columns, props.valueKey, props.labelKey)
} }
/** /**
* 1.单key转为Array<key> * 1.单key转为Array<key>
@ -234,67 +225,6 @@ function selectWithIndex(columnIndex, rowIndex) {
return selectedIndex.value return selectedIndex.value
} }
/**
* @description 为props的value为array类型时提供format
* @param {Array<String|Number|Boolean|Object>} array
*/
function formatArray(array) {
array = array instanceof Array ? array : [array]
// type
const firstLevelTypeList = new Set(array.map(getType))
/**
* 存在三种类型的合法数据
* 1.数组是一维元素所有元素都是原始值
* 2.数组是一维元素所有元素都是object
* 3.数组是二维元素二维元素可以是任意内容
*/
if (firstLevelTypeList.size !== 1 && firstLevelTypeList.has('object')) {
//
throw Error('The columns are correct')
}
/**
* 数组的所有一维子元素都不是array说明是它是一个一维数组
* 所以需要把一维的转成二维这样方便统一处理
*/
if (!(array[0] instanceof Array)) {
array = [array]
}
// object
return array.map((col) =>
col.map((row) => {
const isObj = getType(row)
const { valueKey, labelKey } = props
/* 针对原始值,包装成{valueKey,labelKey} */
if (isObj !== 'object') {
return {
[valueKey]: row,
[labelKey]: row
}
}
/**
* 针对已经是object的修补成{valueKey,labelKey}
* 如果没有labelKey用valueKey代替
* 如果没有valueKey用labelKey代替
* valueKey,labelKey都没有直接抛错
*/
// eslint-disable-next-line no-prototype-builtins
if (!row.hasOwnProperty(valueKey) && !row.hasOwnProperty(labelKey)) {
// eslint-disable-next-line prettier/prettier
throw Error('Can\'t find valueKey and labelKey in columns')
}
// eslint-disable-next-line no-prototype-builtins
if (!row.hasOwnProperty(labelKey)) {
row[labelKey] = row[valueKey]
}
// eslint-disable-next-line no-prototype-builtins
if (!row.hasOwnProperty(valueKey)) {
row[valueKey] = row[labelKey]
}
return row
})
)
}
/** /**
* @description 滚动选中时更新选中的索引触发change事件 * @description 滚动选中时更新选中的索引触发change事件
* @return {Number|Array<Number>}选中项的下标或者集合 * @return {Number|Array<Number>}选中项的下标或者集合
@ -389,7 +319,6 @@ function getSelects() {
if (selects.length === 1) { if (selects.length === 1) {
return selects[0] return selects[0]
} }
return selects return selects
} }
@ -449,7 +378,7 @@ function setColumnData(columnIndex, data, jumpTo = 0) {
selectedIndex.value = selectWithIndex(columnIndex, jumpTo) selectedIndex.value = selectWithIndex(columnIndex, jumpTo)
// formatArray // formatArray
// ps v2.9.3flat // ps v2.9.3flat
formatColumns.value[columnIndex] = formatArray(data).reduce((acc, val) => acc.concat(val), []) formatColumns.value[columnIndex] = formatArray(data, props.valueKey, props.labelKey).reduce((acc, val) => acc.concat(val), [])
} }
function getColumnsData() { function getColumnsData() {

View File

@ -69,7 +69,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-picker', name: 'wd-picker',
behaviors: ['uni://form-field'],
options: { options: {
virtualHost: true, virtualHost: true,
addGlobalClass: true, addGlobalClass: true,
@ -80,8 +79,9 @@ export default {
<script lang="ts" setup> <script lang="ts" setup>
import { getCurrentInstance, onBeforeMount, ref, watch, computed, onMounted } from 'vue' import { getCurrentInstance, onBeforeMount, ref, watch, computed, onMounted } from 'vue'
import { deepClone, defaultDisplayFormat, getType } from '../common/util' import { deepClone, defaultDisplayFormat, getType, isArray } from '../common/util'
import { useCell } from '../mixins/useCell' import { useCell } from '../mixins/useCell'
import { ColumnItem, formatArray } from '../wd-picker-view/type'
interface Props { interface Props {
customClass?: string customClass?: string
@ -126,9 +126,9 @@ interface Props {
// key // key
labelKey: string labelKey: string
// //
modelValue: string | number | boolean | Array<string | number | boolean> modelValue: string | number | Array<string | number>
// //
columns: Array<string | string[]> columns: Array<string | number | ColumnItem | Array<string | number | ColumnItem>>
// //
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
columnChange?: Function columnChange?: Function
@ -182,8 +182,8 @@ const popupShow = ref<boolean>(false)
// //
const showValue = ref<string>('') const showValue = ref<string>('')
const pickerValue = ref<string | number | boolean | (string | number | boolean)[]>('') const pickerValue = ref<string | number | boolean | (string | number | boolean)[]>('')
const displayColumns = ref<Array<string | string[]>>([]) // pickerView columns const displayColumns = ref<Array<string | number | ColumnItem | Array<string | number | ColumnItem>>>([]) // pickerView columns
const resetColumns = ref<Array<string | string[]>>([]) // columns const resetColumns = ref<Array<string | number | ColumnItem | Array<string | number | ColumnItem>>>([]) // columns
const isPicking = ref<boolean>(false) // pickview const isPicking = ref<boolean>(false) // pickview
const hasConfirmed = ref<boolean>(false) // const hasConfirmed = ref<boolean>(false) //
@ -264,6 +264,7 @@ const { proxy } = getCurrentInstance() as any
const emit = defineEmits(['confirm', 'open', 'cancel', 'update:modelValue']) const emit = defineEmits(['confirm', 'open', 'cancel', 'update:modelValue'])
onMounted(() => { onMounted(() => {
props.modelValue && setShowValue(getSelects(props.modelValue))
if (props.modelValue && pickerViewWd.value && pickerViewWd.value.getSelects) { if (props.modelValue && pickerViewWd.value && pickerViewWd.value.getSelects) {
setShowValue(pickerViewWd.value!.getSelects()) setShowValue(pickerViewWd.value!.getSelects())
} }
@ -274,6 +275,51 @@ onBeforeMount(() => {
resetColumns.value = deepClone(props.columns) resetColumns.value = deepClone(props.columns)
}) })
/**
* @description 根据传入的valuepicker组件获取当前cell展示值
* @param {String|Number|Array<String|Number|Array<any>>}value
*/
function getSelects(value) {
const formatColumns = formatArray(props.columns, props.valueKey, props.labelKey)
if (props.columns.length === 0) return
// 使
if (value === '' || value === null || value === undefined || (getType(value) === 'array' && value.length === 0)) {
value = formatColumns.map((col) => {
return col[0][props.valueKey]
})
}
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 = value instanceof Array ? 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() { function open() {
showPopup() showPopup()

View File

@ -38,16 +38,18 @@ interface Props {
modal: boolean modal: boolean
zIndex: number zIndex: number
hideWhenClose: boolean hideWhenClose: boolean
modalStyle?: string modalStyle: string
safeAreaInsetBottom: boolean safeAreaInsetBottom: boolean
modelValue: boolean modelValue: boolean
customStyle?: string customStyle: string
lazyRender: boolean lazyRender: boolean
customClass?: string customClass: string
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
customClass: '', customClass: '',
customStyle: '',
modalStyle: '',
position: 'center', position: 'center',
closeOnClickModal: true, closeOnClickModal: true,
modal: true, modal: true,

View File

@ -6,7 +6,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-radio-group', name: 'wd-radio-group',
behaviors: ['uni://form-field'],
options: { options: {
virtualHost: true, virtualHost: true,
addGlobalClass: true, addGlobalClass: true,

View File

@ -21,7 +21,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-rate', name: 'wd-rate',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,

View File

@ -94,6 +94,13 @@ onMounted(() => {
width.value = lastWidth width.value = lastWidth
// //
onScrollHandler = () => { onScrollHandler = () => {
const query = uni
.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(proxy)
// #endif
.select('.wd-resize__container')
.boundingClientRect()
query.exec(([res]) => { query.exec(([res]) => {
// created // created
if (scrollEventCount.value++ === 0) { if (scrollEventCount.value++ === 0) {

View File

@ -50,7 +50,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-search', name: 'wd-search',
behaviors: ['uni://form-field'],
options: { options: {
virtualHost: true, virtualHost: true,
addGlobalClass: true, addGlobalClass: true,

View File

@ -88,7 +88,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-select-picker', name: 'wd-select-picker',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,

View File

@ -44,7 +44,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-slider', name: 'wd-slider',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,

View File

@ -67,7 +67,9 @@
line-height: 1.1; line-height: 1.1;
@include when(active) { @include when(active) {
:deep(.wd-sort-button__icon-up, .wd-sort-button__icon-down) {
:deep(.wd-sort-button__icon-up),
:deep(.wd-sort-button__icon-down) {
transform: scale(calc((10 / 14))); transform: scale(calc((10 / 14)));
} }
} }

View File

@ -3,9 +3,9 @@
<view <view
:class="`wd-swipe-action ${customClass}`" :class="`wd-swipe-action ${customClass}`"
@click.stop="onClick()" @click.stop="onClick()"
@touchstart="startDrag"
@touchmove="stopPropagation ? nothing : ''" @touchmove="stopPropagation ? nothing : ''"
@touchmove.capture="onDrag" @touchstart="startDrag"
@touchmove.prevent="onDrag"
@touchend="endDrag" @touchend="endDrag"
@touchcancel="endDrag" @touchcancel="endDrag"
> >
@ -43,7 +43,7 @@ import { getRect } from '../common/util'
interface Props { interface Props {
customClass?: string customClass?: string
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
beforeClose: Function beforeClose?: Function
disabled: boolean disabled: boolean
modelValue: string modelValue: string
} }
@ -51,8 +51,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
customStyle: '', customStyle: '',
modelValue: 'close', modelValue: 'close',
disabled: false, disabled: false
beforeClose: (v) => v
}) })
const wrapperStyle = ref<string>('') const wrapperStyle = ref<string>('')
@ -280,7 +279,7 @@ function close(reason, position?: string) {
} }
if (reason && position) { if (reason && position) {
props.beforeClose(reason, position) props.beforeClose && props.beforeClose(reason, position)
} }
swipeMove(0) swipeMove(0)

View File

@ -6,7 +6,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-switch', name: 'wd-switch',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,

View File

@ -42,7 +42,6 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'wd-upload', name: 'wd-upload',
behaviors: ['uni://form-field'],
options: { options: {
addGlobalClass: true, addGlobalClass: true,
virtualHost: true, virtualHost: true,

1909
yarn.lock

File diff suppressed because it is too large Load Diff