一、目标
模仿vue-lazyload插件
只需将img标签的src属性名替换为自定义属性v-lazy,即可实现图片懒加载功能
例如:
二、实现
不清楚图片懒加载原理的参考我的上一篇博客
1.封装自定义插件:暴露一个对象,包含一个install方法
先介绍一下自定义插件使用方法和通用写法:
// main.js
import createApp from 'vue';
import App from './App.vue';
import MyPlugin from './myPlugin ';
const app = createApp(App);
// 使用插件 传入一个对象作为配置项
app.use(MyPlugin, {
myProperty: 'some value'
});
app.mount('#app');
// myPlugin.js
export default {
// 插件安装时调用 接收参数:Vue实例对象和配置项
install(Vue, options) {
// 添加全局指令
Vue.directive('my-directive', {
bind(el, binding) {
// 指令逻辑
}
// 可以添加更多的钩子函数,如 inserted, update, componentUpdated 和 unbind
});
// 添加全局方法
Vue.prototype.$myMethod = function() {
// 方法逻辑
};
// 添加全局属性
Vue.prototype.$myProperty = options.myProperty
}
};
2.利用交叉观察器Intersection Observer实现图片懒加载
main.js引入插件
// main.js
import createApp from 'vue';
import App from './App.vue';
import lazyPlugin from './lazyPlugin';
const app = createApp(App);
// 使用插件 传入一个对象作为配置项
app.use(lazyPlugin);
app.mount('#app');
定义插件,编写install函数
//lazyPlugin.js
export default {
install(Vue){
//自定义指令(指令名,回调函数)
//回调函数包含参数 el:绑定该指令的DOM元素(img元素) | binding:属性值(img的url)
Vue.directive('lazy',(el,binding)=>{
//编写回调函数 接收参数entries:被观察元素组成的数组
const callback = (entries)=>{
entries.forEach(entry=>{
//若与视口发生交叉
if(entry.isIntersecting){
el.src = binding.value;
observer.unobserve(el);
}
})
}
//构造观察器
const observer = new IntersectionObserver(callback)
observer.observe(el);
})
}
}