# PopupPlus 弹出层
弹出层组件,在应用中弹出一个消息提示窗口、提示框等
# 引入
import PressPopupPlus from 'press-ui/press-popup-plus/press-popup-plus.vue';
export default {
components: {
PressPopupPlus,
}
}
# 代码演示
# 关闭图标
设置close-icon为true。
<template>
<PressPopupPlus
v-if="show"
:close-icon="true"
:arrow-icon="false"
:title="title"
button="确定"
@confirm="confirm"
@cancel="cancel"
>
<div class="content">
一些内容
</div>
</PressPopupPlus>
</template>
export default {
data() {
return {
title: '决胜方式',
show: false;
}
},
methods: {
cancel() {
this.show = false;
},
confirm() {
this.show = false;
},
}
};
</script>
# 取消图标
设置arrow-icon为true。
<PressPopupPlus
v-if="show"
:close-icon="false"
:arrow-icon="true"
:title="title"
button="确定"
@confirm="confirm"
@cancel="cancel"
>
<div class="content">
一些内容
</div>
</PressPopupPlus>
# 没有关闭/取消
设置close-icon为false,arrow-icon为false。
<PressPopupPlus
v-if="show"
:close-icon="false"
:arrow-icon="false"
:title="title"
button="确定"
@confirm="confirm"
@cancel="cancel"
>
<div class="content">
一些内容
</div>
</PressPopupPlus>
# 线框确认图标
设置border-button为true。
<PressPopupPlus
v-if="show"
:close-icon="true"
:arrow-icon="false"
:border-button="true"
:title="title"
button="确定"
@confirm="confirm"
@cancel="cancel"
>
<div class="content">
一些内容
</div>
</PressPopupPlus>
# 横版
设置horizontal为true。
<PressPopupPlus
v-if="show"
:close-icon="true"
:horizontal="true"
:width-number="54"
:title="title"
@confirm="confirm"
@cancel="cancel"
>
<div class="content">
一些内容
</div>
</PressPopupPlus>
# 使用slot
<PressPopupPlus
v-if="show"
:close-icon="true"
:horizontal="true"
:width-number="54"
:title="title"
@confirm="confirm"
@cancel="cancel"
>
<PressIcon
slot="icon"
name="gem-o"
size="22px"
/>
<div slot="title">
{{ t('wayToWin') }}
<PressIcon
name="like-o"
size="16"
/>
</div>
<PressIcon
slot="button"
name="setting-o"
size="22px"
/>
<div class="content">
{{ t('SomeContent') }}
</div>
</PressPopupPlus>
# 异步关闭
可传入asyncConfirm、asyncCancel方法控制异步关闭,如果返回false或Promise<false>则不会关闭popup。
<PressPopupPlus
:close-icon="false"
:arrow-icon="false"
:button="t('confirm')"
:async-confirm="asyncConfirm"
:async-close="asyncCancel"
>
<div class="content">
{{ t('SomeContent') }}
</div>
</PressPopupPlus>
export default {
methods: {
asyncConfirm() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, 500);
});
},
asyncCancel() {
return false;
},
}
}
注意在小程序平台,asyncConfirm 和 asyncCancel 的 this 执向有问题。
let that = null;
export default {
data() {
that = this;
return {}
},
methods: {
asyncConfirm() {
// 小程序中回调 this 是子组件
return that.isAuthenticationPopup;
},
}
}
# 受控组件
press-popup-plus与press-popup展示逻辑有很大不同,press-popup-plus为受控组件,show 默认为false。外界传 true时,展示进入动画,外界传false时,展示退出动画。
- 展示:组件外=> 组件内,
show属性:false => true,enter - 关闭:组件内 => 组件外 => 组件内,触发
close事件,组件外手动处理show = false,并传给组件内,才能关闭,show:true => false,leave
这种处理方式有以下好处:
- 不用在组件内声明额外关于
show的变量 - 不用关心异步操作,当外部不想关闭时,不设置
show为false即可。
press-popup由于历史原因,isShow属性(对应press-popup-plus的show)默认为true,且点击cancel、confirm时会关闭popup,大量业务这样使用:
v-if控制显示,要隐藏时再传入isShow = false,或者this.$refs.container.clickCancel()
为什么不用v-if设为false时来退出popup呢,因为这样退出动画就没了。
这种方式增加了开发者的心智负担,声明了额外属性,调用了内部不稳定的方法(可能更改或废弃)。
为了使用更简单,同时兼容历史代码,popup内部做了一些优化,推荐用这种方式使用(v0.7.35之后):
<PressPopupPlus
:is-show="show"
button="确认"
title="受控组件"
@confirm="show = false"
@cancel="show = false"
>
<div class="content">
{{ t('SomeContent') }}
</div>
</PressPopupPlus>
show为true时,popup才显示,要关闭时,设置 show = false 即可.
对于异步操作,分为两种:
- 点击顶部
confirm、cancel按钮,可传入asyncConfirm、asyncCancel,这两种方法返回Promise<false>时不会关闭popup。 - 其他部分,用户自行校验,根据情况设置
show = false。
# 函数式调用
支持函数式调用,需要在页面下预埋组件,并指定mode为functional。
<press-popup-plus
:id="PRESS_PICKER_ID"
mode="functional"
>
<scroll-view
scroll-y
:style="{maxHeight: '200px', padding: '0 20px'}"
>
<div class="content__inner">
{{ t('SomeScrollContent') }}
</div>
<div class="content__inner">
{{ t('SomeScrollContent') }}
</div>
<div class="content__inner">
{{ t('SomeScrollContent') }}
</div>
</scroll-view>
</press-popup-plus>
export default {
methods: {
onShowFunctionalPicker() {
showFunctionalComponent.call(this, {
selector: `#${PRESS_PICKER_ID}`,
title: this.t('wayToWin'),
button: this.t('confirm'),
horizontal: false,
closeIcon: false,
arrowIcon: true,
borderButton: false,
customStyle: '',
}).then(() => {
this.onTip('confirm');
})
.catch(() => {
this.onTip('cancel');
});
},
}
}
.content__inner {
height: 200px;
}
# API
# PopupPlus Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| show-title | 是否显示标题 | boolean | true |
| title | 弹窗标题 | string | - |
| button | 弹窗标题按钮 | string | - |
| border-button | 标题按钮是否为线型 | boolean | false |
| z-index | 弹窗层级 | string | 99 |
| popup-class | 类名 | string | - |
| close-on-click-overlay | 是否可以点击蒙版关闭 | boolean | true |
| close-icon | 是否显示关闭按钮 | boolean | false |
| arrow-icon | 是否显示为返回箭头 | boolean | false |
| horizontal | 是否切换横板样式 | boolean | false |
| width-number | 横板弹窗宽度百分比 | number | 100 |
| mode | 函数式调用时传functional | string | - |
| async-confirm | 异步confirm方法,可为Promise或普通方法 | function | - |
| async-cancel | 异步cancel方法,可为Promise或普通方法 | function | - |
| disabled-button | 按钮置灰 | boolean | false |
| lock-scroll | 是否锁定背景滚动 | boolean | true |
# PopupPlus Events
| 事件 | 说明 | 返回值 |
|---|---|---|
| cancel | 点击取消 | - |
| confirm | 点击确定 | - |
以下为废弃属性(v0.7.32):
| 类型 | 旧 | 新 |
|---|---|---|
| Prop | show-back-arrow | arrow-icon |
| Prop | is-showpopup-close | close-icon |
| Prop | is-show-title | show-title |
| Prop | is-cross-slab | horizontal |
| Prop | popup-title | title |
| Prop | popup-title-btn | button |
| Prop | is-border-btn | border-button |
| Prop | can-touch-remove | close-on-click-overlay |
| Event | onConfirm | confirm |
| Event | onCancel | cancel |
# PopupPlus Slot
| 名称 | 说明 |
|---|---|
| title | 顶部标题 |
| icon | 左侧图标位置内容 |
| button | 右侧按钮位置内容 |
# 在线调试
# 常见问题
- input 高度
transform后的position: fixed失效,对于popup中包含input输入框,且需要调整高度的场景,可以使用customStyle:
<press-popup-plus
:custom-style="`bottom: ${inputBottom}px;`"
>
</press-popup-plus>
- 内部元素滚动
press-popup 为了防止滚动穿透,在外层以及蒙层使用了 @touch.stop="noop"。如果内部元素需要滚动,可以使用 scroll-view,单纯设置元素 overflow: scroll 可能会在小程序下无效。可以参考上面“函数式调用”示例部分。
← PopoverPlus Common →