first commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### DateTimePicker Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
auto-close | Boolean | false | \- | N
|
||||
cancel-btn | String | 取消 | \- | N
|
||||
confirm-btn | String | - | \- | N
|
||||
custom-locale | String | zh | \- | N
|
||||
end | String / Number | - | \- | N
|
||||
filter | Function | - | Typescript:`(type: TimeModeValues, columns: DateTimePickerColumn) => DateTimePickerColumn` `type DateTimePickerColumn = DateTimePickerColumnItem[]` `interface DateTimePickerColumnItem { label: string,value: string}`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
format | String | 'YYYY-MM-DD HH:mm:ss' | \- | N
|
||||
formatter | Function | - | Typescript:`(option: DateTimePickerColumnItem, columnIndex: number) => DateTimePickerColumnItem` | N
|
||||
header | Boolean | true | \- | N
|
||||
mode | String / Array | 'date' | Typescript:`DateTimePickerMode` `type DateTimePickerMode = TimeModeValues \| Array<TimeModeValues> ` `type TimeModeValues = 'year' \| 'month' \| 'date' \| 'hour' \| 'minute' \| 'second' \| 'null'`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
popup-props | Object | {} | popup properties。Typescript:`PopupProps`,[Popup API Documents](./popup?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
show-week | Boolean | false | \- | N
|
||||
start | String / Number | - | \- | N
|
||||
steps | Object | {} | Typescript:`{ [key in TimeModeValues]?: number }` | N
|
||||
title | String | - | title of picker | N
|
||||
use-popup | Boolean | true | \- | N
|
||||
value | String / Number | - | `v-model:value` is supported。Typescript:`DateValue` `type DateValue = string \| number`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
default-value | String / Number | - | uncontrolled property。Typescript:`DateValue` `type DateValue = string \| number`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
visible | Boolean | false | \- | N
|
||||
|
||||
### DateTimePicker Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
cancel | \- | \-
|
||||
change | `(context: { value: DateValue })` | \-
|
||||
close | `(context: { trigger: DateTimePickerTriggerSource })` | [see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts)。<br/>`type DateTimePickerTriggerSource = 'overlay' \| 'cancel-btn' \| 'confirm-btn'`<br/>
|
||||
confirm | `(context: { value: DateValue })` | \-
|
||||
pick | `(context: { value: DateValue })` | \-
|
||||
|
||||
### DateTimePicker Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
footer | \-
|
||||
header | \-
|
||||
|
||||
### DateTimePicker External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-cancel | \-
|
||||
t-class-confirm | \-
|
||||
t-class-title | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-data-time-picker-year-width | 128rpx | -
|
||||
105
uni_modules/tdesign-uniapp/components/date-time-picker/README.md
Normal file
105
uni_modules/tdesign-uniapp/components/date-time-picker/README.md
Normal file
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: DateTimePicker 时间选择器
|
||||
description: 用于选择一个时间点或者一个时间段。
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TDateTimePicker from '@tdesign/uniapp/date-time-picker/date-time-picker.vue';
|
||||
```
|
||||
|
||||
### 组件类型
|
||||
|
||||
#### 年月日选择器
|
||||
|
||||
{{ year-month-date }}
|
||||
|
||||
#### 年月选择器
|
||||
|
||||
{{ year-month }}
|
||||
|
||||
### 时间选择器
|
||||
|
||||
包括:`时分秒`、`时分`两个示例
|
||||
|
||||
{{ time }}
|
||||
|
||||
#### 年月日时分秒选择器
|
||||
|
||||
{{ date-all }}
|
||||
|
||||
### 组件用法
|
||||
|
||||
#### 调整步数
|
||||
|
||||
{{ steps }}
|
||||
|
||||
#### 不使用 Popup
|
||||
|
||||
{{ without-popup }}
|
||||
|
||||
## API
|
||||
|
||||
### DateTimePicker Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
auto-close | Boolean | false | 自动关闭;在确认、取消、点击遮罩层自动关闭,不需要手动设置 visible | N
|
||||
cancel-btn | String | 取消 | 取消按钮文字 | N
|
||||
confirm-btn | String | - | 确定按钮文字 | N
|
||||
custom-locale | String | zh | 组件国际化语言,目前支持: 简体中文(zh)、(tc)、英文(en)、日语(ja)、韩语(ko)、俄语(ru)等六种语言 | N
|
||||
end | String / Number | - | 选择器的最大可选时间,默认为当前时间+10年 | N
|
||||
filter | Function | - | 列选项过滤函数,支持自定义列内容。(type 值可为: year, month, date, hour, minute, second)。TS 类型:`(type: TimeModeValues, columns: DateTimePickerColumn) => DateTimePickerColumn` `type DateTimePickerColumn = DateTimePickerColumnItem[]` `interface DateTimePickerColumnItem { label: string,value: string}`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
format | String | 'YYYY-MM-DD HH:mm:ss' | 用于格式化 pick、change、confirm 事件返回的值,[详细文档](https://day.js.org/docs/en/display/format) | N
|
||||
formatter | Function | - | 格式化标签。TS 类型:`(option: DateTimePickerColumnItem, columnIndex: number) => DateTimePickerColumnItem` | N
|
||||
header | Boolean | true | 头部内容。值为 true 显示空白头部,值为 false 不显示任何内容 | N
|
||||
mode | String / Array | 'date' | year = 年;month = 年月;date = 年月日;hour = 年月日时; minute = 年月日时分;当类型为数组时,第一个值控制年月日,第二个值控制时分秒。TS 类型:`DateTimePickerMode` `type DateTimePickerMode = TimeModeValues \| Array<TimeModeValues> ` `type TimeModeValues = 'year' \| 'month' \| 'date' \| 'hour' \| 'minute' \| 'second' \| 'null'`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
popup-props | Object | {} | 透传 Popup 组件全部属性。TS 类型:`PopupProps`,[Popup API Documents](./popup?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
show-week | Boolean | false | 是否在日期旁边显示周几(如周一,周二,周日等) | N
|
||||
start | String / Number | - | 选择器的最小可选时间,默认为当前时间-10年 | N
|
||||
steps | Object | {} | 时间间隔步数,示例:`{ minute: 5 }`。TS 类型:`{ [key in TimeModeValues]?: number }` | N
|
||||
title | String | - | 标题 | N
|
||||
use-popup | Boolean | true | 是否使用弹出层包裹 | N
|
||||
value | String / Number | - | 选中值。支持语法糖 `v-model:value`。TS 类型:`DateValue` `type DateValue = string \| number`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
default-value | String / Number | - | 选中值。非受控属性。TS 类型:`DateValue` `type DateValue = string \| number`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts) | N
|
||||
visible | Boolean | false | 是否显示 | N
|
||||
|
||||
### DateTimePicker Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
cancel | \- | 取消按钮点击时触发
|
||||
change | `(context: { value: DateValue })` | 确认按钮点击时触发
|
||||
close | `(context: { trigger: DateTimePickerTriggerSource })` | 关闭时触发。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/date-time-picker/type.ts)。<br/>`type DateTimePickerTriggerSource = 'overlay' \| 'cancel-btn' \| 'confirm-btn'`<br/>
|
||||
confirm | `(context: { value: DateValue })` | 确认按钮点击时触发
|
||||
pick | `(context: { value: DateValue })` | 选中值发生变化时触发
|
||||
|
||||
### DateTimePicker Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
footer | 底部内容
|
||||
header | 自定义 `header` 显示内容
|
||||
|
||||
### DateTimePicker External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-cancel | 取消样式类
|
||||
t-class-confirm | 确认样式类
|
||||
t-class-title | 标题样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-data-time-picker-year-width | 128rpx | -
|
||||
@@ -0,0 +1,4 @@
|
||||
.t-date-time-picker__item--roomly {
|
||||
width: var(--td-data-time-picker-year-width, 128rpx);
|
||||
flex: 0 0 var(--td-data-time-picker-year-width, 128rpx);
|
||||
}
|
||||
@@ -0,0 +1,570 @@
|
||||
<template>
|
||||
<view>
|
||||
<t-picker
|
||||
:custom-style="tools._style([customStyle])"
|
||||
:class="tClass + ' ' + classPrefix"
|
||||
:visible="visible"
|
||||
:value="columnsValue"
|
||||
:header="header"
|
||||
:title="title"
|
||||
:auto-close="autoClose"
|
||||
:confirm-btn="confirmBtn || locale.confirm"
|
||||
:cancel-btn="cancelBtn || locale.cancel"
|
||||
:use-popup="usePopup"
|
||||
:popup-props="popupProps"
|
||||
@pick="onColumnChange"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
@visible-change="onVisibleChange"
|
||||
@close="onClose"
|
||||
>
|
||||
<template
|
||||
#header
|
||||
>
|
||||
<slot
|
||||
name="header"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<t-picker-item
|
||||
v-for="(item, index) in columns"
|
||||
:key="index"
|
||||
:class="tools.cls(classPrefix + '__item', [['roomly', columns.length >= 5 && index == 0]])"
|
||||
:use-slots="false"
|
||||
:options="item"
|
||||
index="index"
|
||||
:format="formatter"
|
||||
/>
|
||||
<template
|
||||
#footer
|
||||
>
|
||||
<slot
|
||||
name="footer"
|
||||
/>
|
||||
</template>
|
||||
</t-picker>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TPicker from '../picker/picker';
|
||||
import TPickerItem from '../picker-item/picker-item';
|
||||
import { prefix } from '../common/config';
|
||||
import { coalesce } from '../common/utils';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import props from './props';
|
||||
import dayjsLocaleMap from './locale/dayjs';
|
||||
import tools from '../common/utils.wxs';
|
||||
import dayjs from '../npm/dayjs/esm/index.js';
|
||||
import localeData from '../npm/dayjs/esm/plugin/localeData';
|
||||
|
||||
/**
|
||||
* dayjs LocaleData 插件
|
||||
* https://dayjs.fenxianglu.cn/category/plugin.html#localedata
|
||||
*/
|
||||
dayjs.extend(localeData);
|
||||
dayjs.locale('zh-cn');
|
||||
|
||||
const defaultLocale = dayjsLocaleMap[dayjs.locale()]?.key || dayjsLocaleMap.default?.key;
|
||||
|
||||
|
||||
const name = `${prefix}-date-time-picker`;
|
||||
|
||||
const ModeItem = {
|
||||
YEAR: 'year',
|
||||
MONTH: 'month',
|
||||
DATE: 'date',
|
||||
HOUR: 'hour',
|
||||
MINUTE: 'minute',
|
||||
SECOND: 'second',
|
||||
};
|
||||
|
||||
const DATE_MODES = ['year', 'month', 'date'];
|
||||
const TIME_MODES = ['hour', 'minute', 'second'];
|
||||
const FULL_MODES = [...DATE_MODES, ...TIME_MODES];
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [
|
||||
{
|
||||
key: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-confirm`,
|
||||
`${prefix}-class-cancel`,
|
||||
`${prefix}-class-title`,
|
||||
],
|
||||
components: {
|
||||
TPicker,
|
||||
TPickerItem,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'update:visible',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
columns: [],
|
||||
columnsValue: [],
|
||||
fullModes: [],
|
||||
locale: dayjsLocaleMap[defaultLocale].i18n, // 国际化语言包
|
||||
dayjsLocale: dayjsLocaleMap[defaultLocale].key, // dayjs 自适应的 key
|
||||
tools,
|
||||
|
||||
dataValue: coalesce(this.value, this.defaultValue),
|
||||
|
||||
date: null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(v) {
|
||||
this.dataValue = v;
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
|
||||
start: 'updateColumns',
|
||||
end: 'updateColumns',
|
||||
dataValue: 'updateColumns',
|
||||
|
||||
customLocale: {
|
||||
handler(v) {
|
||||
if (!v || !dayjsLocaleMap[v].key) return;
|
||||
this.locale = dayjsLocaleMap[v].i18n;
|
||||
this.dayjsLocale = dayjsLocaleMap[v].key;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
mode: {
|
||||
handler(v, prev) {
|
||||
// 解决 pick 事件触发两次问题
|
||||
const checkEqual = () => {
|
||||
if (!prev) return false;
|
||||
let result = false;
|
||||
try {
|
||||
result = JSON.stringify(v) === JSON.stringify(prev);
|
||||
} catch (e) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
if (checkEqual()) return;
|
||||
|
||||
const fullModes = this.getFullModeArray(v);
|
||||
this.fullModes = fullModes;
|
||||
this.updateColumns();
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// created 时机并不准,uniapp 自己 mock 的
|
||||
// this.date = null;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
updateColumns() {
|
||||
this.date = this.getParseDate();
|
||||
|
||||
const { columns, columnsValue } = this.getValueCols();
|
||||
this.columns = columns,
|
||||
this.columnsValue = columnsValue;
|
||||
},
|
||||
|
||||
getDaysOfWeekInMonth(date, type) {
|
||||
const { locale, steps, dayjsLocale } = this;
|
||||
const startOfMonth = date.startOf('month');
|
||||
const minEdge = this.getOptionEdge('min', type);
|
||||
const maxEdge = this.getOptionEdge('max', type);
|
||||
const step = coalesce(steps?.[type], 1);
|
||||
const daysOfWeek = [];
|
||||
|
||||
for (let i = minEdge; i <= maxEdge; i += step) {
|
||||
const currentDate = startOfMonth.date(i).locale(dayjsLocale);
|
||||
const dayName = currentDate.format('ddd');
|
||||
daysOfWeek.push({
|
||||
value: `${i}`,
|
||||
label: `${i}${locale.date || ''} ${dayName}`,
|
||||
});
|
||||
}
|
||||
|
||||
return daysOfWeek;
|
||||
},
|
||||
|
||||
getParseDate() {
|
||||
const { dataValue } = this;
|
||||
const minDate = this.getMinDate();
|
||||
|
||||
const isTimeMode = this.isTimeMode();
|
||||
let currentValue = dataValue;
|
||||
|
||||
// 时间需要补齐前缀
|
||||
if (isTimeMode) {
|
||||
const dateStr = dayjs(minDate).format('YYYY-MM-DD');
|
||||
currentValue = dayjs(`${dateStr} ${currentValue}`);
|
||||
}
|
||||
|
||||
const parseDate = dayjs(currentValue || minDate);
|
||||
const isDateValid = parseDate.isValid();
|
||||
|
||||
return isDateValid ? parseDate : minDate;
|
||||
},
|
||||
|
||||
normalize(val, defaultDay) {
|
||||
return val && dayjs(val).isValid() ? dayjs(val) : defaultDay;
|
||||
},
|
||||
|
||||
getMinDate() {
|
||||
return this.normalize(this.start, dayjs().subtract(10, 'year'));
|
||||
},
|
||||
|
||||
getMaxDate() {
|
||||
return this.normalize(this.end, dayjs().add(10, 'year'));
|
||||
},
|
||||
|
||||
getDateRect(type = 'default') {
|
||||
const map = {
|
||||
min: 'getMinDate',
|
||||
max: 'getMaxDate',
|
||||
default: 'getDate',
|
||||
};
|
||||
const date = this[map[type]]();
|
||||
const keys = ['year', 'month', 'date', 'hour', 'minute', 'second'];
|
||||
|
||||
return keys.map(k => date[k]?.());
|
||||
},
|
||||
|
||||
getDate() {
|
||||
return this.clipDate(this?.date || this.getMinDate());
|
||||
},
|
||||
|
||||
// 数据裁减 确保数据不越界
|
||||
clipDate(date) {
|
||||
const minDate = this.getMinDate();
|
||||
const maxDate = this.getMaxDate();
|
||||
return dayjs(Math.min(Math.max(minDate.valueOf(), date.valueOf()), maxDate.valueOf()));
|
||||
},
|
||||
|
||||
// 年变化时 需要修正 日数据 例如 2 月的 28 | 29
|
||||
setYear(date, year) {
|
||||
const beforeMonthDays = date.date();
|
||||
const afterMonthDays = date.year(year).daysInMonth();
|
||||
|
||||
const tempDate = date.date(Math.min(beforeMonthDays.valueOf(), afterMonthDays.valueOf()));
|
||||
return tempDate.year(year);
|
||||
},
|
||||
|
||||
// 月变化时 需要修正 日数据边界
|
||||
setMonth(date, month) {
|
||||
const beforeMonthDays = date.date();
|
||||
const afterMonthDays = date.month(month).daysInMonth();
|
||||
|
||||
const tempDate = date.date(Math.min(beforeMonthDays.valueOf(), afterMonthDays.valueOf()));
|
||||
return tempDate.month(month);
|
||||
},
|
||||
|
||||
getColumnOptions() {
|
||||
const { fullModes, filter } = this;
|
||||
|
||||
const columnOptions = [];
|
||||
fullModes?.forEach((mode) => {
|
||||
const columnOption = this.getOptionByType(mode);
|
||||
if (typeof filter === 'function') {
|
||||
columnOptions.push(filter(mode, columnOption));
|
||||
} else {
|
||||
columnOptions.push(columnOption);
|
||||
}
|
||||
});
|
||||
return columnOptions;
|
||||
},
|
||||
|
||||
getOptionByType(type) {
|
||||
const { locale, steps, showWeek } = this;
|
||||
const options = [];
|
||||
|
||||
const minEdge = this.getOptionEdge('min', type);
|
||||
const maxEdge = this.getOptionEdge('max', type);
|
||||
const step = coalesce(steps?.[type], 1);
|
||||
const dayjsMonthsShort = dayjs().locale(this.dayjsLocale)
|
||||
.localeData()
|
||||
.monthsShort();
|
||||
|
||||
if (type === 'date' && showWeek) {
|
||||
return this.getDaysOfWeekInMonth(this.date, type);
|
||||
}
|
||||
|
||||
for (let i = minEdge; i <= maxEdge; i += step) {
|
||||
options.push({
|
||||
value: `${i}`,
|
||||
label: type === 'month' ? dayjsMonthsShort[i] : `${i + locale[type]}`,
|
||||
});
|
||||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
|
||||
getYearOptions(dateParams) {
|
||||
const { locale } = this;
|
||||
const { minDateYear, maxDateYear } = dateParams;
|
||||
|
||||
const years = [];
|
||||
for (let i = minDateYear; i <= maxDateYear; i += 1) {
|
||||
years.push({
|
||||
value: `${i}`,
|
||||
label: `${i + locale.year}`,
|
||||
});
|
||||
}
|
||||
return years;
|
||||
},
|
||||
|
||||
getOptionEdge(minOrMax, type) {
|
||||
const selDateArray = this.getDateRect();
|
||||
const compareArray = this.getDateRect(minOrMax);
|
||||
const edge = {
|
||||
month: [0, 11],
|
||||
date: [1, this.getDate().daysInMonth()],
|
||||
hour: [0, 23],
|
||||
minute: [0, 59],
|
||||
second: [0, 59],
|
||||
};
|
||||
const types = ['year', 'month', 'date', 'hour', 'minute', 'second'];
|
||||
|
||||
for (let i = 0, size = selDateArray.length; i < size; i += 1) {
|
||||
if (types[i] === type) return compareArray[i];
|
||||
if (compareArray[i] !== selDateArray[i]) return edge[type][minOrMax === 'min' ? 0 : 1];
|
||||
}
|
||||
return edge[type][minOrMax === 'min' ? 0 : 1];
|
||||
},
|
||||
|
||||
getMonthOptions() {
|
||||
const months = [];
|
||||
|
||||
const minMonth = this.getOptionEdge('min', 'month');
|
||||
const maxMonth = this.getOptionEdge('max', 'month');
|
||||
const dayjsMonthsShort = dayjs.monthsShort();
|
||||
|
||||
for (let i = minMonth; i <= maxMonth; i += 1) {
|
||||
months.push({
|
||||
value: `${i}`,
|
||||
label: dayjsMonthsShort[i],
|
||||
});
|
||||
}
|
||||
|
||||
return months;
|
||||
},
|
||||
|
||||
getDayOptions() {
|
||||
const { locale } = this;
|
||||
const days = [];
|
||||
const minDay = this.getOptionEdge('min', 'date');
|
||||
const maxDay = this.getOptionEdge('max', 'date');
|
||||
|
||||
for (let i = minDay; i <= maxDay; i += 1) {
|
||||
days.push({
|
||||
value: `${i}`,
|
||||
label: `${i + locale.day}`,
|
||||
});
|
||||
}
|
||||
|
||||
return days;
|
||||
},
|
||||
|
||||
getHourOptions() {
|
||||
const { locale } = this;
|
||||
const hours = [];
|
||||
const minHour = this.getOptionEdge('min', 'hour');
|
||||
const maxHour = this.getOptionEdge('max', 'hour');
|
||||
|
||||
for (let i = minHour; i <= maxHour; i += 1) {
|
||||
hours.push({
|
||||
value: `${i}`,
|
||||
label: `${i + locale.hour}`,
|
||||
});
|
||||
}
|
||||
|
||||
return hours;
|
||||
},
|
||||
|
||||
getMinuteOptions() {
|
||||
const { locale } = this;
|
||||
const minutes = [];
|
||||
const minMinute = this.getOptionEdge('min', 'minute');
|
||||
const maxMinute = this.getOptionEdge('max', 'minute');
|
||||
|
||||
for (let i = minMinute; i <= maxMinute; i += 1) {
|
||||
minutes.push({
|
||||
value: `${i}`,
|
||||
label: `${i + locale.minute}`,
|
||||
});
|
||||
}
|
||||
|
||||
return minutes;
|
||||
},
|
||||
|
||||
getValueCols() {
|
||||
return {
|
||||
columns: this.getColumnOptions(),
|
||||
columnsValue: this.getColumnsValue(),
|
||||
};
|
||||
},
|
||||
|
||||
getColumnsValue() {
|
||||
const { fullModes } = this;
|
||||
const date = this.getDate();
|
||||
|
||||
const columnsValue = [];
|
||||
|
||||
fullModes?.forEach((mode) => {
|
||||
columnsValue.push(`${date[mode]()}`);
|
||||
});
|
||||
|
||||
return columnsValue;
|
||||
},
|
||||
|
||||
getNewDate(value, type) {
|
||||
let newValue = this.getDate();
|
||||
|
||||
switch (type) {
|
||||
case ModeItem.YEAR:
|
||||
newValue = this.setYear(newValue, value);
|
||||
break;
|
||||
case ModeItem.MONTH:
|
||||
newValue = this.setMonth(newValue, value);
|
||||
break;
|
||||
case ModeItem.DATE:
|
||||
newValue = newValue.date(value);
|
||||
break;
|
||||
case ModeItem.HOUR:
|
||||
newValue = newValue.hour(value);
|
||||
break;
|
||||
case ModeItem.MINUTE:
|
||||
newValue = newValue.minute(value);
|
||||
break;
|
||||
case ModeItem.SECOND:
|
||||
newValue = newValue.second(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return this.clipDate(newValue);
|
||||
},
|
||||
|
||||
onColumnChange(e) {
|
||||
const { value, column } = e;
|
||||
const { fullModes, format } = this;
|
||||
|
||||
const columnValue = value?.[column];
|
||||
const columnType = fullModes?.[column];
|
||||
|
||||
const newValue = this.getNewDate(parseInt(columnValue, 10), columnType);
|
||||
|
||||
this.date = newValue;
|
||||
|
||||
const { columns, columnsValue } = this.getValueCols();
|
||||
|
||||
this.columns = columns;
|
||||
this.columnsValue = columnsValue;
|
||||
|
||||
const date = this.getDate();
|
||||
const pickValue = format ? date.format(format) : date.valueOf();
|
||||
|
||||
this.$emit('pick', { value: pickValue });
|
||||
},
|
||||
|
||||
onConfirm() {
|
||||
const { format } = this;
|
||||
const date = this.getDate();
|
||||
|
||||
const value = format ? date.format(format) : date.valueOf();
|
||||
this._trigger('change', { value });
|
||||
this.$emit('confirm', { value });
|
||||
this.resetColumns();
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.resetColumns();
|
||||
this.$emit('cancel');
|
||||
},
|
||||
|
||||
onVisibleChange(e) {
|
||||
if (!e.visible) {
|
||||
this.resetColumns();
|
||||
}
|
||||
},
|
||||
|
||||
onClose(e) {
|
||||
const { trigger } = e;
|
||||
|
||||
this.$emit('close', { trigger });
|
||||
this.$emit('update:visible', false);
|
||||
},
|
||||
|
||||
resetColumns() {
|
||||
const parseDate = this.getParseDate();
|
||||
|
||||
this.date = parseDate;
|
||||
|
||||
const { columns, columnsValue } = this.getValueCols();
|
||||
|
||||
this.columns = columns;
|
||||
this.columnsValue = columnsValue;
|
||||
},
|
||||
|
||||
// 将简写的 mode 转化成枚举值
|
||||
getFullModeArray(mode) {
|
||||
// 简易模式
|
||||
if (typeof mode === 'string' || mode instanceof String) {
|
||||
return this.getFullModeByModeString(mode, FULL_MODES);
|
||||
}
|
||||
|
||||
// 高级模式
|
||||
if (Array.isArray(mode)) {
|
||||
if (mode?.length === 1) {
|
||||
return this.getFullModeByModeString(mode[0], FULL_MODES);
|
||||
}
|
||||
|
||||
if (mode?.length === 2) {
|
||||
const dateModes = this.getFullModeByModeString(mode[0], DATE_MODES);
|
||||
const timeModes = this.getFullModeByModeString(mode[1], TIME_MODES);
|
||||
return [...dateModes, ...timeModes];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getFullModeByModeString(modeString, matchModes) {
|
||||
if (!modeString) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const endIndex = matchModes?.findIndex(mode => modeString === mode);
|
||||
return matchModes?.slice(0, endIndex + 1);
|
||||
},
|
||||
|
||||
// 仅展示时或者时分 需要单独特殊处理
|
||||
isTimeMode() {
|
||||
const { fullModes } = this;
|
||||
return fullModes[0] === ModeItem.HOUR;
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './date-time-picker.css';
|
||||
</style>
|
||||
@@ -0,0 +1,81 @@
|
||||
// dayjs 语言包
|
||||
import * as enLocale from '../../npm/dayjs/esm/locale/en';
|
||||
import * as zhLocale from '../../npm/dayjs/esm/locale/zh-cn';
|
||||
import * as tcLocale from '../../npm/dayjs/esm/locale/zh-tw'; // 繁体
|
||||
import * as koLocale from '../../npm/dayjs/esm/locale/ko'; // 韩语
|
||||
import * as jaLocale from '../../npm/dayjs/esm/locale/ja'; // 日语
|
||||
import * as ruLocale from '../../npm/dayjs/esm/locale/ru'; // 俄语
|
||||
|
||||
// 本地语言包
|
||||
import en from './en';
|
||||
import zh from './zh';
|
||||
import tc from './tc';
|
||||
import ko from './ko';
|
||||
import ja from './ja';
|
||||
import ru from './ru';
|
||||
|
||||
export default {
|
||||
default: {
|
||||
key: 'zh-cn',
|
||||
label: '简体中文',
|
||||
locale: zhLocale,
|
||||
i18n: zh,
|
||||
},
|
||||
en: {
|
||||
key: 'en',
|
||||
label: 'English',
|
||||
locale: enLocale,
|
||||
i18n: en,
|
||||
},
|
||||
'zh-cn': {
|
||||
key: 'zh-cn',
|
||||
label: '简体中文',
|
||||
locale: zhLocale,
|
||||
i18n: zh,
|
||||
},
|
||||
// 容错处理
|
||||
zh: {
|
||||
key: 'zh-cn',
|
||||
label: '简体中文',
|
||||
locale: zhLocale,
|
||||
i18n: zh,
|
||||
},
|
||||
'zh-tw': {
|
||||
key: 'zh-tw',
|
||||
label: '繁体中文',
|
||||
locale: tcLocale,
|
||||
i18n: tc,
|
||||
},
|
||||
// 容错处理
|
||||
tc: {
|
||||
key: 'zh-tw',
|
||||
label: '繁体中文',
|
||||
locale: tcLocale,
|
||||
i18n: tc,
|
||||
},
|
||||
ko: {
|
||||
key: 'ko',
|
||||
label: '한국어',
|
||||
locale: koLocale,
|
||||
i18n: ko,
|
||||
},
|
||||
// 容错处理
|
||||
kr: {
|
||||
key: 'ko',
|
||||
label: '한국어',
|
||||
locale: koLocale,
|
||||
i18n: ko,
|
||||
},
|
||||
ja: {
|
||||
key: 'ja',
|
||||
label: '日本語',
|
||||
locale: jaLocale,
|
||||
i18n: ja,
|
||||
},
|
||||
ru: {
|
||||
key: 'ru',
|
||||
label: 'русский',
|
||||
locale: ruLocale,
|
||||
i18n: ru,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
year: '',
|
||||
month: '',
|
||||
date: '',
|
||||
hour: '',
|
||||
minute: '',
|
||||
second: '',
|
||||
am: 'AM',
|
||||
pm: 'PM',
|
||||
confirm: 'confirm',
|
||||
cancel: 'cancel',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
year: '年',
|
||||
month: '月',
|
||||
date: '日',
|
||||
hour: '時',
|
||||
minute: '分',
|
||||
second: '秒',
|
||||
am: '午前',
|
||||
pm: '午後',
|
||||
confirm: '確認',
|
||||
cancel: 'キャンセル',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
year: '년',
|
||||
month: '월',
|
||||
date: '일',
|
||||
hour: '시',
|
||||
minute: '분',
|
||||
second: '초',
|
||||
am: '오전',
|
||||
pm: '오후',
|
||||
confirm: '확인',
|
||||
cancel: '취소',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
year: '',
|
||||
month: '',
|
||||
date: '',
|
||||
hour: '',
|
||||
minute: '',
|
||||
second: '',
|
||||
am: 'до полудня',
|
||||
pm: 'после полудня',
|
||||
confirm: 'подтвердить',
|
||||
cancel: 'отменить',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
year: '年',
|
||||
month: '月',
|
||||
date: '日',
|
||||
hour: '時',
|
||||
minute: '分',
|
||||
second: '秒',
|
||||
am: '上午',
|
||||
pm: '下午',
|
||||
confirm: '確定',
|
||||
cancel: '取消',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
year: '年',
|
||||
month: '月',
|
||||
date: '日',
|
||||
hour: '时',
|
||||
minute: '分',
|
||||
second: '秒',
|
||||
am: '上午',
|
||||
pm: '下午',
|
||||
confirm: '确定',
|
||||
cancel: '取消',
|
||||
};
|
||||
114
uni_modules/tdesign-uniapp/components/date-time-picker/props.ts
Normal file
114
uni_modules/tdesign-uniapp/components/date-time-picker/props.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdDateTimePickerProps } from './type';
|
||||
export default {
|
||||
/** 自动关闭;在确认、取消、点击遮罩层自动关闭,不需要手动设置 visible */
|
||||
autoClose: Boolean,
|
||||
/** 取消按钮文字 */
|
||||
cancelBtn: {
|
||||
type: String,
|
||||
default: '取消',
|
||||
},
|
||||
/** 确定按钮文字 */
|
||||
confirmBtn: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 组件国际化语言,目前支持: 简体中文(zh)、(tc)、英文(en)、日语(ja)、韩语(ko)、俄语(ru)等六种语言 */
|
||||
customLocale: {
|
||||
type: String,
|
||||
default: 'zh',
|
||||
},
|
||||
/** 选择器的最大可选时间,默认为当前时间+10年 */
|
||||
end: {
|
||||
type: [String, Number],
|
||||
},
|
||||
/** 列选项过滤函数,支持自定义列内容。(type 值可为: year, month, date, hour, minute, second) */
|
||||
filter: {
|
||||
type: Function,
|
||||
},
|
||||
/** 用于格式化 pick、change、confirm 事件返回的值,[详细文档](https://day.js.org/docs/en/display/format) */
|
||||
format: {
|
||||
type: String,
|
||||
default: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
/** 格式化标签 */
|
||||
formatter: {
|
||||
type: Function,
|
||||
},
|
||||
/** 头部内容。值为 true 显示空白头部,值为 false 不显示任何内容 */
|
||||
header: {
|
||||
type: Boolean,
|
||||
default: true as TdDateTimePickerProps['header'],
|
||||
},
|
||||
/** year = 年;month = 年月;date = 年月日;hour = 年月日时; minute = 年月日时分;当类型为数组时,第一个值控制年月日,第二个值控制时分秒 */
|
||||
mode: {
|
||||
type: [String, Array],
|
||||
default: 'date' as TdDateTimePickerProps['mode'],
|
||||
},
|
||||
/** 透传 Popup 组件全部属性 */
|
||||
popupProps: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 是否在日期旁边显示周几(如周一,周二,周日等) */
|
||||
showWeek: Boolean,
|
||||
/** 选择器的最小可选时间,默认为当前时间-10年 */
|
||||
start: {
|
||||
type: [String, Number],
|
||||
},
|
||||
/** 时间间隔步数,示例:`{ minute: 5 }` */
|
||||
steps: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 标题 */
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 是否使用弹出层包裹 */
|
||||
usePopup: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 选中值 */
|
||||
value: {
|
||||
type: [String, Number],
|
||||
},
|
||||
/** 选中值,非受控属性 */
|
||||
defaultValue: {
|
||||
type: [String, Number],
|
||||
},
|
||||
/** 是否显示 */
|
||||
visible: Boolean,
|
||||
/** 取消按钮点击时触发 */
|
||||
onCancel: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 确认按钮点击时触发 */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 关闭时触发 */
|
||||
onClose: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 确认按钮点击时触发 */
|
||||
onConfirm: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 选中值发生变化时触发 */
|
||||
onPick: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
134
uni_modules/tdesign-uniapp/components/date-time-picker/type.ts
Normal file
134
uni_modules/tdesign-uniapp/components/date-time-picker/type.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdPopupProps as PopupProps } from '../popup/type';
|
||||
|
||||
export interface TdDateTimePickerProps {
|
||||
/**
|
||||
* 自动关闭;在确认、取消、点击遮罩层自动关闭,不需要手动设置 visible
|
||||
* @default false
|
||||
*/
|
||||
autoClose?: boolean;
|
||||
/**
|
||||
* 取消按钮文字
|
||||
* @default 取消
|
||||
*/
|
||||
cancelBtn?: string;
|
||||
/**
|
||||
* 确定按钮文字
|
||||
* @default ''
|
||||
*/
|
||||
confirmBtn?: string;
|
||||
/**
|
||||
* 组件国际化语言,目前支持: 简体中文(zh)、(tc)、英文(en)、日语(ja)、韩语(ko)、俄语(ru)等六种语言
|
||||
* @default zh
|
||||
*/
|
||||
customLocale?: string;
|
||||
/**
|
||||
* 选择器的最大可选时间,默认为当前时间+10年
|
||||
*/
|
||||
end?: string | number;
|
||||
/**
|
||||
* 列选项过滤函数,支持自定义列内容。(type 值可为: year, month, date, hour, minute, second)
|
||||
*/
|
||||
filter?: (type: TimeModeValues, columns: DateTimePickerColumn) => DateTimePickerColumn;
|
||||
/**
|
||||
* 用于格式化 pick、change、confirm 事件返回的值,[详细文档](https://day.js.org/docs/en/display/format)
|
||||
* @default 'YYYY-MM-DD HH:mm:ss'
|
||||
*/
|
||||
format?: string;
|
||||
/**
|
||||
* 格式化标签
|
||||
*/
|
||||
formatter?: (option: DateTimePickerColumnItem, columnIndex: number) => DateTimePickerColumnItem;
|
||||
/**
|
||||
* 头部内容。值为 true 显示空白头部,值为 false 不显示任何内容
|
||||
* @default true
|
||||
*/
|
||||
header?: boolean;
|
||||
/**
|
||||
* year = 年;month = 年月;date = 年月日;hour = 年月日时; minute = 年月日时分;当类型为数组时,第一个值控制年月日,第二个值控制时分秒
|
||||
* @default 'date'
|
||||
*/
|
||||
mode?: DateTimePickerMode;
|
||||
/**
|
||||
* 透传 Popup 组件全部属性
|
||||
* @default {}
|
||||
*/
|
||||
popupProps?: PopupProps;
|
||||
/**
|
||||
* 是否在日期旁边显示周几(如周一,周二,周日等)
|
||||
* @default false
|
||||
*/
|
||||
showWeek?: boolean;
|
||||
/**
|
||||
* 选择器的最小可选时间,默认为当前时间-10年
|
||||
*/
|
||||
start?: string | number;
|
||||
/**
|
||||
* 时间间隔步数,示例:`{ minute: 5 }`
|
||||
* @default {}
|
||||
*/
|
||||
steps?: { [key in TimeModeValues]?: number };
|
||||
/**
|
||||
* 标题
|
||||
* @default ''
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* 是否使用弹出层包裹
|
||||
* @default true
|
||||
*/
|
||||
usePopup?: boolean;
|
||||
/**
|
||||
* 选中值
|
||||
*/
|
||||
value?: DateValue;
|
||||
/**
|
||||
* 选中值,非受控属性
|
||||
*/
|
||||
defaultValue?: DateValue;
|
||||
/**
|
||||
* 是否显示
|
||||
* @default false
|
||||
*/
|
||||
visible?: boolean;
|
||||
/**
|
||||
* 取消按钮点击时触发
|
||||
*/
|
||||
onCancel?: () => void;
|
||||
/**
|
||||
* 确认按钮点击时触发
|
||||
*/
|
||||
onChange?: (context: { value: DateValue }) => void;
|
||||
/**
|
||||
* 关闭时触发
|
||||
*/
|
||||
onClose?: (context: { trigger: DateTimePickerTriggerSource }) => void;
|
||||
/**
|
||||
* 确认按钮点击时触发
|
||||
*/
|
||||
onConfirm?: (context: { value: DateValue }) => void;
|
||||
/**
|
||||
* 选中值发生变化时触发
|
||||
*/
|
||||
onPick?: (context: { value: DateValue }) => void;
|
||||
}
|
||||
|
||||
export type DateTimePickerColumn = DateTimePickerColumnItem[];
|
||||
|
||||
export interface DateTimePickerColumnItem {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type DateTimePickerMode = TimeModeValues | Array<TimeModeValues>;
|
||||
|
||||
export type TimeModeValues = 'year' | 'month' | 'date' | 'hour' | 'minute' | 'second' | 'null';
|
||||
|
||||
export type DateValue = string | number;
|
||||
|
||||
export type DateTimePickerTriggerSource = 'overlay' | 'cancel-btn' | 'confirm-btn';
|
||||
Reference in New Issue
Block a user