Mask 遮罩层
17:06说明
全屏固定定位的遮罩层,用于强调特定元素并拦截下层交互。节点常驻不卸载,显隐由 visibility + opacity 的类通道切换,关闭时保留可见窗口播完淡出(及内容缩放)再收回;组件不自带关闭逻辑,show 由页面控制。
兼容性
| 平台 | 支持情况 |
|---|---|
| App | ✅ 支持(HarmonyOS 端 duration 不生效,固定用样式表基础值 300ms) |
| H5 | ✅ 支持 |
| 微信小程序 | ✅ 支持 |
示例
基础用法
点击按钮弹出遮罩,点击遮罩区域关闭。
查看源码
vue
<template>
<ux-button type="primary" @click="showMask">显示遮罩</ux-button>
<ux-mask :show="show" :zoom="zoom" @click="closeMask"></ux-mask>
</template>
<script setup lang="uts">
const show = ref<boolean>(false);
const zoom = ref<boolean>(true);
function showMask(): void {
show.value = true;
}
function closeMask(): void {
show.value = false;
}
</script>缩放效果 zoom
zoom=true 时内容带缩放动画(打开由 0.8 放大到 1,关闭由 1 缩回 0.8;遮罩背景不缩放),zoom=false 时无缩放。
查看源码
vue
<template>
<view class="btn-wrap">
<ux-button :type="zoom ? 'primary' : 'default'" custom-class="btn-item" @click="setZoom(true)">开启缩放</ux-button>
<ux-button :type="!zoom ? 'primary' : 'default'" custom-class="btn-item" @click="setZoom(false)">关闭缩放</ux-button>
</view>
<ux-mask :show="show" :zoom="zoom" @click="closeMask"></ux-mask>
</template>
<script setup lang="uts">
const show = ref<boolean>(false);
const zoom = ref<boolean>(true);
function setZoom(val: boolean): void {
zoom.value = val;
show.value = true;
}
function closeMask(): void {
show.value = false;
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>内容填充
通过默认插槽在遮罩内填充自定义内容,点击内容不会关闭遮罩。
查看源码
vue
<template>
<ux-button type="primary" @click="showContent">显示内容</ux-button>
<ux-mask :show="show" @click="closeMask">
<view class="wrap">
<view class="rect">
<text class="rect-text">自定义内容</text>
</view>
</view>
</ux-mask>
</template>
<script setup lang="uts">
const show = ref<boolean>(false);
function showContent(): void {
show.value = true;
}
function closeMask(): void {
show.value = false;
}
</script>
<style scoped>
.wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
.rect {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 240px;
height: 240px;
background-color: #ffffff;
border-radius: 8px;
}
.rect-text {
font-size: 14px;
color: #606266;
}
</style>动画时长 duration
通过 duration 设置遮罩显隐动画时长,单位毫秒。
查看源码
vue
<template>
<view class="btn-wrap">
<ux-button v-for="(item, index) in durationList" :key="index" :type="duration == item.value ? 'primary' : 'default'" custom-class="btn-item" @click="setDuration(item.value)">{{ item.label }}</ux-button>
</view>
<ux-mask :show="show" :duration="duration" @click="closeMask"></ux-mask>
</template>
<script setup lang="uts">
const show = ref<boolean>(false);
const duration = ref<number>(300);
const durationList = [
{ value: 100, label: '100ms' },
{ value: 300, label: '300ms' },
{ value: 800, label: '800ms' }
];
function setDuration(val: number): void {
duration.value = val;
show.value = true;
}
function closeMask(): void {
show.value = false;
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>不可点击关闭 mask-click-able
mask-click-able=false 时点击遮罩不会关闭,需通过内容中的按钮关闭。
查看源码
vue
<template>
<ux-button type="primary" @click="showNotClickable">显示遮罩</ux-button>
<ux-mask :show="show" :mask-click-able="false" @click="closeMask">
<view class="wrap">
<view class="rect" @click.stop>
<text class="rect-text">点击遮罩无法关闭</text>
<ux-button size="small" type="primary" @click="closeMask">关闭</ux-button>
</view>
</view>
</ux-mask>
</template>
<script setup lang="uts">
const show = ref<boolean>(false);
function showNotClickable(): void {
show.value = true;
}
function closeMask(): void {
show.value = false;
}
</script>
<style scoped>
.wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
.rect {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 240px;
height: 240px;
background-color: #ffffff;
border-radius: 8px;
}
.rect-text {
font-size: 14px;
color: #606266;
margin-bottom: 16px;
}
</style>API
Props
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
customStyle | 自定义根节点样式 | string | UTSJSONObject | - | - |
customClass | 自定义根节点样式类 | string | '' | - |
show | 是否显示遮罩 | boolean | false | - |
zIndex | 层级 z-index | string | number | '' | - |
zoom | 是否使用 scale 对内容层进行缩放(遮罩背景不缩放) | boolean | true | - |
duration | 遮罩的过渡时间,单位为 ms | string | number | 300 | - |
maskClickAble | 是否可以通过点击遮罩进行关闭 | boolean | true | - |
Events
| 事件名 | 说明 | 回调参数 | 版本 |
|---|---|---|---|
click | maskClickAble为true时,点击遮罩发送此事件 | - | - |
Slots
| 插槽名 | 说明 | 版本 |
|---|---|---|
default | 遮罩内容,撑满整个遮罩层;内容区加 @click.stop 可避免点击内容触发遮罩的 click | - |
注意事项
- 组件不自带关闭逻辑:把
show置为false只会播放淡出/缩小过渡,显示状态需页面自行维护;@click仅派发事件,不回写show。 mask-click-able=false时点击遮罩连click事件都不会派发(不只是"不关闭"),需靠内容区按钮自行关闭,示例即为此写法。zoom只作用于内容层,遮罩背景不缩放;关闭时内容由scale(1)缩回scale(0.8)。- 遮罩为
position: fixed且内部阻止touchmove,显示期间下层页面不会滚动。 - 遮罩节点常驻不卸载:关闭后由主 + 兜底双定时器在过渡播完后收回可见窗口,快速反切会清理旧定时器。
z-index留空取全局遮罩层级($u.zIndex.mask),多个遮罩同屏时用它控制叠放顺序。duration在 HarmonyOS 端不生效:内联下发被#ifndef APP-HARMONY排除,固定使用样式表基础值 300ms。