Vue3的自定义指令怎么迁移到nuxt3

一、找到Vue3中指令的源码

const DISTANCE = 100; // 距离
const ANIMATIONTIME = 500; // 500毫秒
let distance: number | null = null,
  animationtime: number | null = null;
const map = new WeakMap();
const ob = new IntersectionObserver((entries) => {
  for (const entrie of entries) {
    if (entrie.isIntersecting) {
      const animation = map.get(entrie.target);
      if (animation) {
        animation.play();
        ob.unobserve(entrie.target);
      }
    }
  }
});

function isBelowViewport(el: HTMLElement) {
  const rect = el.getBoundingClientRect();
  return rect.top - (distance || DISTANCE) > window.innerHeight;
}

export default {
  mounted(el: HTMLElement, binding: any) {
    if (binding.value) {
      // console.log(binding.value);
      distance = binding.value.px;
      animationtime = binding.value.time;
    }
    if (!isBelowViewport(el)) {
      return;
    }
    const animation = el.animate(
      [
        {
          opacity: 0,
          transform: `translateY(${distance || DISTANCE}px)`,
        },
        {
          opacity: 1,
          transform: `translateY(0px)`,
        },
      ],
      {
        duration: animationtime || ANIMATIONTIME,
        fill: "forwards",
        easing: "ease-in-out",
      }
    );
    animation.pause();
    map.set(el, animation);
    ob.observe(el);
  },

  unmounted(el:HTMLElement) {
    ob.unobserve(el);
  },
};

二、源码迁移到nuxt3

存放目录为指定的的plugins文件夹,没有这个文件夹自己新建
然后新建一个文件xx.ts用于存放修改之后的指令代码, 我这里使用toTop.ts
所以路径是 plugins/toTop.ts 下面是文件内容

const DISTANCE = 100; // 距离
const ANIMATIONTIME = 500; // 500毫秒
let distance: number | null = null,
  animationtime: number | null = null;
const map = new WeakMap();
const ob =
  process.client &&
  new IntersectionObserver((entries) => {
    for (const entrie of entries) {
      if (entrie.isIntersecting) {
        const animation = map.get(entrie.target);
        if (animation) {
          animation.play();
          ob.unobserve(entrie.target);
        }
      }
    }
  });

function isBelowViewport(el: HTMLElement) {
  const rect = el.getBoundingClientRect();
  return rect.top - (distance || DISTANCE) > window.innerHeight;
}

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.directive("top", {
    mounted(el, binding) {
      if (binding.value) {
        // console.log(binding.value);
        distance = binding.value.px;
        animationtime = binding.value.time;
      }
      if (!isBelowViewport(el)) {
        return;
      }
      const animation = el.animate(
        [
          {
            opacity: 0,
            transform: `translateY(${distance || DISTANCE}px)`,
          },
          {
            opacity: 1,
            transform: `translateY(0px)`,
          },
        ],
        {
          duration: animationtime || ANIMATIONTIME,
          fill: "forwards",
          easing: "ease-in-out",
        }
      );
      animation.pause();
      map.set(el, animation);
      ob.observe(el);
    },
    unmounted(el: HTMLElement) {
      ob.unobserve(el);
    },
    getSSRProps(binding, vnode) {
      // 你可以在这里提供SSR特定的props
      return {};
    },
  });
});

三、注册指令

在 nuxt.config.ts 文件中


export default defineNuxtConfig({
 // ...其他配置
  plugins: ["/plugins/toTop.ts"],
 // ...其他配置
});

参考的官方文档

地址

在这里插入图片描述