1.使用自定义指令配合vueuse中的useIntersectionObserver
(0) 给需要添加图片懒加载效果的图片加上 v-lazy=“图片路径”,不用写src属性了。
(1) 执行npm install useIntersectionObserver -S
(2) 在directives目录下创建一个文件,这里我创建的是lazy.ts,代码如下:
import { useIntersectionObserver } from "@vueuse/core";
export const lazyPlugin = {
install(app) {
app.directive("lazy", {
async mounted(el, binding) {
// 选择一张图片作为图片懒加载的默认图片
let def = await import("../assets/vue.svg");
el.src = def.default;
// useIntersectionObserver函数的第一个参数是要侦视的元素,第二个参数是一个回调函数,函数的参数entries是一个只有一个元素的数组,元素中有一个属性isIntersecting为布尔值,true表示正在相交,此时需要从useIntersectionObserver函数返回值中解构出stop函数,用于停止侦视。
let { stop } = useIntersectionObserver(el, (entries) => {
if (entries[0].isIntersecting) {
el.src = binding.value;
stop();
}
});
},
});
},
};
(3) 在main.ts中,引入并注册插件
import { createApp } from "vue";
import App from "./App.vue";
import { lazyPlugin } from "@/directives/lazy";
const app = createApp(App);
app.use(lazyPlugin);
app.mount("#app");
2.使用自定义指令配合IntersectionObserver构造函数
(0) 给需要添加图片懒加载效果的图片加上 v-lazy=“图片路径”,不用写src属性了。
(1) 在App.vue中,和上面的写法本质都是通过IntersectionObserver构造函数实现的,代码如下
let vLazy = async (el, binding) => {
let def = await import("@/assets/vue.svg");
el.src = def.default;
let observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
el.src = binding.value;
// 停止侦视
observer.unobserve(el);
}
});
// 开始侦视
observer.observe(el);
};
注:这种写法要注意声明的函数名称,自定义指令要写成camelCase写法,而函数名要写成kebab-case写法,如自定义指令为v-lazy,函数名就必须要写成vLazy,自定义指令为v-lazy-load,函数名就必须要写成vLazyLoad。