Vue 3 指令——如何将项目数组推送到指令

Vue 3 directives – how to push array of items to directive

由于 Vue 3 没有 IntersectionObserver 库,我想实现自己的小解决方案。

我阅读了指令,据我了解这是正确的方向。 (?)

我的本地指令:

directives: {
    'lazyload': {
      mounted(el) {
        if ('IntersectionObserver' in window) {        
          let intersectionObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach((entry) => {
              if (entry.isIntersecting) {
                const lazyImage = entry.target;
                
                // set data-srcset as image srcset
                lazyImage.srcset = lazyImage.getAttribute('data-srcset');
                
                // add class after image has loaded
                lazyImage.addEventListener('load', () => {
                  lazyImage.classList.add('is-lazyloaded');
                };
                // unobserve after
                lazyLoadItemObserver.unobserve(lazyImage);
              }
            });
          });
          
          // observe every image
          const lazyLoadItems = document.querySelectorAll('[lazyload]')
          
          lazyLoadItems.forEach((lazyImage) => {
            lazyLoadItemObserver.observe(lazyImage);
          });
  
        }
      }
    }
  }

普通的方法是用每个 <IMG> 元素创建一个数组,例如 attribute lazyload。我不明白的是如何从每个具有 v-lazyload 绑定的 <IMG> 中创建一个数组。

类似于“如果此图像具有 v-lazyload 绑定,请将其放入 IntersectionObserver 的数组中。”不过我可能理解错了。

所以我想提出一个指令,它设置一个单一的 IntersectionObserver,它观察具有 v-lazyload 绑定的所有图像的数组。

v-lazyload 指令已经在目标元素上,因此无需查询文档。

在指令的 mounted 挂钩中,您可以将 IntersectionObserver 实例附加到父节点(如果它尚不存在)。然后,使用该实例观察目标元素(也取消观察 unmounted 中的元素):

directives: {
  mounted(el) {
    el.parentNode.lazyLoadItemObserver = el.parentNode.lazyLoadItemObserver || new IntersectionObserver(/*...*/)
    el.parentNode.lazyLoadItemObserver.observe(el)
  },
  unmounted(el) {
    el.parentNode.lazyLoadItemObserver.unobserve(el)
  },
}

demo