跪拜 Guibai
← All articles
Vue.js · Frontend · Frontend Framework

vue-layerx Turns Any Vue Dialog Into a One-Line Imperative Call

By 阿懂在掘金 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Vue projects that lean heavily on dialogs and drawers accumulate repetitive `v-model` boilerplate and tightly coupled shell-content components that resist reuse. vue-layerx provides an imperative escape hatch without replacing the component library or forcing JSX, which lowers the migration cost for teams already invested in Element Plus, Ant Design Vue, or custom design systems.

Summary

vue-layerx 1.0.1 introduces a container-content model for Vue 3 modals. A `createLayer` call adapts any existing component library's Dialog or Drawer—Element Plus, Ant Design Vue, Vant, or a custom shell—into a reusable `useDialog` function. From there, opening a dialog with any business component takes a single `dialog.open()` call, with no `visible` state to manage in the page template. Slots remain template-based through `LayerTemplate`, avoiding mandatory JSX, and content components can self-configure their container via `defineLayer` so footer slots and width preferences travel with the business logic.

For enterprise teams, configuration stacking follows a clear priority chain: infrastructure defaults from `createLayer`, content contracts from `defineLayer`, and caller overrides at `useDialog` or `open`. An `adapter` hook runs after all layers merge, letting teams enforce site-wide policies like disabling mask-close across every dialog. The library also handles `Provide/Inject` context repair under imperative calls, reactive dependency tracking for cross-instance slot transmission, and `await dialog.confirm()` for result-waiting workflows.

Test coverage sits at 100% across statements, branches, functions, and lines with over 300 test cases. It ships as full TypeScript with Vue as its only peer dependency and supports SSR in Nuxt and Vite SSR setups.

Takeaways
Three lines adapt any `v-model`-based Dialog or Drawer into an imperative API: `createLayer(ElDialog)`, `useDialog(HelloWorld)`, and `dialog.open()`.
Content components stay plain Vue SFCs and remain usable both inside dialogs and standalone on pages.
`LayerTemplate` delivers slot content from the calling template to the imperative dialog without requiring JSX.
`defineLayer` lets a content component declare its own container preferences, such as width or footer slots, keeping business logic self-contained.
Configuration merges from three sources—`createLayer` defaults, `defineLayer` contracts, and `useDialog`/`open` overrides—with later sources taking higher priority.
An `adapter` hook runs after all configuration layers merge, enabling site-wide enforcement of policies like disabling mask-close.
`await dialog.confirm()` provides a promise-based way to wait for a dialog's result.
The library repairs `Provide/Inject` context that normally breaks under imperative rendering.
Test coverage is 100% across all metrics with 300+ cases; the only peer dependency is Vue 3, and SSR is supported.
Conclusions

Most imperative dialog solutions for Vue push teams toward JSX for slot content, which fragments the template workflow. vue-layerx's `LayerTemplate` keeps slots in the template, so a team can adopt imperative dialogs without a second syntax.

Letting content components declare container preferences through `defineLayer` inverts the usual ownership model. The business component carries its own dialog width and footer, so the calling page doesn't need to know those details, which reduces prop-drilling across layers.

The `adapter` hook is a small but sharp addition. Configuration stacking handles defaults and overrides, but a post-merge hook is the only way to guarantee a policy like 'no mask-close ever' survives every override path—something most modal managers lack.

Concepts & terms
Container-content separation
A model where the modal shell (container: visibility, mask, title bar) and the business UI (content: form, detail panel) are developed as independent components and composed at call time rather than baked into a single file.
LayerAdapter
A post-merge hook in vue-layerx that receives the fully resolved configuration from all sources (infrastructure defaults, content contract, caller overrides) and can mutate it before rendering, useful for enforcing non-overridable policies.
LayerTemplate
A vue-layerx component that projects template-based slot content into an imperatively opened dialog, avoiding the need to write JSX for slot insertion.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗