vue3+typescript实现图片懒加载插件
(编辑:jimmy 日期: 2025/10/26 浏览:3 次 )
github项目地址: github.com/murongg/vue…
求star 与 issues
我文采不好,可能写的文章不咋样,有什么问题可以在留言区评论,我会尽力解答
本项目已经发布到npm
安装:
$ npm i vue3-lazyload # or $ yarn add vue3-lazyload
需求分析
- 支持自定义 loading 图片,图片加载状态时使用此图片
- 支持自定义 error 图片,图片加载失败后使用此图片
- 支持 lifecycle hooks,类似于 vue 的生命周期,并同时在
img标签绑定lazy属性,类似于
<img src="/UploadFiles/2021-04-02/...">并支持:
img[lazy=loading] { /*your style here*/ } img[lazy=error] { /*your style here*/ } img[lazy=loaded] { /*your style here*/ }支持使用
v-lazy自定义指令,指定可传入 string/object ,当为 string 时,默认为需要加载的 url,当为 object 时,可传入
src: 当前需要加载的图片 urlloading: 加载状态时所用到的图片error: 加载失败时所用到的图片lifecycle: 本次 lazy 的生命周期,替换掉全局生命周期
目录结构
- src ---- index.ts 入口文件,主要用来注册插件 ---- lazy.ts 懒加载主要功能 ---- types.ts 类型文件,包括 interface/type/enum 等等 ---- util.ts 共享工具文件
编写懒加载类
懒加载主要通过 IntersectionObserver对象实现,可能有些浏览器不支持,暂未做兼容。
确定注册插件时传入的参数
export interface LazyOptions {
error"_blank" href="https://v3.vuejs.org/guide/custom-directive.html#intro" rel="external nofollow" >Custom Directives,支持以下 Hook Functions:beforeMount 、mounted、beforeUpdate、updated、beforeUnmount、unmounted,具体释义可以去 vue3 文档查看,目前仅需要用到mounted、updated、unmounted,这三个 Hook。
Lazy 类基础框架代码,lazy.ts:
export default class Lazy {
public options: LazyOptions = {
loading: DEFAULT_LOADING,
error: DEFAULT_ERROR,
observerOptions: DEFAULT_OBSERVER_OPTIONS,
log: true,
lifecycle: {}
};
constructor(options"htmlcode">
/**
* mount
*
* @param {HTMLElement} el
* @param {DirectiveBinding<string>} binding
* @memberof Lazy
*/
public mount(el: HTMLElement, binding: DirectiveBinding<string | ValueFormatterObject>): void {
this._image = el
const { src, loading, error, lifecycle } = this._valueFormatter(binding.value)
this._lifecycle(LifecycleEnum.LOADING, lifecycle)
this._image.setAttribute('src', loading || DEFAULT_LOADING)
if (!hasIntersectionObserver) {
this.loadImages(el, src, error, lifecycle)
this._log(() => {
throw new Error('Not support IntersectionObserver!')
})
}
this._initIntersectionObserver(el, src, error, lifecycle)
}
/**
* force loading
*
* @param {HTMLElement} el
* @param {string} src
* @memberof Lazy
*/
public loadImages(el: HTMLElement, src: string, error"htmlcode">
/**
* update
*
* @param {HTMLElement} el
* @memberof Lazy
*/
public update(el: HTMLElement, binding: DirectiveBinding<string | ValueFormatterObject>): void {
this._observer.unobserve(el)
const { src, error, lifecycle } = this._valueFormatter(binding.value)
this._initIntersectionObserver(el, src, error, lifecycle)
}
编写 unmount hook
/**
* unmount
*
* @param {HTMLElement} el
* @memberof Lazy
*/
public unmount(el: HTMLElement): void {
this._observer.unobserve(el)
}
在 index.ts 编写注册插件需要用到的 install 方法
import Lazy from './lazy'
import { App } from 'vue'
import { LazyOptions } from './types'
export default {
/**
* install plugin
*
* @param {App} Vue
* @param {LazyOptions} options
*/
install (Vue: App, options: LazyOptions): void {
const lazy = new Lazy(options)
Vue.config.globalProperties.$Lazyload = lazy
// 留着备用,为了兼容$Lazyload
// 选项api,可以通过this.$Lazyload获取到Lazy类的实例,组合api我还不知道怎么获取
// 所以通过 provide 来实现此需求
// 使用方式 const useLazylaod = inject('Lazyload')
Vue.provide('Lazyload', lazy)
Vue.directive('lazy', {
mounted: lazy.mount.bind(lazy),
updated: lazy.update.bind(lazy),
unmounted: lazy.unmount.bind(lazy)
})
}
}
使用插件
import { createApp } from 'vue'
import App from './App.vue'
import VueLazyLoad from '../src/index'
const app = createApp(App)
app.use(VueLazyLoad, {
log: true,
lifecycle: {
loading: () => {
console.log('loading')
},
error: () => {
console.log('error')
},
loaded: () => {
console.log('loaded')
}
}
})
app.mount('#app')
App.vue:
<template>
<div class="margin" />
<img v-lazy="'/example/assets/logo.png'" alt="Vue logo" width="100">
<img v-lazy="{src: errorlazy.src, lifecycle: errorlazy.lifecycle}" alt="Vue logo" class="image" width="100">
<button @click="change">
change
</button>
</template>
<script>
import { reactive } from 'vue'
export default {
name: 'App',
setup() {
const errorlazy = reactive({
src: '/example/assets/log1o.png',
lifecycle: {
loading: () => {
console.log('image loading')
},
error: () => {
console.log('image error')
},
loaded: () => {
console.log('image loaded')
}
}
})
const change = () => {
errorlazy.src = 'http://t8.baidu.com/it/u=3571592872,3353494284&fm=79&app=86&size=h300&n=0&g=4n&f=jpeg?sec=1603764281&t=bedd2d52d62e141cbb08c462183601c7'
}
return {
errorlazy,
change
}
}
}
</script>
<style>
.margin {
margin-top: 1000px;
}
.image[lazy=loading] {
background: goldenrod;
}
.image[lazy=error] {
background: red;
}
.image[lazy=loaded] {
background: green;
}
</style>
以上就是vue3+typescript实现图片懒加载插件的详细内容,更多关于vue3 图片懒加载的资料请关注其它相关文章!
上一篇:vue项目查看vue版本及cli版本的实现方式
下一篇:Ant Design的Table组件去除
在去年的5月23日,借助Intel Bridge Technology以及Intel Celadon两项技术的驱动,Intel为PC用户带来了Android On Windows(AOW)平台,并携手国内软件公司腾讯共同推出了腾讯应用宝电脑版,将Windows与安卓两大生态进行了融合,PC的使用体验随即被带入到了一个全新的阶段。