diff --git a/components.js b/components.js index e0ee8e4be..d601c0a41 100644 --- a/components.js +++ b/components.js @@ -46,4 +46,5 @@ module.exports = [ 'picker', 'dialog', 'toast', + 'calendar', ]; diff --git a/docs/markdown/changelog-v3.zh-CN.md b/docs/markdown/changelog-v3.zh-CN.md index 8e5705bcf..168a06737 100644 --- a/docs/markdown/changelog-v3.zh-CN.md +++ b/docs/markdown/changelog-v3.zh-CN.md @@ -24,16 +24,17 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。 以下改动是为了适配 Vue 3 的 v-model API 用法变更: -- Tabs: `v-model` 重命名为 `v-model:active` -- Popup: `v-model` 重命名为 `v-model:show` +- ActionSheet: `v-model` 重命名为 `v-model:show` +- Calendar: `v-model` 重命名为 `v-model:show` - Circle: `v-model` 重命名为 `v-model:currentRate` - Dialog: `v-model` 重命名为 `v-model:show` -- ShareSheet: `v-model` 重命名为 `v-model:show` -- ActionSheet: `v-model` 重命名为 `v-model:show` -- List: `v-model` 重命名为 `v-model:loading`,`error.sync` 重命名为 `v-model:error` - Field: v-model 对应的属性 `value` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue` -- Switch: v-model 对应的属性 `value` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue` +- List: `v-model` 重命名为 `v-model:loading`,`error.sync` 重命名为 `v-model:error` +- Popup: `v-model` 重命名为 `v-model:show` - Sidebar: v-model 对应的属性 `activeKey` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue` +- ShareSheet: `v-model` 重命名为 `v-model:show` +- Switch: v-model 对应的属性 `value` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue` +- Tabs: `v-model` 重命名为 `v-model:active` - TreeSelect: `active-id.sync` 重命名为 `v-model:active-id` - TreeSelect: `main-active-index.sync` 重命名为 `v-model:main-active-index` diff --git a/src/calendar/README.md b/src/calendar/README.md index 69c0d53e7..8184de2f4 100644 --- a/src/calendar/README.md +++ b/src/calendar/README.md @@ -21,7 +21,7 @@ The `confirm` event will be triggered after the date selection is completed. ```html - + ``` ```js @@ -48,7 +48,7 @@ export default { ```html - + ``` ```js @@ -74,7 +74,7 @@ You can select a date range after setting `type` to`range`. In range mode, the d ```html - + ``` ```js @@ -103,7 +103,7 @@ export default { Set `show-confirm` to `false` to hide the confirm button. In this case, the `confirm` event will be triggered immediately after the selection is completed. ```html - + ``` ### Custom Color @@ -111,7 +111,7 @@ Set `show-confirm` to `false` to hide the confirm button. In this case, the `con Use `color` prop to custom calendar color. ```html - + ``` ### Custom Date Range @@ -119,7 +119,7 @@ Use `color` prop to custom calendar color. Use `min-date` and `max-date` to custom date range. ```html - + ``` ```js @@ -140,7 +140,7 @@ Use `confirm-text` and `confirm-disabled-text` to custom confirm text. ```html + ``` ```js @@ -189,7 +189,7 @@ export default { Use `position` to custom popup position,can be set to `top`、`left`、`right`. ```html - + ``` ### Max Range @@ -251,7 +251,7 @@ Following props are supported when the poppable is true | Attribute | Description | Type | Default | | --- | --- | --- | --- | -| v-model | Whether to show calendar | _boolean_ | `false` | +| v-model:show | Whether to show calendar | _boolean_ | `false` | | position | Popup position, can be set to `top` `right` `left` | _string_ | `bottom` | | round | Whether to show round corner | _boolean_ | `true` | | close-on-popstate `v2.4.4` | Whether to close when popstate | _boolean_ | `true` | diff --git a/src/calendar/README.zh-CN.md b/src/calendar/README.zh-CN.md index 075b38fa9..adfbca1fe 100644 --- a/src/calendar/README.zh-CN.md +++ b/src/calendar/README.zh-CN.md @@ -21,7 +21,7 @@ Vue.use(Calendar); ```html - + ``` ```js @@ -50,7 +50,7 @@ export default { ```html - + ``` ```js @@ -76,7 +76,7 @@ export default { ```html - + ``` ```js @@ -105,7 +105,7 @@ export default { 将 `show-confirm` 设置为 `false` 可以隐藏确认按钮,这种情况下选择完成后会立即触发 `confirm` 事件。 ```html - + ``` ### 自定义颜色 @@ -113,7 +113,7 @@ export default { 通过 `color` 属性可以自定义日历的颜色,对选中日期和底部按钮生效。 ```html - + ``` ### 自定义日期范围 @@ -121,7 +121,7 @@ export default { 通过 `min-date` 和 `max-date` 定义日历的范围。 ```html - + ``` ```js @@ -142,7 +142,7 @@ export default { ```html + ``` ```js @@ -191,7 +191,7 @@ export default { 通过 `position` 属性自定义弹出层的弹出位置,可选值为 `top`、`left`、`right`。 ```html - + ``` ### 日期区间最大范围 @@ -253,7 +253,7 @@ export default { | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | -| v-model | 是否显示日历弹窗 | _boolean_ | `false` | +| v-model:show | 是否显示日历弹窗 | _boolean_ | `false` | | position | 弹出位置,可选值为 `top` `right` `left` | _string_ | `bottom` | | round | 是否显示圆角弹窗 | _boolean_ | `true` | | close-on-popstate `v2.4.4` | 是否在页面回退时自动关闭 | _boolean_ | `true` | diff --git a/src/calendar/components/Header.js b/src/calendar/components/Header.js index 814583b29..9166999b6 100644 --- a/src/calendar/components/Header.js +++ b/src/calendar/components/Header.js @@ -15,7 +15,7 @@ export default createComponent({ methods: { genTitle() { if (this.showTitle) { - const title = this.slots('title') || this.title || t('title'); + const title = this.$slots.title?.() || this.title || t('title'); return
{title}
; } }, diff --git a/src/calendar/components/Month.js b/src/calendar/components/Month.js index a04dfda3e..dd4fee992 100644 --- a/src/calendar/components/Month.js +++ b/src/calendar/components/Month.js @@ -31,6 +31,8 @@ export default createComponent({ firstDayOfWeek: Number, }, + emits: ['click'], + data() { return { visible: false, @@ -183,18 +185,16 @@ export default createComponent({ return 'disabled'; } - if (type === 'single') { + if (Array.isArray(currentDate)) { + if (type === 'multiple') { + return this.getMultipleDayType(day); + } + if (type === 'range') { + return this.getRangeDayType(day); + } + } else if (type === 'single') { return compareDay(day, currentDate) === 0 ? 'selected' : ''; } - - if (type === 'multiple') { - return this.getMultipleDayType(day); - } - - /* istanbul ignore else */ - if (type === 'range') { - return this.getRangeDayType(day); - } }, getBottomInfo(type) { diff --git a/src/calendar/demo/index.vue b/src/calendar/demo/index.vue index 5b2c7a767..1dfb3476c 100644 --- a/src/calendar/demo/index.vue +++ b/src/calendar/demo/index.vue @@ -102,7 +102,7 @@ { if (compareMonth(month, targetDate) === 0) { - const { body, months } = this.$refs; - months[index].scrollIntoView(body); + const { body } = this.$refs; + this.monthRefs[index].scrollIntoView(body); return true; } @@ -244,9 +257,10 @@ export default createComponent({ // calculate the position of the elements // and find the elements that needs to be rendered onScroll() { - const { body, months } = this.$refs; + const { body } = this.$refs; + const { months, monthRefs } = this; const top = getScrollTop(body); - const heights = months.map((item) => item.getHeight()); + const heights = months.map((item, index) => monthRefs[index].getHeight()); const heightSum = heights.reduce((a, b) => a + b, 0); // iOS scroll bounce may exceed the range @@ -262,17 +276,17 @@ export default createComponent({ const visible = height <= bottom && height + heights[i] >= top; if (visible && !currentMonth) { - currentMonth = months[i]; + currentMonth = monthRefs[i]; } - if (!months[i].visible && visible) { + if (!monthRefs[i].visible && visible) { this.$emit('month-show', { - date: months[i].date, - title: months[i].title, + date: monthRefs[i].date, + title: monthRefs[i].title, }); } - months[i].visible = visible; + monthRefs[i].visible = visible; height += heights[i]; } @@ -327,7 +341,7 @@ export default createComponent({ }, togglePopup(val) { - this.$emit('input', val); + this.$emit('update:show', val); }, select(date, complete) { @@ -376,8 +390,9 @@ export default createComponent({ const showMonthTitle = index !== 0 || !this.showSubtitle; return ( { + this.monthRefs[index] = val; + }} date={date} type={this.type} color={this.color} @@ -398,10 +413,8 @@ export default createComponent({ }, genFooterContent() { - const slot = this.slots('footer'); - - if (slot) { - return slot; + if (this.$slots.footer) { + return this.$slots.footer(); } if (this.showConfirm) { @@ -438,13 +451,13 @@ export default createComponent({ return (
this.slots('title'), - }} firstDayOfWeek={this.dayOffset} />
@@ -459,23 +472,25 @@ export default createComponent({ render() { if (this.poppable) { const createListener = (name) => () => this.$emit(name); + const listeners = { + 'onUpdate:show': this.togglePopup, + onOpen: createListener('open'), + onClose: createListener('close'), + onOpened: createListener('opened'), + onClosed: createListener('closed'), + }; return ( {this.genCalendar()} diff --git a/vant.config.js b/vant.config.js index b687d8194..ac3fe0f12 100644 --- a/vant.config.js +++ b/vant.config.js @@ -115,10 +115,10 @@ module.exports = { { title: '表单组件', items: [ - // { - // path: 'calendar', - // title: 'Calendar 日历', - // }, + { + path: 'calendar', + title: 'Calendar 日历', + }, // { // path: 'checkbox', // title: 'Checkbox 复选框', @@ -449,10 +449,10 @@ module.exports = { { title: 'Form Components', items: [ - // { - // path: 'calendar', - // title: 'Calendar', - // }, + { + path: 'calendar', + title: 'Calendar', + }, // { // path: 'checkbox', // title: 'Checkbox',