vue-layerx

像路由导航一样调度弹窗,像普通组件一样复用弹窗内容
237 9
Install
npm install vue-layerx
Latest Version:1.2.2
Vue:2 · 3
License:MIT
Last Updated:Oct 26, 2026
Links: GitHub  ·  npm
Maintainer: xuyimingwork

vue-layerx

简体中文 | English

弹窗编程新范式
像路由导航一样打开弹窗
像普通组件一样复用弹窗内容

npm version npm downloads ci codecov
minzip vue license

📚 文档 · 🎮 Element Plus · 🎮 Vuetify

zread Ask DeepWiki

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

@arfedulov/vue2-modal

An easy to style vue component for creating modal windows.

905 1
@hz_yujin/vue2-base-dialog

Vue 2 ProDialog:基于 Element UI el-dialog 的样式包装器,统一风格并透传全部弹层...

1,035
vuedl

Vue dialog helper

17,871 29
vue2-modal

An easy to use vue 2 modal component for showing and hiding modals

3,938 5
vue-greenborn-modal-manager

Gestor de modales genérico y autocontenido para Vue 3: composable de estado (sin...

1,240 0

Version History

Version Released Vue License
1.2.2 ^2.7.0 || ^3.3.0 MIT
1.2.1 ^2.7.0 || ^3.3.0 MIT
1.2.0 ^2.7.0 || ^3.3.0 MIT
1.1.0 ^2.7.0 || ^3.3.0 MIT
1.0.2 ^3.3.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