记录一次通过ChatGPT帮我写了一个resize指令

lxf2023-04-12 20:15:02

记录一次通过ChatGPT帮我写了一个resize指令

记录一次通过ChatGPT帮我写了一个resize指令

记录一次通过ChatGPT帮我写了一个resize指令 最终代码如下:

import { DirectiveBinding } from 'vue';

// 用于存储 DOM 元素和 ResizeObserver 实例之间的映射关系
const resizeObservers = new WeakMap();

function handleResize(el: HTMLElement, binding: DirectiveBinding): void {
  const onResize = binding.value;

  let observer = resizeObservers.get(el);
  if (!observer) {
    // 如果当前元素上不存在 ResizeObserver 实例,则创建一个新的实例并进行监听
    observer = new ResizeObserver((entries) => {
      const entry = entries[0];
      const width = Math.round(entry.contentRect.width);
      const height = Math.round(entry.contentRect.height);
      onResize({ width, height });
    });

    observer.observe(el);

    resizeObservers.set(el, observer);
  } else {
    // 如果当前元素上已经存在 ResizeObserver 实例,则更新回调函数
    observer.disconnect();
    observer = new ResizeObserver((entries) => {
      const entry = entries[0];
      const width = Math.round(entry.contentRect.width);
      const height = Math.round(entry.contentRect.height);
      onResize({ width, height });
    });
    observer.observe(el);

    resizeObservers.set(el, observer);
  }
}

function removeResize(el: HTMLElement): void {
  const observer = resizeObservers.get(el);
  if (observer && observer.disconnect) {
    observer.disconnect();
    resizeObservers.delete(el);
  }
}

export default {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    handleResize(el, binding);
  },
  updated(el: HTMLElement, binding: DirectiveBinding) {
    handleResize(el, binding);
  },
  unmounted(el: HTMLElement) {
    removeResize(el);
  },
};

在上述示例代码中,我们使用了一个 WeakMap 对象 resizeObservers 来保存 DOM 元素和 ResizeObserver 实例之间的映射关系。在指令的 mounted 钩子函数中,我们首先尝试从 resizeObservers 中获取当前元素的 ResizeObserver 实例。如果不存在,则创建一个新的实例,并进行监听;如果已经存在,则直接更新回调函数即可。

在指令的 updated 钩子函数中,我们也直接调用 handleResize 函数进行处理,该函数会自动判断是否已经存在 ResizeObserver 实例并进行相应的更新操作。

在指令的 unmounted 钩子函数中,我们同样需要将当前元素上的 ResizeObserver 实例卸载,并从 resizeObservers 中删除对应的键值对。

对于每个需要使用 v-resize 指令的组件,我们只需要像下面这样在模板中使用即可:

<template>
  <div v-resize="onResize">...</div>
</template>

<script>
export default {
  methods: {
    // 处理元素大小变化的回调函数
    onResize({ width, height }) {
      console.log(`width: ${width}, height: ${height}`);
    },
  },
};
</script>

在上述示例代码中,我们传递了一个处理元素大小变化的回调函数 onResizev-resize 指令,并在该函数中进行相应的逻辑处理。