feat(Popup): add closeable prop (#4362)

This commit is contained in:
neverland 2019-09-04 17:58:34 +08:00 committed by GitHub
parent 0bd3997373
commit e64beee5b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 92 additions and 115 deletions

View File

@ -49,6 +49,17 @@ Use `position` prop to set popup display position
/> />
``` ```
### Close Icon
```html
<van-popup
v-model="show"
closeable
position="bottom"
:style="{ height: '20%' }"
/>
```
### Round Corner ### Round Corner
```html ```html
@ -112,6 +123,7 @@ export default {
| close-on-click-overlay | Whether to close when click overlay | *boolean* | `true` | - | | close-on-click-overlay | Whether to close when click overlay | *boolean* | `true` | - |
| transition | Transition | *string* | `popup-slide` | - | | transition | Transition | *string* | `popup-slide` | - |
| get-container | Return the mount node for Popup | *string \| () => HTMLElement* | - | - | | get-container | Return the mount node for Popup | *string \| () => HTMLElement* | - | - |
| closeable | Whether to show close icon | *boolean* | `false` | 2.2.0 |
### Events ### Events

View File

@ -55,6 +55,19 @@ export default {
/> />
``` ```
### 关闭图标
设置`closeable`属性后,会在弹出层的右上角显示关闭图标
```html
<van-popup
v-model="show"
closeable
position="bottom"
:style="{ height: '20%' }"
/>
```
### 圆角弹窗 ### 圆角弹窗
设置`round`属性后,弹窗会根据弹出位置添加不同的圆角样式 设置`round`属性后,弹窗会根据弹出位置添加不同的圆角样式
@ -119,7 +132,8 @@ export default {
| lock-scroll | 是否锁定背景滚动 | *boolean* | `true` | - | | lock-scroll | 是否锁定背景滚动 | *boolean* | `true` | - |
| lazy-render | 是否在显示弹层时才渲染节点 | *boolean* | `true` | - | | lazy-render | 是否在显示弹层时才渲染节点 | *boolean* | `true` | - |
| close-on-click-overlay | 是否在点击遮罩层后关闭 | *boolean* | `true` | - | | close-on-click-overlay | 是否在点击遮罩层后关闭 | *boolean* | `true` | - |
| transition | 动画类名,用法与 Vue 内置的`transtion`组件的`name`属性一致 | *string* | - | - | | closeable | 是否显示关闭图标 | *boolean* | `false` | 2.2.0 |
| transition | 动画类名,用法与 Vue 原生`transtion`组件的`name`属性一致 | *string* | - | - |
| get-container | 指定挂载的节点,可以传入选择器,<br>或一个返回节点的函数 | *string \| () => HTMLElement* | - | - | | get-container | 指定挂载的节点,可以传入选择器,<br>或一个返回节点的函数 | *string \| () => HTMLElement* | - | - |
### Events ### Events

View File

@ -1,109 +1,43 @@
<template> <template>
<demo-section> <demo-section>
<demo-block :title="$t('basicUsage')"> <demo-block :title="$t('basicUsage')">
<van-button <van-button type="primary" @click="showBasic = true">{{ $t('buttonBasic') }}</van-button>
type="primary" <van-popup v-model="showBasic" :style="{ padding: '30px 50px' }">{{ $t('content') }}</van-popup>
@click="showBasic = true"
>
{{ $t('buttonBasic') }}
</van-button>
<van-popup
v-model="showBasic"
:style="{ padding: '30px 50px' }"
>
{{ $t('content') }}
</van-popup>
</demo-block> </demo-block>
<demo-block :title="$t('position')"> <demo-block :title="$t('position')">
<van-row> <van-row>
<van-button <!-- top -->
type="primary" <van-button type="primary" @click="showTop = true">{{ $t('buttonTop') }}</van-button>
@click="showTop = true" <van-popup v-model="showTop" position="top" :style="{ height: '20%' }" />
>
{{ $t('buttonTop') }}
</van-button>
<van-popup <!-- bottom -->
v-model="showTop" <van-button type="primary" @click="showBottom = true">{{ $t('buttonBottom') }}</van-button>
position="top" <van-popup v-model="showBottom" position="bottom" :style="{ height: '20%' }" />
:style="{ height: '20%' }"
/>
<van-button
type="primary"
@click="showBottom = true"
>
{{ $t('buttonBottom') }}
</van-button>
<van-popup
v-model="showBottom"
position="bottom"
:style="{ height: '20%' }"
/>
</van-row> </van-row>
<van-button <!-- left -->
type="primary" <van-button type="primary" @click="showLeft = true">{{ $t('buttonLeft') }}</van-button>
@click="showLeft = true" <van-popup v-model="showLeft" position="left" :style="{ width: '20%', height: '100%' }" />
>
{{ $t('buttonLeft') }}
</van-button>
<van-popup <!-- right -->
v-model="showLeft" <van-button type="primary" @click="showRight = true">{{ $t('buttonRight') }}</van-button>
position="left" <van-popup v-model="showRight" position="right" :style="{ width: '20%', height: '100%' }" />
:style="{ width: '20%', height: '100%' }"
/>
<van-button
type="primary"
@click="showRight = true"
>
{{ $t('buttonRight') }}
</van-button>
<van-popup
v-model="showRight"
position="right"
:style="{ width: '20%', height: '100%' }"
/>
</demo-block> </demo-block>
<demo-block <demo-block v-if="!$attrs.weapp" :title="$t('closeIcon')">
v-if="!$attrs.weapp" <van-button type="primary" @click="showCloseIcon = true">{{ $t('closeIcon') }}</van-button>
:title="$t('roundCorner')" <van-popup v-model="showCloseIcon" closeable position="bottom" :style="{ height: '20%' }" />
>
<van-button
type="primary"
@click="showRoundCorner = true"
>
{{ $t('roundCorner') }}
</van-button>
<van-popup
v-model="showRoundCorner"
round
position="bottom"
:style="{ height: '20%' }"
/>
</demo-block> </demo-block>
<demo-block <demo-block v-if="!$attrs.weapp" :title="$t('roundCorner')">
v-if="!$attrs.weapp" <van-button type="primary" @click="showRoundCorner = true">{{ $t('roundCorner') }}</van-button>
:title="$t('getContainer')" <van-popup v-model="showRoundCorner" round position="bottom" :style="{ height: '20%' }" />
> </demo-block>
<van-button
type="primary" <demo-block v-if="!$attrs.weapp" :title="$t('getContainer')">
@click="showGetContainer = true" <van-button type="primary" @click="showGetContainer = true">{{ $t('getContainer') }}</van-button>
> <van-popup v-model="showGetContainer" get-container="body" :style="{ padding: '30px 50px' }" />
{{ $t('getContainer') }}
</van-button>
<van-popup
v-model="showGetContainer"
get-container="body"
:style="{ padding: '30px 50px' }"
/>
</demo-block> </demo-block>
</demo-section> </demo-section>
</template> </template>
@ -119,7 +53,8 @@ export default {
buttonLeft: '左侧弹出', buttonLeft: '左侧弹出',
buttonRight: '右侧弹出', buttonRight: '右侧弹出',
getContainer: '指定挂载节点', getContainer: '指定挂载节点',
roundCorner: '圆角弹窗' roundCorner: '圆角弹窗',
closeIcon: '关闭图标'
}, },
'en-US': { 'en-US': {
position: 'Position', position: 'Position',
@ -129,7 +64,8 @@ export default {
buttonLeft: 'From Left', buttonLeft: 'From Left',
buttonRight: 'From Right', buttonRight: 'From Right',
getContainer: 'Get Container', getContainer: 'Get Container',
roundCorner: 'Round Corner' roundCorner: 'Round Corner',
closeIcon: 'Close Icon'
} }
}, },
@ -140,6 +76,7 @@ export default {
showBottom: false, showBottom: false,
showLeft: false, showLeft: false,
showRight: false, showRight: false,
showCloseIcon: false,
showRoundCorner: false, showRoundCorner: false,
showGetContainer: false showGetContainer: false
}; };

View File

@ -1,5 +1,6 @@
import { createNamespace, isDef } from '../utils'; import { createNamespace, isDef } from '../utils';
import { PopupMixin } from '../mixins/popup'; import { PopupMixin } from '../mixins/popup';
import Icon from '../icon';
const [createComponent, bem] = createNamespace('popup'); const [createComponent, bem] = createNamespace('popup');
@ -9,6 +10,7 @@ export default createComponent({
props: { props: {
round: Boolean, round: Boolean,
duration: Number, duration: Number,
closeable: Boolean,
transition: String, transition: String,
position: { position: {
type: String, type: String,
@ -61,6 +63,9 @@ export default createComponent({
onClick={this.onClick} onClick={this.onClick}
> >
{this.slots()} {this.slots()}
{this.closeable && (
<Icon name="cross" class={bem('close-icon')} onClick={this.close} />
)}
</div> </div>
</transition> </transition>
); );

View File

@ -82,5 +82,13 @@
&-slide-left-leave-active { &-slide-left-leave-active {
transform: translate3d(-100%, -50%, 0); transform: translate3d(-100%, -50%, 0);
} }
&__close-icon {
position: absolute;
top: 16px;
right: 16px;
color: @gray-dark;
font-size: 18px;
}
} }
} }

View File

@ -2,34 +2,23 @@
exports[`renders demo correctly 1`] = ` exports[`renders demo correctly 1`] = `
<div> <div>
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text"> <div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">展示弹出层</span></button>
展示弹出层
</span></button>
<!----> <!---->
</div> </div>
<div> <div>
<div class="van-row"><button class="van-button van-button--primary van-button--normal"><span class="van-button__text"> <div class="van-row"><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">顶部弹出</span></button>
顶部弹出 <!----> <button class="van-button van-button--primary van-button--normal"><span class="van-button__text">底部弹出</span></button>
</span></button>
<!----> <button class="van-button van-button--primary van-button--normal"><span class="van-button__text">
底部弹出
</span></button>
<!----> <!---->
</div> <button class="van-button van-button--primary van-button--normal"><span class="van-button__text"> </div> <button class="van-button van-button--primary van-button--normal"><span class="van-button__text">左侧弹出</span></button>
左侧弹出 <!----> <button class="van-button van-button--primary van-button--normal"><span class="van-button__text">右侧弹出</span></button>
</span></button>
<!----> <button class="van-button van-button--primary van-button--normal"><span class="van-button__text">
右侧弹出
</span></button>
<!----> <!---->
</div> </div>
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text"> <div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">关闭图标</span></button>
圆角弹窗
</span></button>
<!----> <!---->
</div> </div>
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text"> <div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">圆角弹窗</span></button>
指定挂载节点 <!---->
</span></button> </div> </div>
<div><button class="van-button van-button--primary van-button--normal"><span class="van-button__text">指定挂载节点</span></button> </div>
</div> </div>
`; `;

View File

@ -227,3 +227,15 @@ test('round prop', () => {
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
test('closeable prop', () => {
const wrapper = mount(Popup, {
propsData: {
value: true,
closeable: true
}
});
wrapper.find('.van-popup__close-icon').trigger('click');
expect(wrapper.emitted('input')[0][0]).toEqual(false);
});