mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat: add Empty component (#6010)
This commit is contained in:
parent
14299a2011
commit
525f7ecb88
80
src/empty/README.md
Normal file
80
src/empty/README.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# Empty
|
||||||
|
|
||||||
|
### Install
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { Empty } from 'vant';
|
||||||
|
|
||||||
|
Vue.use(Empty);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-empty description="Description" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Image Type
|
||||||
|
|
||||||
|
Use the image prop to display different placeholder images
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Error -->
|
||||||
|
<van-empty image="error" description="Description" />
|
||||||
|
<!-- Network -->
|
||||||
|
<van-empty image="network" description="Description" />
|
||||||
|
<!-- Search -->
|
||||||
|
<van-empty image="search" description="Description" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Image
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-empty
|
||||||
|
class="custom-image"
|
||||||
|
image="https://img.yzcdn.cn/vant/leaf.jpg"
|
||||||
|
description="Description"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.custom-image img {
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bottom Content
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-empty description="Description">
|
||||||
|
<van-button round type="danger" class="bottom-button">
|
||||||
|
Button
|
||||||
|
</van-button>
|
||||||
|
</van-empty>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.bottom-button {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### Props
|
||||||
|
|
||||||
|
| Attribute | Description | Type | Default |
|
||||||
|
|------|------|------|------|
|
||||||
|
| image | Image type,can be set to `error` `network` `search` or image URL | *string* | `default` |
|
||||||
|
| description | Desciption | *string* | - |
|
||||||
|
|
||||||
|
### Slots
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
|------|------|
|
||||||
|
| default | Custom bottom content |
|
||||||
|
| image | Custom image |
|
||||||
|
| description | Custom description |
|
89
src/empty/README.zh-CN.md
Normal file
89
src/empty/README.zh-CN.md
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# Empty 空状态
|
||||||
|
|
||||||
|
### 介绍
|
||||||
|
|
||||||
|
空状态时的占位提示,2.6 版本开始支持此组件
|
||||||
|
|
||||||
|
### 引入
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { Empty } from 'vant';
|
||||||
|
|
||||||
|
Vue.use(Empty);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 代码演示
|
||||||
|
|
||||||
|
### 基本用法
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-empty description="描述文字" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### 图片类型
|
||||||
|
|
||||||
|
Empty 组件内置了多种占位图片类型,可以在不同业务场景下使用
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- 通用错误 -->
|
||||||
|
<van-empty image="error" description="描述文字" />
|
||||||
|
<!-- 网络错误 -->
|
||||||
|
<van-empty image="network" description="描述文字" />
|
||||||
|
<!-- 搜索提示 -->
|
||||||
|
<van-empty image="search" description="描述文字" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自定义图片
|
||||||
|
|
||||||
|
需要自定义图片时,可以在 image 属性中传入任意图片 URL
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-empty
|
||||||
|
class="custom-image"
|
||||||
|
image="https://img.yzcdn.cn/vant/custom-empty-image.png"
|
||||||
|
description="描述文字"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.custom-image .van-empty__image {
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 底部内容
|
||||||
|
|
||||||
|
通过默认插槽可以在 Empty 组件的下方插入内容
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-empty description="描述文字">
|
||||||
|
<van-button round type="danger" class="bottom-button">
|
||||||
|
按钮
|
||||||
|
</van-button>
|
||||||
|
</van-empty>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.bottom-button {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### Props
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| image | 图片类型,可选值为 `error` `network` `search`,支持传入图片 URL | *string* | `default` |
|
||||||
|
| description | 图片下方的描述文字 | *string* | - |
|
||||||
|
|
||||||
|
### Slots
|
||||||
|
|
||||||
|
| 名称 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| default | 自定义底部内容 |
|
||||||
|
| image | 自定义图标 |
|
||||||
|
| description | 自定义描述文字 |
|
87
src/empty/demo/index.vue
Normal file
87
src/empty/demo/index.vue
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<template>
|
||||||
|
<demo-section>
|
||||||
|
<demo-block :title="t('basicUsage')">
|
||||||
|
<van-empty :description="t('description')" />
|
||||||
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block :title="t('imageType')">
|
||||||
|
<van-tabs v-model="active">
|
||||||
|
<van-tab name="error" :title="t('error')">
|
||||||
|
<van-empty image="error" :description="t('description')" />
|
||||||
|
</van-tab>
|
||||||
|
<van-tab name="network" :title="t('network')">
|
||||||
|
<van-empty image="network" :description="t('description')" />
|
||||||
|
</van-tab>
|
||||||
|
<van-tab name="search" :title="t('search')">
|
||||||
|
<van-empty image="search" :description="t('description')" />
|
||||||
|
</van-tab>
|
||||||
|
</van-tabs>
|
||||||
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block :title="t('customImage')">
|
||||||
|
<van-empty
|
||||||
|
class="custom-image"
|
||||||
|
image="https://img.yzcdn.cn/vant/custom-empty-image.png"
|
||||||
|
:description="t('description')"
|
||||||
|
/>
|
||||||
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block :title="t('bottomContent')">
|
||||||
|
<van-empty :description="t('description')">
|
||||||
|
<van-button round type="danger" class="bottom-button">
|
||||||
|
{{ t('button') }}
|
||||||
|
</van-button>
|
||||||
|
</van-empty>
|
||||||
|
</demo-block>
|
||||||
|
</demo-section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
i18n: {
|
||||||
|
'zh-CN': {
|
||||||
|
error: '通用错误',
|
||||||
|
search: '搜索提示',
|
||||||
|
network: '网络错误',
|
||||||
|
imageType: '图片类型',
|
||||||
|
description: '描述文字',
|
||||||
|
customImage: '自定义图片',
|
||||||
|
bottomContent: '底部内容',
|
||||||
|
},
|
||||||
|
'en-US': {
|
||||||
|
error: 'Error',
|
||||||
|
search: 'Search',
|
||||||
|
network: 'Network',
|
||||||
|
imageType: 'Image Type',
|
||||||
|
description: 'Description',
|
||||||
|
customImage: 'Custom Image',
|
||||||
|
bottomContent: 'Bottom Content',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
active: 'error',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
@import '../../style/var';
|
||||||
|
|
||||||
|
.demo-empty {
|
||||||
|
background: @white;
|
||||||
|
|
||||||
|
.custom-image {
|
||||||
|
.van-empty__image {
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-button {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
58
src/empty/index.js
Normal file
58
src/empty/index.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { createNamespace } from '../utils';
|
||||||
|
|
||||||
|
const [createComponent, bem] = createNamespace('empty');
|
||||||
|
|
||||||
|
const PRESETS = ['error', 'search', 'default', 'network'];
|
||||||
|
|
||||||
|
export default createComponent({
|
||||||
|
props: {
|
||||||
|
description: String,
|
||||||
|
image: {
|
||||||
|
type: String,
|
||||||
|
default: 'default',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
url() {
|
||||||
|
if (PRESETS.indexOf(this.image) !== -1) {
|
||||||
|
return `https://img.yzcdn.cn/vant/empty-image-${this.image}.png`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.image;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
genImage() {
|
||||||
|
const image = this.slots('image') || <img src={this.url} />;
|
||||||
|
return <div class={bem('image')}>{image}</div>;
|
||||||
|
},
|
||||||
|
|
||||||
|
genDescription() {
|
||||||
|
const description = this.slots('description') || this.description;
|
||||||
|
|
||||||
|
if (description) {
|
||||||
|
return <p class={bem('description')}>{description}</p>;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
genBottom() {
|
||||||
|
const slot = this.slots();
|
||||||
|
|
||||||
|
if (slot) {
|
||||||
|
return <div class={bem('bottom')}>{slot}</div>;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div class={bem()}>
|
||||||
|
{this.genImage()}
|
||||||
|
{this.genDescription()}
|
||||||
|
{this.genBottom()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
32
src/empty/index.less
Normal file
32
src/empty/index.less
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
@import '../style/var';
|
||||||
|
|
||||||
|
.van-empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: @empty-padding;
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
width: @empty-image-size;
|
||||||
|
height: @empty-image-size;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
margin-top: @empty-description-margin-top;
|
||||||
|
padding: @empty-description-padding;
|
||||||
|
color: @empty-description-color;
|
||||||
|
font-size: @empty-description-font-size;
|
||||||
|
line-height: @empty-description-line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__bottom {
|
||||||
|
margin-top: @empty-bottom-margin-top;
|
||||||
|
}
|
||||||
|
}
|
53
src/empty/test/__snapshots__/demo.spec.js.snap
Normal file
53
src/empty/test/__snapshots__/demo.spec.js.snap
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`renders demo correctly 1`] = `
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<div class="van-empty">
|
||||||
|
<div class="van-empty__image"><img src="https://img.yzcdn.cn/vant/empty-image-default.png"></div>
|
||||||
|
<p class="van-empty__description">描述文字</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="van-tabs van-tabs--line">
|
||||||
|
<div class="van-tabs__wrap van-hairline--top-bottom">
|
||||||
|
<div role="tablist" class="van-tabs__nav van-tabs__nav--line">
|
||||||
|
<div role="tab" aria-selected="true" class="van-tab van-tab--active van-ellipsis"><span class="van-tab__text">通用错误<!----></span></div>
|
||||||
|
<div role="tab" class="van-tab van-ellipsis"><span class="van-tab__text">网络错误<!----></span></div>
|
||||||
|
<div role="tab" class="van-tab van-ellipsis"><span class="van-tab__text">搜索提示<!----></span></div>
|
||||||
|
<div class="van-tabs__line" style="width: 0px; transform: translateX(0px) translateX(-50%);"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="van-tabs__content">
|
||||||
|
<div role="tabpanel" class="van-tab__pane" style="">
|
||||||
|
<div class="van-empty">
|
||||||
|
<div class="van-empty__image"><img src="https://img.yzcdn.cn/vant/empty-image-error.png"></div>
|
||||||
|
<p class="van-empty__description">描述文字</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div role="tabpanel" class="van-tab__pane" style="display: none;">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
<div role="tabpanel" class="van-tab__pane" style="display: none;">
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="custom-image van-empty">
|
||||||
|
<div class="van-empty__image"><img src="https://img.yzcdn.cn/vant/custom-empty-image.png"></div>
|
||||||
|
<p class="van-empty__description">描述文字</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="van-empty">
|
||||||
|
<div class="van-empty__image"><img src="https://img.yzcdn.cn/vant/empty-image-default.png"></div>
|
||||||
|
<p class="van-empty__description">描述文字</p>
|
||||||
|
<div class="van-empty__bottom"><button class="bottom-button van-button van-button--danger van-button--normal van-button--round"><span class="van-button__text">
|
||||||
|
按钮
|
||||||
|
</span></button></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
14
src/empty/test/__snapshots__/index.spec.js.snap
Normal file
14
src/empty/test/__snapshots__/index.spec.js.snap
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`description slot 1`] = `
|
||||||
|
<div class="van-empty">
|
||||||
|
<div class="van-empty__image"><img src="https://img.yzcdn.cn/vant/empty-image-default.png"></div>
|
||||||
|
<p class="van-empty__description">Custom description</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`image slot 1`] = `
|
||||||
|
<div class="van-empty">
|
||||||
|
<div class="van-empty__image">Custom Image</div>
|
||||||
|
</div>
|
||||||
|
`;
|
4
src/empty/test/demo.spec.js
Normal file
4
src/empty/test/demo.spec.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import Demo from '../demo';
|
||||||
|
import { snapshotDemo } from '../../../test/demo';
|
||||||
|
|
||||||
|
snapshotDemo(Demo);
|
22
src/empty/test/index.spec.js
Normal file
22
src/empty/test/index.spec.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import Empty from '..';
|
||||||
|
import { mount } from '../../../test';
|
||||||
|
|
||||||
|
test('image slot', () => {
|
||||||
|
const wrapper = mount(Empty, {
|
||||||
|
scopedSlots: {
|
||||||
|
image: () => 'Custom Image',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('description slot', () => {
|
||||||
|
const wrapper = mount(Empty, {
|
||||||
|
scopedSlots: {
|
||||||
|
description: () => 'Custom description',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
@ -333,6 +333,16 @@
|
|||||||
@dropdown-menu-content-max-height: 80%;
|
@dropdown-menu-content-max-height: 80%;
|
||||||
@dropdown-item-z-index: 10;
|
@dropdown-item-z-index: 10;
|
||||||
|
|
||||||
|
// Empty
|
||||||
|
@empty-padding: @padding-xl 0;
|
||||||
|
@empty-image-size: 160px;
|
||||||
|
@empty-description-margin-top: @padding-md;
|
||||||
|
@empty-description-padding: 0 60px;
|
||||||
|
@empty-description-color: @gray-6;
|
||||||
|
@empty-description-font-size: 14px;
|
||||||
|
@empty-description-line-height: 20px;
|
||||||
|
@empty-bottom-margin-top: 24px;
|
||||||
|
|
||||||
// Field
|
// Field
|
||||||
@field-label-width: 90px;
|
@field-label-width: 90px;
|
||||||
@field-input-text-color: @text-color;
|
@field-input-text-color: @text-color;
|
||||||
|
1
types/index.d.ts
vendored
1
types/index.d.ts
vendored
@ -45,6 +45,7 @@ export class CouponCell extends VanComponent {}
|
|||||||
export class CouponList extends VanComponent {}
|
export class CouponList extends VanComponent {}
|
||||||
export class Divider extends VanComponent {}
|
export class Divider extends VanComponent {}
|
||||||
export class DropdownMenu extends VanComponent {}
|
export class DropdownMenu extends VanComponent {}
|
||||||
|
export class Empty extends VanComponent {}
|
||||||
export class Grid extends VanComponent {}
|
export class Grid extends VanComponent {}
|
||||||
export class GridItem extends VanComponent {}
|
export class GridItem extends VanComponent {}
|
||||||
export class GoodsAction extends VanComponent {}
|
export class GoodsAction extends VanComponent {}
|
||||||
|
@ -232,6 +232,10 @@ module.exports = {
|
|||||||
path: 'divider',
|
path: 'divider',
|
||||||
title: 'Divider 分割线',
|
title: 'Divider 分割线',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'empty',
|
||||||
|
title: 'Empty 空状态',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'image-preview',
|
path: 'image-preview',
|
||||||
title: 'ImagePreview 图片预览',
|
title: 'ImagePreview 图片预览',
|
||||||
@ -575,6 +579,10 @@ module.exports = {
|
|||||||
path: 'divider',
|
path: 'divider',
|
||||||
title: 'Divider',
|
title: 'Divider',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'empty',
|
||||||
|
title: 'Empty',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'image-preview',
|
path: 'image-preview',
|
||||||
title: 'ImagePreview',
|
title: 'ImagePreview',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user