组件结构
dropdown
组件对参数做了一些处理,然后直接调用了vc-trigger
组件来进行渲染,先看一下整体的组件调用结构。
极简实现
这个组件需要满足以下几个基本的功能:
- 可以传入两个插槽
default
和popup
,default
是默认展示的节点,点击后可以弹出popup
。 popup
可以指定在文档中的位置,默认是插入到body
节点下面。popup
可以相对于default
来进行定位。
效果如下:
同时,popup
也插入到了body
节点下面。
简易代码
先看一下整体的数据流转过程,用户传入的两个插槽是如何渲染到页面中的。这两个查擦的传递过程需要仔细看一下。
接下来逐步解释一下从底层到上层的代码。
Align.tsx
- 用户传入的信息就是
default
插槽的内容,给它套一个div
节点,用来获取引用,方便定位。
return () => {
const child = slots.default?.();
if (child) {
return <div ref={nodeRef}>{child}</div>;
}
return null;
};
- 当组件挂载或者挂载位置变化的时候,调用对齐的方法。
onMounted(() => {
align();
});
watch(
() => [props.align, props.target],
() => {
align();
},
{ immediate: true, deep: true, flush: 'post' }
);
- 上面用到了一个方法
align
,这个方法的主要作用就是让用户传入的default
节点和target
对齐。target
是props
传入的节点;default
被手动加的一层div
包裹,通过ref
来进行代理。
import { alignElement } from 'dom-align';
const nodeRef = ref<HTMLElement | null>(null);
const align = () => {
if (!nodeRef.value) return;
const { align: latestAlign, target: latestTarget } = props;
let result: any;
let targetElement: HTMLElement | null = null;
if (typeof latestTarget === 'function') {
targetElement = latestTarget();
}
if (targetElement && targetElement.nodeType === Node.ELEMENT_NODE) {
result = alignElement(nodeRef.value, targetElement, latestAlign);
}
};
标签:vue,return,popup,dropdown,default,align,源码,props,const
From: https://blog.csdn.net/weixin_44438233/article/details/141955068