Skip to content

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是否显示遮罩booleanfalse-
zIndex层级 z-indexstring | number''-
zoom是否使用 scale 对内容层进行缩放(遮罩背景不缩放)booleantrue-
duration遮罩的过渡时间,单位为 msstring | number300-
maskClickAble是否可以通过点击遮罩进行关闭booleantrue-

Events ​

事件名说明回调参数版本
clickmaskClickAble为true时,点击遮罩发送此事件--

Slots ​

插槽名说明版本
default遮罩内容,撑满整个遮罩层;内容区加 @click.stop 可避免点击内容触发遮罩的 click-

注意事项 ​

  1. 组件不自带关闭逻辑:把 show 置为 false 只会播放淡出/缩小过渡,显示状态需页面自行维护;@click 仅派发事件,不回写 show。
  2. mask-click-able=false 时点击遮罩连 click 事件都不会派发(不只是"不关闭"),需靠内容区按钮自行关闭,示例即为此写法。
  3. zoom 只作用于内容层,遮罩背景不缩放;关闭时内容由 scale(1) 缩回 scale(0.8)。
  4. 遮罩为 position: fixed 且内部阻止 touchmove,显示期间下层页面不会滚动。
  5. 遮罩节点常驻不卸载:关闭后由主 + 兜底双定时器在过渡播完后收回可见窗口,快速反切会清理旧定时器。
  6. z-index 留空取全局遮罩层级($u.zIndex.mask),多个遮罩同屏时用它控制叠放顺序。
  7. duration 在 HarmonyOS 端不生效:内联下发被 #ifndef APP-HARMONY 排除,固定使用样式表基础值 300ms。