likes
comments
collection
share

基于vue指令实现监听dom的宽高是否发生变化,也可监听dom其他的属性变化

作者站长头像
站长
· 阅读数 15

背景

resize方法只在window下有用,但是很多时候我们需要去判断当前的容器是否大小有改变,大小的改变需要触发一些显示操作,例如我的场景是一个tag-view,需要在超出时隐藏tag,并且显示左右翻页按钮

基于vue指令实现监听dom的宽高是否发生变化,也可监听dom其他的属性变化 中间容器的宽度发生变化时,需要去计算是否出现左右翻页按钮

实现思路

其实为什么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);
  },
};