基于vue指令实现监听dom的宽高是否发生变化,也可监听dom其他的属性变化
背景
resize方法只在window下有用,但是很多时候我们需要去判断当前的容器是否大小有改变,大小的改变需要触发一些显示操作,例如我的场景是一个tag-view,需要在超出时隐藏tag,并且显示左右翻页按钮
中间容器的宽度发生变化时,需要去计算是否出现左右翻页按钮
实现思路
其实为什么resize方法只在window有用而不是每个dom都具备,个人认为是resize应该是基于定时器实现的,所以一个视窗只针对窗口去做这个定时监听判断,如果给每个dom都去加上,意味着有多少dom层级就会有多少个定时器,很明显是很消耗内存的,并不现实 所以当前这个实现我们就通过定时器来做的 vue的指令在创建时会传递当前的el和绑定的值进去,所以基于这个,我在创建指令的时候,定义了一个定时器,将这个定时器绑定在了el上,再记录住一份当前的宽高值,每次定时器去查询当前的el的宽高值是否和记录的值一致,一致则不处理,当值发生变化时,触发指令绑定的方法 当指令销毁时,清除当前绑定的定时器
代码
我这个是根据Vue3写的,vue2的更改一下钩子就ok了
// 宽高或内容滚动宽高发生变化指令
import { Directive } from 'vue';
export const resize: Directive = {
mounted(el, binding) {
el.reSizeValue = el.reSizeValue || {
clientWidth: 0,
scrollWidth: 0, // 因为自身业务的需要,我还判断了里面滚动内容宽高的变化,这些参数自己根据需要去操作
clinetHeight: 0,
scrollHeight: 0,
interval: null,
};
function isReize() {
const { clientWidth, scrollWidth, clinetHeight, scrollHeight } = el;
if (
clientWidth !== el.reSizeValue.clientWidth ||
scrollWidth !== el.reSizeValue.scrollWidth ||
clinetHeight !== el.reSizeValue.clinetHeight ||
scrollHeight !== el.reSizeValue.scrollHeight
) {
el.reSizeValue.clientWidth = clientWidth;
el.reSizeValue.scrollWidth = scrollWidth;
el.reSizeValue.clinetHeight = clinetHeight;
el.reSizeValue.scrollHeight = scrollHeight;
binding.value(); // 可以自己带参数出去
}
}
el.reSizeValue.interval = setInterval(isReize, 300);
},
unmounted(el) {
clearInterval(el.reSizeValue.interval);
},
};
转载自:https://juejin.cn/post/7057441659780333598