{"_id":"@code-killer/vue-lazy-load","_rev":"5-d617e47afb35843520826354c1be2d25","name":"@code-killer/vue-lazy-load","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.0":{"name":"@code-killer/vue-lazy-load","version":"1.0.0","keywords":["vue","vue3","lazy-load","intersection-observer","image","directive","v-lazy"],"author":{"name":"nature-tr"},"license":"MIT","_id":"@code-killer/vue-lazy-load@1.0.0","maintainers":[{"name":"dolmocheng","email":"2911107728@qq.com"}],"homepage":"https://github.com/nature-tr/test#readme","bugs":{"url":"https://github.com/nature-tr/test/issues"},"dist":{"shasum":"485c1a1f98a7db8d5cebfaca377957c935ab8dc7","tarball":"https://registry.npmjs.org/@code-killer/vue-lazy-load/-/vue-lazy-load-1.0.0.tgz","fileCount":4,"integrity":"sha512-q/LPZmc0BDiHtWmAPkS08wQ5w7JOSXjTIwMGwIjr//p+f7VxpGlDWXAFpWJjMOqzAg3eVIcMhYdGFd3cPeC7qw==","signatures":[{"sig":"MEYCIQCp72pnSkZbIYb1FXzDgjdi0FuI6yz16WUerjf6mji0DgIhAJ1yCYA8PNChqecHFZjFbzRhqlBThy8iujYONzf4JYBm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":7848},"main":"src/index.js","type":"module","module":"src/index.js","exports":{".":{"import":"./src/index.js"}},"gitHead":"be456af52057e7def5fca23b29c462a298723669","_npmUser":{"name":"dolmocheng","email":"2911107728@qq.com"},"repository":{"url":"git+https://github.com/nature-tr/test.git","type":"git","directory":"packages/vue-lazy-load"},"_npmVersion":"11.7.0","description":"Vue 3 图片懒加载指令插件，基于 IntersectionObserver + 内存缓存","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"vue":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vue-lazy-load_1.0.0_1772271124855_0.47965125554716703","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@code-killer/vue-lazy-load","version":"1.0.1","keywords":["vue","vue3","lazy-load","intersection-observer","image","directive","v-lazy"],"author":{"name":"nature-tr"},"license":"MIT","_id":"@code-killer/vue-lazy-load@1.0.1","maintainers":[{"name":"dolmocheng","email":"2911107728@qq.com"}],"homepage":"https://github.com/nature-tr/test#readme","bugs":{"url":"https://github.com/nature-tr/test/issues"},"dist":{"shasum":"5588b22eb7d870f517f05126d1727c6668d825a0","tarball":"https://registry.npmjs.org/@code-killer/vue-lazy-load/-/vue-lazy-load-1.0.1.tgz","fileCount":5,"integrity":"sha512-49FY0cFPQZWq3qbbC6k2A2TjmMZEODmxV/Oeax/1rJZzLnhZzQme1T9c2NpIgAsKY8m9qBGUPQOc75VFJhibMQ==","signatures":[{"sig":"MEUCIDvNhgY73i3cGU2qr6bJcST4HbmVCMQr0t4fDgkPdkTlAiEArwqKox/KAoUGJ7flORRo6sClZAIKoBq6ss+9iQYj6U4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9936},"main":"src/index.js","type":"module","module":"src/index.js","exports":{".":{"import":"./src/index.js"}},"gitHead":"be456af52057e7def5fca23b29c462a298723669","_npmUser":{"name":"dolmocheng","email":"2911107728@qq.com"},"repository":{"url":"git+https://github.com/nature-tr/test.git","type":"git","directory":"packages/vue-lazy-load"},"_npmVersion":"11.7.0","description":"Vue 3 图片懒加载指令插件，基于 IntersectionObserver + 内存缓存","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"vue":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vue-lazy-load_1.0.1_1772271775952_0.49761916267445705","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@code-killer/vue-lazy-load","version":"1.1.0","keywords":["vue","vue3","lazy-load","intersection-observer","image","directive","v-lazy","lru-cache","indexeddb","blob-cache"],"author":{"name":"nature-tr"},"license":"MIT","_id":"@code-killer/vue-lazy-load@1.1.0","maintainers":[{"name":"dolmocheng","email":"2911107728@qq.com"}],"homepage":"https://github.com/nature-tr/test#readme","bugs":{"url":"https://github.com/nature-tr/test/issues"},"dist":{"shasum":"f50873b68369af58417be9a3107a2422e3020819","tarball":"https://registry.npmjs.org/@code-killer/vue-lazy-load/-/vue-lazy-load-1.1.0.tgz","fileCount":5,"integrity":"sha512-tO1ZWhV1nJYVS4+4/mYI+xqTHx8zCizjDporb2+CgAZ4XQfx1PhHl+daflD4EQ5zPvA+/yvDO7FFnHjOg1mzaA==","signatures":[{"sig":"MEUCIQC6XdEAnPT3y8p2D2ccprqipqwKhxv3LnSnXkOWRZyFmwIgYCWADU54PJNgGjyDZhUW8s5YbURCVx6PF2RKuBYdHIs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19149},"main":"src/index.js","type":"module","module":"src/index.js","exports":{".":{"import":"./src/index.js"}},"gitHead":"0ef806073c97d0251b2c49f3a7596649f21ba27e","_npmUser":{"name":"dolmocheng","email":"2911107728@qq.com"},"repository":{"url":"git+https://github.com/nature-tr/test.git","type":"git","directory":"packages/vue-lazy-load"},"_npmVersion":"11.7.0","description":"Vue 3 图片懒加载指令插件，基于 IntersectionObserver + 两级缓存（LRU 内存 + IndexedDB 持久化）","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"vue":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vue-lazy-load_1.1.0_1772279744855_0.8101236335399371","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@code-killer/vue-lazy-load","version":"1.1.1","keywords":["vue","vue3","lazy-load","intersection-observer","image","directive","v-lazy","lru-cache","indexeddb","blob-cache"],"author":{"name":"nature-tr"},"license":"MIT","_id":"@code-killer/vue-lazy-load@1.1.1","maintainers":[{"name":"dolmocheng","email":"2911107728@qq.com"}],"homepage":"https://github.com/nature-tr/test#readme","bugs":{"url":"https://github.com/nature-tr/test/issues"},"dist":{"shasum":"3b5a7c4387f06037ad828beed7ecf320ecbb74b3","tarball":"https://registry.npmjs.org/@code-killer/vue-lazy-load/-/vue-lazy-load-1.1.1.tgz","fileCount":5,"integrity":"sha512-Zw/RgFhL4zu7ODRKaYWb7z/ldshGAchsceR4rrO4fYrCriIDolyRubokhid9wkfTcKl/umOfAgO8DlBO49aw7Q==","signatures":[{"sig":"MEQCIFqOKWzMqL2sX1M+KhQaMfKY5cz+MIm3NaqZ2F8S/WVFAiATDfy3tEFUO6bRpbkbMpvUM7aO5jhbms0G6WFtRQeYRA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19279},"main":"src/index.js","type":"module","module":"src/index.js","exports":{".":{"import":"./src/index.js"}},"gitHead":"d3db8c799ad4efe7fdd0380166f2a227f49b5c40","_npmUser":{"name":"dolmocheng","email":"2911107728@qq.com"},"repository":{"url":"git+https://github.com/nature-tr/test.git","type":"git","directory":"packages/vue-lazy-load"},"_npmVersion":"11.7.0","description":"Vue 3 图片懒加载指令插件，基于 IntersectionObserver + 两级缓存（LRU 内存 + IndexedDB 持久化）","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"vue":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vue-lazy-load_1.1.1_1772280099245_0.9897857544636883","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@code-killer/vue-lazy-load","version":"1.2.0","description":"Vue 3 图片懒加载指令插件，基于 IntersectionObserver + 两级缓存（LRU 内存 + IndexedDB 持久化）","type":"module","main":"src/index.js","module":"src/index.js","exports":{".":{"import":"./src/index.js"}},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/nature-tr/test.git","directory":"packages/vue-lazy-load"},"peerDependencies":{"vue":"^3.0.0"},"keywords":["vue","vue3","lazy-load","intersection-observer","image","directive","v-lazy","lru-cache","indexeddb","blob-cache"],"author":{"name":"nature-tr"},"license":"MIT","gitHead":"d3db8c799ad4efe7fdd0380166f2a227f49b5c40","_id":"@code-killer/vue-lazy-load@1.2.0","bugs":{"url":"https://github.com/nature-tr/test/issues"},"homepage":"https://github.com/nature-tr/test#readme","_nodeVersion":"22.14.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-92+LSiINrdyp9/6TksDg4QLysmTGdAiOapNRRJs2mfT8wKUU/YU+OUl/iqbz97LY7z4BFdS9RSpq9T7diVStGw==","shasum":"6f256ceef0092f9d35fd08ff98f761ac5fb10336","tarball":"https://registry.npmjs.org/@code-killer/vue-lazy-load/-/vue-lazy-load-1.2.0.tgz","fileCount":5,"unpackedSize":19279,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDU4RFgDyr7UJ7kvu91SjU0IIvH5iBTiOy2fpWRzkbOzQIgIv1ZMf6LfPrJmA3yvX4MhHuTN23UQLPZfc5EpeRlsG4="}]},"_npmUser":{"name":"dolmocheng","email":"2911107728@qq.com"},"directories":{},"maintainers":[{"name":"dolmocheng","email":"2911107728@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vue-lazy-load_1.2.0_1772280285945_0.8336425747292708"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-28T09:32:04.737Z","modified":"2026-02-28T12:04:46.234Z","1.0.0":"2026-02-28T09:32:04.993Z","1.0.1":"2026-02-28T09:42:56.096Z","1.1.0":"2026-02-28T11:55:44.992Z","1.1.1":"2026-02-28T12:01:39.396Z","1.2.0":"2026-02-28T12:04:46.105Z"},"bugs":{"url":"https://github.com/nature-tr/test/issues"},"author":{"name":"nature-tr"},"license":"MIT","homepage":"https://github.com/nature-tr/test#readme","keywords":["vue","vue3","lazy-load","intersection-observer","image","directive","v-lazy","lru-cache","indexeddb","blob-cache"],"repository":{"type":"git","url":"git+https://github.com/nature-tr/test.git","directory":"packages/vue-lazy-load"},"description":"Vue 3 图片懒加载指令插件，基于 IntersectionObserver + 两级缓存（LRU 内存 + IndexedDB 持久化）","maintainers":[{"name":"dolmocheng","email":"2911107728@qq.com"}],"readme":"# @code-killer/vue-lazy-load\n\nVue 3 图片懒加载指令插件，基于 IntersectionObserver + 两级缓存（LRU 内存 + IndexedDB 持久化）。\n\n## 特性\n\n- **IntersectionObserver 懒加载** — 图片进入视口时才加载，减少首屏请求\n- **两级缓存架构** — L1 内存 LRU Cache + L2 IndexedDB 持久化，刷新页面后仍可命中缓存\n- **LRU 淘汰策略** — L1 基于 Map 插入顺序实现 LRU，淘汰时自动 `URL.revokeObjectURL` 释放 Blob 内存\n- **IndexedDB 自动淘汰** — L2 超出上限时按 `accessedAt` 索引游标淘汰最久未访问的记录\n- **请求去重** — 多个 `<img>` 同时引用同一 URL，只发一次网络请求\n- **缓存命中零延迟** — 已缓存的图片同步赋值 src，无闪烁\n- **fallback 兜底图** — 主图加载失败自动切换到备用图\n- **全局配置** — 支持自定义 loading 占位图、error 占位图、预加载距离、缓存容量\n\n## 安装\n\n```bash\nnpm install @code-killer/vue-lazy-load\n```\n\n## 使用\n\n### 注册插件\n\n```js\nimport { createApp } from 'vue'\nimport { VueLazyLoad } from '@code-killer/vue-lazy-load'\nimport App from './App.vue'\n\nconst app = createApp(App)\n\napp.use(VueLazyLoad, {\n  rootMargin: '200px',        // 可选：提前加载距离，默认 200px\n  loading: '/placeholder.png', // 可选：加载中占位图\n  error: '/error.png',         // 可选：加载失败占位图\n  persistent: false,           // 可选：是否开启 L2 IndexedDB 持久化缓存，默认 false\n  maxMemory: 150,              // 可选：L1 内存缓存最大条目数，默认 150\n  maxIdb: 500,                 // 可选：L2 IndexedDB 最大条目数，默认 500\n})\n\napp.mount('#app')\n```\n\n### 基本用法\n\n```html\n<img v-lazy=\"imageUrl\" />\n```\n\n### 带 fallback 兜底图\n\n```html\n<img v-lazy=\"{ src: imageUrl, fallback: fallbackUrl }\" />\n```\n\n主图加载失败时自动切换到 `fallbackUrl`。\n\n### 缓存管理 API\n\n```js\nimport { clearImageCache, getCacheStats } from '@code-killer/vue-lazy-load'\n\nclearImageCache()        // 清除所有缓存（L1 + L2），释放内存（适用于登出、调试等场景）\ngetCacheStats()          // 返回 { hits, misses, hitRate, size }，用于判断缓存配置是否合理\n```\n\n## 缓存架构\n\n```\nimg 挂载\n  → 检查 L1 内存缓存（同步）\n    → 命中：直接赋值 src（零延迟，零闪烁）\n    → 未命中：注册 IntersectionObserver\n      → 进入视口\n        → 检查 L2 IndexedDB（异步，仅 persistent 开启时）\n          → 命中：创建 Blob URL → 提升到 L1 → 赋值 src\n          → 未命中：fetch 图片 → Blob URL → 写入 L1 + L2 → 赋值 src\n        → 失败：使用 fallback 或全局 error 占位图\n```\n\n### 两级缓存说明\n\n| 层级 | 存储介质 | 容量 | 特点 |\n|------|----------|------|------|\n| L1 | 内存 Map（LRU） | 默认 150 条 | 同步读取，零延迟，页面刷新后失效 |\n| L2 | IndexedDB（Blob） | 默认 500 条 | 异步读取，页面刷新后仍命中，需手动开启 |\n\n- L2 默认关闭，通过 `persistent: true` 开启，尊重用户存储意愿\n- L2 命中后自动提升到 L1，后续访问走内存零延迟\n- 两级均有自动淘汰机制，不会无限增长\n\n## 配置项\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `rootMargin` | `string` | `'200px'` | IntersectionObserver 预加载距离 |\n| `loading` | `string` | `''` | 加载中占位图 URL |\n| `error` | `string` | `''` | 加载失败占位图 URL |\n| `persistent` | `boolean` | `false` | 是否开启 L2 IndexedDB 持久化缓存 |\n| `maxMemory` | `number` | `150` | L1 内存缓存最大条目数 |\n| `maxIdb` | `number` | `500` | L2 IndexedDB 最大条目数 |\n\n## 要求\n\n- Vue 3.x\n- 浏览器支持 IntersectionObserver（覆盖率 > 97%）\n- L2 持久化需浏览器支持 IndexedDB（覆盖率 > 98%）\n\n## 更新日志\n\n### v1.1.0\n\n- 新增两级缓存架构：L1 内存 LRU Cache + L2 IndexedDB 持久化存储\n- 新增 `persistent` 配置项，控制是否开启 L2 持久化缓存\n- 新增 `maxMemory`、`maxIdb` 配置项，支持自定义缓存容量上限\n- 新增 `getCacheStats()` API，返回 L1 缓存命中率统计\n- 新增 `clearImageCache()` API，支持手动清除全部缓存\n- L1 淘汰时自动 `URL.revokeObjectURL` 释放 Blob 内存\n- L2 超出上限时按访问时间自动淘汰最久未使用的记录\n\n### v1.0.1\n\n- 初始版本：IntersectionObserver 懒加载 + 内存缓存 + 请求去重 + fallback 兜底\n\n## License\n\nMIT\n","readmeFilename":"README.md"}