feat(Picker): add empty slot (#13219)

This commit is contained in:
inottn 2024-11-24 19:49:58 +08:00 committed by GitHub
parent 42754ee7c8
commit b41f8cd14c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 143 additions and 2 deletions

View File

@ -241,6 +241,11 @@ export default defineComponent({
const renderColumns = () => {
const wrapHeight = optionHeight.value * +props.visibleOptionNum;
const columnsStyle = { height: `${wrapHeight}px` };
if (!props.loading && !hasOptions.value && slots.empty) {
return slots.empty();
}
return (
<div ref={columnsRef} class={bem('columns')} style={columnsStyle}>
{renderColumnItems()}

View File

@ -276,11 +276,27 @@ export default {
};
```
### Empty content
When the data is empty, you can use the `empty` slot to customize the empty content.
```html
<van-picker title="Title">
<template #empty>
<van-empty
image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png"
image-size="80"
description="No data"
/>
</template>
</van-picker>
```
### Custom Columns Field
```html
<van-picker
:title="Title"
title="Title"
:columns="columns"
:columns-field-names="customFieldName"
/>
@ -374,6 +390,7 @@ export default {
| option | Custom option content | _option: PickerOption, index: number_ |
| columns-top | Custom content above columns | - |
| columns-bottom | Custom content below columns | - |
| empty `v4.9.10` | Custom empty content | - |
### Data Structure of PickerOption

View File

@ -297,11 +297,27 @@ export default {
};
```
### 空状态
当数据为空时,可以使用 `empty` 插槽自定义空状态内容。
```html
<van-picker title="标题">
<template #empty>
<van-empty
image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png"
image-size="80"
description="No data"
/>
</template>
</van-picker>
```
### 自定义 Columns 的结构
```html
<van-picker
:title="标题"
title="标题"
:columns="columns"
:columns-field-names="customFieldName"
/>
@ -395,6 +411,7 @@ export default {
| option | 自定义选项内容 | _option: PickerOption, index: number_ |
| columns-top | 自定义选项上方内容 | - |
| columns-bottom | 自定义选项下方内容 | - |
| empty `v4.9.10` | 自定义空状态内容 | - |
### PickerOption 数据结构

View File

@ -12,6 +12,7 @@ import {
disabledColumns,
customKeyColumns,
} from './data';
import VanEmpty from '../../empty';
import { showToast } from '../../toast';
import { useTranslate } from '../../../docs/site';
@ -29,6 +30,7 @@ const t = useTranslate({
multipleColumns: '多列选择',
customChildrenKey: '自定义 Columns 结构',
customChildrenColumns: customKeyColumns['zh-CN'],
emptyDescription: '暂无数据',
toastContent: (value: string) => `当前值:${value}`,
},
'en-US': {
@ -44,6 +46,7 @@ const t = useTranslate({
multipleColumns: 'Multiple Columns',
customChildrenKey: 'Custom Columns Fields',
customChildrenColumns: customKeyColumns['en-US'],
emptyDescription: 'No data',
toastContent: (value: string) => `Value: ${value}`,
},
});
@ -109,6 +112,18 @@ const onCancel = () => showToast(t('cancel'));
<van-picker loading :title="t('title')" />
</demo-block>
<demo-block card :title="t('emptyStatus')">
<van-picker :title="t('title')">
<template #empty>
<van-empty
image="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png"
image-size="80"
:description="t('emptyDescription')"
/>
</template>
</van-picker>
</demo-block>
<demo-block card :title="t('customChildrenKey')">
<van-picker
:title="t('title')"

View File

@ -640,6 +640,41 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</div>
</div>
<div>
<!--[-->
<div class="van-picker">
<div class="van-picker__toolbar">
<!--[-->
<button
type="button"
class="van-picker__cancel van-haptics-feedback"
>
Cancel
</button>
<div class="van-picker__title van-ellipsis">
Title
</div>
<button
type="button"
class="van-picker__confirm van-haptics-feedback"
>
Confirm
</button>
</div>
<!--[-->
<div class="van-empty">
<div
class="van-empty__image"
style="width:80px;height:80px;"
>
<img src="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png">
</div>
<p class="van-empty__description">
No data
</p>
</div>
</div>
</div>
<div>
<!--[-->
<div class="van-picker">

View File

@ -608,6 +608,38 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</div>
</div>
<div>
<div class="van-picker">
<div class="van-picker__toolbar">
<button
type="button"
class="van-picker__cancel van-haptics-feedback"
>
Cancel
</button>
<div class="van-picker__title van-ellipsis">
Title
</div>
<button
type="button"
class="van-picker__confirm van-haptics-feedback"
>
Confirm
</button>
</div>
<div class="van-empty">
<div
class="van-empty__image"
style="width: 80px; height: 80px;"
>
<img src="https://fastly.jsdelivr.net/npm/@vant/assets/custom-empty-image.png">
</div>
<p class="van-empty__description">
No data
</p>
</div>
</div>
</div>
<div>
<div class="van-picker">
<div class="van-picker__toolbar">

View File

@ -420,3 +420,23 @@ test('should allow to skip rendering confirm and cancel buttons', async () => {
expect(wrapper.find('.van-picker__confirm').exists()).toBeFalsy();
expect(wrapper.find('.van-picker__cancel').exists()).toBeFalsy();
});
test('should render empty slot when options is empty', async () => {
const wrapper = mount(Picker, {
props: {
loading: true,
columns: [[], []],
},
slots: {
empty: () => <div>empty content</div>,
},
});
expect(wrapper.html()).not.toContain('empty content');
await wrapper.setProps({ loading: false });
expect(wrapper.html()).toContain('empty content');
await wrapper.setProps({ columns: [{ values: ['foo'] }] });
expect(wrapper.html()).not.toContain('empty content');
});