Popup源码分析 – ant-design-vue系列
1 极简代码
直接返回两个组件:Mask
和 PopupInner
,后者在上一篇已经分析过了。下面我们先看一下 Mask
的源码。
setup(props, { slots }) {
return () => {
if (!props.visible) return null;
return (
<div class="v-popup">
{/* <Mask visible /> */}
<PopupInner target={props.target} align={props.align} visible>
{slots.default?.()}
</PopupInner>
</div>
);
};
}
2 Mask源码
这是一个函数式组件,处理过程比较简单,只是调用getMotion
获取了动画类名,给到Transition
组件使用。
但是由于mask
变量在Trigger
中的默认值是false
,在Popup
中也没有单独处理,所以在这里,mask === false
,也就是说dropdown
没有Mask
蒙层。所以在极简代码中也是注释掉的。
export default function Mask(props: MaskProps) {
const { prefixCls, visible, zIndex, mask, maskAnimation, maskTransitionName } = props;
// 这里的mask是false
if (!mask) {
return null;
}
let motion = {};
if (maskTransitionName || maskAnimation) {
motion = getMotion({
prefixCls,
transitionName: maskTransitionName,
animation: maskAnimation,
});
}
return (
<Transition appear {...motion}>
<div v-if={visible} style={{ zIndex }} class={`${prefixCls}-mask`} />
</Transition>
);
}
- 我们可以找到modal的蒙层,看一下蒙层的css是如何实现的。
绝对定位 + 层级 + 高度 + 背景色
.ant-modal-mask {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1000;
height: 100%;
background-color: rgba(0, 0, 0, 0.45);
}
3 Popup源码
我们把有关mobile的判断去掉,剩下的就是下面的代码。可以看到,因为Mask
组件是null
,所以几乎就是直接渲染了PopupInner
组件。
需要注意的是,这里重新声明了innerVisible
,并且监听props.visible
时使用了 flush: 'post'
。这些都是为了让动画延迟执行。涉及到动画的地方都是这样处理的。
setup(props, { attrs, slots, expose }) {
const innerVisible = ref(false);
const popupRef = ref();
watch(
() => props.visible,
() => {
innerVisible.value = props.visible;
},
{ immediate: true, flush: 'post' },
);
expose({
forceAlign: () => {
popupRef.value?.forceAlign();
},
getElement: () => {
return popupRef.value?.getElement();
},
});
return () => {
const cloneProps = { ...props, ...attrs, visible: innerVisible.value };
return (
<div>
<Mask {...cloneProps} />
<PopupInner {...cloneProps} ref={popupRef} v-slots={{ default: slots.default }} />
</div>
);
};
},
4 总结
Popup
组件到这里就结束了,再来看一下这个整理结构。可以看到:
Popup
作用主要是整合Mask
和PopupInner
。PopupInne
r主要是定义了动画。Align
作用是执行target
和source
的对齐操作。