Trigger源码分析 – ant-design-vue系列
1 概述
源码地址: https://github.com/vueComponent/ant-design-vue/blob/main/components/vc-trigger/Trigger.tsx
在源码的实现中,Trigger组件主要有两个作用:
- 使用
Portal
组件,把Popup
组件传送到指定的dom
下,默认是body
。 - 为
target
节点绑定事件,控制事件的触发逻辑。
2 极简实现
为了实现以上功能,我们可以和源码一样,使用vue3
提供的Teleport
组件,来实现节点的传送;同时把所有事件进行透传即可。
在这里trigger
就是我们原先的target
节点,可以翻译成切换器。
setup(props, {
slots }) {
const align: any = computed(() => {
const {
placement } = props;
return placements[placement];
});
const getComponent = () => {
return (
<Popup
style={
{
position: 'absolute' }}
target={
() => triggerRef.value!}
align={
align.value}
visible={
props.visible}
>
{
slots.popup?.()}
</Popup>
);
};
const triggerRef = ref<HTMLElement>();
return () => {
// 1 Popup 部分
const portal = <Portal>{
getComponent()}</Portal>;
// 2 target部分
const trigger = (
<div style={
{
display: 'inline-block' }} ref={
triggerRef}>
{
slots.default?.()}
</div>
);
return (
<>
{
portal}
{
trigger}
</>
);
};
}
3 源码分析
3.1 整体结构
这个组件比较特殊,使用了选项式
的写法。
export default defineComponent({
name: 'Trigger',
mixins: [BaseMixin],
inheritAttrs: false, // 用于控制组件的根元素是否应该继承父作用域中的属性(attribute)和事件监听器(listener)。
porps: {
},
setup() {
}, // 使用props提供的响应式变量,这里是 定位&portal 相关的;并且声明了一些初始值
data() (), // 处理visible变量,为this挂载所有事件,尝试让PopupRef变量指向Portal
watch: (), // 监听visible的变化
created() {
}, // 依赖注入,提供vcTriggerContext和PortalContextKey上下文
deactivated() {
}, // 组件失活时,关闭popup弹窗
mounted() {
}, // 调用updatedCal(),这个函数的作用是在visible为true的时候,注册点击/滚动/失焦的相关事件,以便于在点击popup外部/页面滚动/窗口失焦的时候关闭弹窗;在visible为false时,移除事件监听。
updated() {
}, // 组件属性更新后调用updatedCal(),重新注册。
beforeUnmount() {
}, // 卸载前清除所有监听器
methods: {
}, // 事件的执行、事件是否绑定、获取组件的方法等
ren