keep-alive-iframe
v1.0.22
Published
A Vue component for managing iframe lifecycle with keep-alive functionality
Maintainers
Readme
Keep Alive iFrame
🚀 一个支持 keep-alive 功能的 Vue 3 iframe 组件库,解决 iframe 在路由切换时被销毁的问题。
🌟 在线预览
访问 https://keepaliveiframe.netlify.app/ 查看在线演示和使用示例。
✨ 核心特性
- 🔄 Keep-Alive 支持 - iframe 在路由切换时保持状态不被销毁
- 📱 响应式设计 - 自动适配容器尺寸变化
- 🎯 智能缓存管理 - 支持最大缓存数量限制和 LRU 策略
- 🎨 灵活样式 - 支持自定义加载和错误状态
- 🛠️ TypeScript 支持 - 完整的类型定义
- 🔧 编程式 API - 提供 FrameManager 用于手动管理
- ⚡ 轻量级 - gzip 后仅 3KB
📦 安装
# npm
npm install keep-alive-iframe @vueuse/core
# yarn
yarn add keep-alive-iframe @vueuse/core
# pnpm
pnpm add keep-alive-iframe @vueuse/core📦 依赖说明:需要安装
@vueuse/core作为 peer dependency。
🔧 使用方法
基础用法
<template>
<div>
<KeepAliveFrame
:src="currentSrc"
:keep-alive="true"
@load="handleLoad"
@error="handleError"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { KeepAliveFrame } from 'keep-alive-iframe'
// 自动导入样式(如果需要)
import 'keep-alive-iframe/style.css'
const currentSrc = ref('https://example.com')
const handleLoad = () => {
console.log('iframe loaded')
}
const handleError = () => {
console.log('iframe load error')
}
</script>高级用法
<template>
<KeepAliveFrame
:src="dynamicUrl"
:keep-alive="enableCache"
:iframe-attrs="iframeAttributes"
:max-cache-size="maxCache"
:parent-container="scrollContainer"
@load="handleLoad"
@error="handleError"
@activated="handleActivated"
@deactivated="handleDeactivated"
@resize="handleResize"
@cache-hit="handleCacheHit"
@cache-miss="handleCacheMiss"
>
<!-- 自定义加载状态 -->
<template #loading>
<div class="custom-loading">
<span>正在加载...</span>
</div>
</template>
<!-- 自定义错误状态 -->
<template #error>
<div class="custom-error">
<span>加载失败,请重试</span>
</div>
</template>
<!-- 自定义空状态 -->
<template #empty>
<div class="custom-empty">
<span>请输入有效的 URL</span>
</div>
</template>
</KeepAliveFrame>
</template>
<script setup>
import KeepAliveFrame, { FrameManager, generateId } from 'keep-alive-iframe'
import { ref } from 'vue'
const dynamicUrl = ref('https://example.com')
const enableCache = ref(true)
const maxCache = ref(5)
const scrollContainer = ref(null)
const iframeAttributes = {
allow: 'camera; microphone; clipboard-read; clipboard-write',
sandbox: 'allow-scripts allow-same-origin',
referrerpolicy: 'strict-origin-when-cross-origin'
}
// 事件处理
const handleLoad = (event) => console.log('加载完成', event)
const handleError = (error) => console.error('加载错误', error)
const handleActivated = () => console.log('组件激活')
const handleDeactivated = () => console.log('组件停用')
const handleResize = (rect) => console.log('尺寸变化', rect)
const handleCacheHit = () => console.log('缓存命中')
const handleCacheMiss = () => console.log('缓存未命中')
</script>编程式 API
import { FrameManager, generateId } from 'keep-alive-iframe'
// 创建 iframe
const frameId = generateId()
const frame = FrameManager.create({
uid: frameId,
src: 'https://example.com',
width: 800,
height: 600,
top: 100,
left: 100,
keepAlive: true,
attrs: { allow: 'clipboard-read' },
onLoaded: (e) => console.log('加载完成'),
onError: (e) => console.log('加载失败')
})
// 管理 iframe
FrameManager.show(frameId) // 显示
FrameManager.hide(frameId) // 隐藏
FrameManager.resize(frameId, { // 调整大小
width: 1000,
height: 800,
top: 50,
left: 50
})
FrameManager.destroy(frameId) // 销毁
FrameManager.clear() // 清空所有缓存
FrameManager.setMaxCacheSize(20) // 设置最大缓存数📋 API 文档
Props
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| src | string | - | iframe 的 URL 地址 |
| keepAlive | boolean | true | 是否启用 keep-alive 缓存 |
| iframeAttrs | Record<string, any> | {} | iframe 元素的原生属性 |
| maxCacheSize | number | 10 | 最大缓存 iframe 数量 |
| parentContainer | HTMLElement | - | 父级滚动容器(用于滚动同步) |
| zIndex | number | 1 | iframe 的 z-index |
Events
| 事件名 | 参数 | 描述 |
|--------|------|------|
| load | (event: Event) | iframe 加载完成 |
| error | (error: Event \| string) | iframe 加载失败 |
| activated | () | 组件被激活(keep-alive) |
| deactivated | () | 组件被停用(keep-alive) |
| destroy | () | iframe 被销毁 |
| resize | (rect: DOMRect) | 容器尺寸改变 |
| cacheHit | () | 缓存命中 |
| cacheMiss | () | 缓存未命中 |
Slots
| 插槽名 | 描述 |
|--------|------|
| loading | 自定义加载状态 |
| error | 自定义错误状态 |
| empty | 自定义空状态(无 src 时) |
Expose Methods
| 方法名 | 返回值 | 描述 |
|--------|--------|------|
| getFrame() | HTMLIFrameElement \| null | 获取当前 iframe 元素 |
🔧 TypeScript 支持
库提供完整的 TypeScript 类型定义:
import type {
HTMLElementRect,
IFrameCreateOptions,
IFrameInstance
} from 'keep-alive-iframe'
// 使用类型
const options: IFrameCreateOptions = {
uid: 'my-frame',
src: 'https://example.com',
width: 800,
height: 600,
// ...其他配置
}🎯 工作原理
- iframe 脱离组件 - iframe 实际挂载在
document.body上,而不是组件内部 - 位置同步 - 使用绝对定位让 iframe 与组件容器位置同步
- 智能缓存 - 通过
FrameManager管理 iframe 生命周期和缓存策略 - 响应式布局 - 监听容器尺寸变化,实时调整 iframe 大小
⚠️ 注意事项
跨域限制
- iframe 内容需要允许跨域嵌入
- 可能需要设置适当的 CSP 策略
滚动同步
当启用 keepAlive 时,如果父容器有滚动:
- 传递
parentContainer属性以启用滚动同步 - 或考虑将
keepAlive设为false
性能考虑
- 合理设置
maxCacheSize避免内存过度占用 - 及时清理不需要的 iframe 缓存
🔨 开发
# 克隆项目
git clone https://github.com/your-username/keep-alive-iframe.git
# 安装依赖
npm install
# 开发模式
npm run dev
# 构建库
npm run build:lib
# 构建演示站点
npm run build🤝 贡献
欢迎提交 Issue 和 Pull Request!
📄 许可证
MIT © 2024
🔗 相关链接
CSS 样式
此库包含了完整的 UnoCSS 样式,包括:
- 所有基础工具类(定位、尺寸、颜色等)
- 动画样式(loading spinner)
- 组件专用样式
样式会自动打包到 keep-alive-iframe.css 中,您可以:
- 自动导入(推荐):导入组件时样式会自动加载
- 手动导入:
import 'keep-alive-iframe/style.css'
