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 图片懒加载的资料请关注其它相关文章!
极乐门资源网 Design By www.ioogu.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]