vue-layerx
| Install | |
|---|---|
npm install vue-layerx |
|
| Latest Version: | 1.2.2 |
| Vue: | 2 · 3 |
| License: | MIT |
| Last Updated: | Oct 26, 2026 |
| Links: | GitHub · npm |
vue-layerx
简体中文 | English
弹窗编程新范式
像路由导航一样打开弹窗
像普通组件一样复用弹窗内容
📚 文档 · 🎮 Element Plus · 🎮 Vuetify
vue-layerx 是一个 Vue 弹窗调度框架,用于将已有的 Dialog / Drawer / Popup 组件转换为可编程弹层。
它不替代现有 UI 组件,而是在其之上提供统一的弹窗生命周期管理、动态渲染和业务调用方式。
使用简单,三行代码打开弹窗:
const useDialog = createLayer(ElDialog) // 任意已有弹窗容器
const dialog = useDialog(HelloWorld) // 普通组件做弹窗内容
dialog.open() // 直接调用打开
特性
- 像路由导航一样打开弹窗:无需定义变量,无需预埋模板,直接通过 API 调起
- 弹窗内容即普通组件:无需依赖特殊封装,提升组件复用能力
- 支持响应式参数传递:保持 Vue 原生响应式能力
- 支持插槽投递:命令式打开弹窗时,仍可使用 Vue 插槽组合能力
- 统一 API:同时支持 Vue 3.3+ 与 Vue 2.7
- 零运行时依赖:不依赖任何第三方 npm 包
- TypeScript 编写:提供完整类型定义
- 单元测试覆盖率 100%:保障核心功能稳定性
- 支持服务端渲染(SSR)
安装
pnpm add vue-layerx
# or
npm install vue-layerx
使用
创建组合式函数
任意弹层 容器组件 都可以通过 createLayer 生成对应的组合式函数。以 Dialog 为例:
// src/composables/dialog.ts
import { createLayer } from 'vue-layerx'
import { ElDialog } from 'element-plus'
export const useDialog = createLayer(ElDialog, {
props: { width: '480px', appendToBody: true },
})
弹层:Dialog、Drawer、Popup 等弹出式交互形态的统称。
打开弹层
传入 内容组件 得到弹层实例,再 $open 打开并传入内容参数:
<script setup lang="ts">
import UserForm from './UserForm.vue'
import { useDialog } from '@/composables/dialog'
const dialog = useDialog(UserForm)
</script>
<template>
<button @click="dialog.$open({ id: 1 })">编辑用户</button>
</template>
内容组件
下面几个 UserForm.vue 都能被上面这段打开,只是内容侧逐步补上弹层契约。
1. 收下参数
内容就是普通组件,$open 的字段对上 defineProps:
<script setup lang="ts">
defineProps<{ id: number }>()
</script>
<template>
<p>正在编辑用户 {{ id }}</p>
</template>
2. 声明标题
可以通过 defineLayer 配置内容组件在弹窗中的行为,例如标题:
<script setup lang="ts">
import { defineLayer } from 'vue-layerx'
defineProps<{ id: number }>()
defineLayer({
props: { title: '编辑用户' }, // 给容器
})
</script>
<template>
<p>正在编辑用户 {{ id }}</p>
</template>
3. 关闭弹窗
想让内容组件关闭弹窗时,用 closeOn 声明哪些事件要关层。内容只 emit,不要去调 close():
<script setup lang="ts">
import { defineLayer } from 'vue-layerx'
const props = defineProps<{ id: number }>()
const emit = defineEmits<{ success: [] }>()
defineLayer({
props: { title: '编辑用户' },
content: { closeOn: ['success'] },
})
async function save() {
await updateUser(props.id) // 失败则抛错,不往下走
emit('success')
}
</script>
<template>
<p>正在编辑用户 {{ id }}</p>
<button @click="save">保存</button>
</template>
defineLayer 定义的所有内容在具体使用时都可以再次覆盖,如:
const dialog = useDialog(UserForm, { closeOn: { success: false }, })
4. 插槽投递
想把保存按钮放到弹窗的 footer 插槽里,可以用 LayerTemplate 投递:
<script setup lang="ts">
import { defineLayer, LayerTemplate } from 'vue-layerx'
const layer = defineLayer({
props: { title: '编辑用户' },
content: { closeOn: ['success'] },
})
</script>
<template>
<p>正在编辑用户 {{ id }}</p>
<LayerTemplate :to="layer" name="footer">
<button @click="save">保存</button>
</LayerTemplate>
</template>
详细用法见向弹层投递插槽。
等待弹层结果
只打开、不等返回值用 $open;需要从弹层拿回数据再继续时,用 $confirm:
try {
const { data } = await dialog.$confirm({ id: 1 })
// 使用 data
} catch {
// 取消、点遮罩关闭
}
想要 confirm 就必须指定能 confirm 的事件,可以这样表示:
defineLayer({
content: {
closeOn: {
success: { when: 'always', confirmed: true },
},
},
})
完整说明见等待弹层结果。
文档
完整用法、进阶能力与 API 见文档站:
License
MIT
Related Packages
Gestor de modales genérico y autocontenido para Vue 3: composable de estado (sin...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.2.2 | ^2.7.0 || | MIT | |
| 1.2.1 | ^2.7.0 || | MIT | |
| 1.2.0 | ^2.7.0 || | MIT | |
| 1.1.0 | ^2.7.0 || | MIT | |
| 1.0.2 | ^3.3.0 | MIT | |
| 1.0.1 | ^3.5.0 | MIT | |
| 1.0.0 | ^3.5.0 | MIT | |
| 0.1.0 | ^3.5.0 | MIT | |
| 0.0.1 | ^3.5.0 | MIT |
Pre-releases (5)
| Version | Released | Vue | License |
|---|---|---|---|
| 1.0.0-beta.5 | ^3.5.0 | MIT | |
| 1.0.0-beta.4 | ^3.5.0 | MIT | |
| 1.0.0-beta.3 | ^3.5.0 | MIT | |
| 1.0.0-beta.2 | ^3.5.0 | MIT | |
| 1.0.0-beta.1 | ^3.5.0 | MIT |