一、目标
模仿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);})}
}