vue-mount-plugin 4.0.0-beta.5 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,8 +11,6 @@ A simple and easy to use Vue instance extension plugin that supports Vue 2.0 and
11
11
  [![gzip][gzip-image]][gzip-url]
12
12
  [![License][license-image]][license-url]
13
13
 
14
- [![Sonar][sonar-image]][sonar-url]
15
-
16
14
  </div>
17
15
 
18
16
  <div style="text-align: center; margin-bottom: 20px;" align="center">
@@ -48,19 +46,21 @@ $ yarn add vue-mount-plugin
48
46
  ### Use in Vue `>=3.0`
49
47
 
50
48
  ```vue
51
- <!-- test.vue -->
49
+ <!-- App.vue -->
52
50
  <script setup>
53
- import { getCurrentInstance } from 'vue'
54
- import Mount from 'vue-mount-plugin'
55
- import DemoVue from './demo.vue'
51
+ import { mount, createMount } from 'vue-mount-plugin'
52
+ import Modal from './Modal.vue'
56
53
 
57
- const { proxy } = getCurrentInstance()
58
- const instance = new Mount(DemoVue, { parent: proxy.$root })
54
+ // Mount and show immediately
55
+ const instance = mount(Modal, {
56
+ props: { title: 'Hello' }
57
+ })
59
58
 
60
- // mount to the end of document.body
61
- instance.mount()
59
+ // Or create first, show later
60
+ const instance2 = createMount(Modal, { props: { title: 'Deferred' } })
61
+ instance2.show()
62
62
 
63
- // unmount
63
+ // Unmount when done
64
64
  instance.unmount()
65
65
  </script>
66
66
  ```
@@ -68,22 +68,19 @@ instance.unmount()
68
68
  ### Use in Vue `2.7`
69
69
 
70
70
  ```vue
71
- <!-- test.vue -->
71
+ <!-- App.vue -->
72
72
  <script>
73
- import { getCurrentInstance } from 'vue'
74
- import Mount from 'vue-mount-plugin'
75
- import DemoVue from './demo.vue'
73
+ import { mount, createMount } from 'vue-mount-plugin'
74
+ import Modal from './Modal.vue'
76
75
 
77
76
  export default {
78
- setup() {
79
- const { proxy } = getCurrentInstance()
80
- const instance = new Mount(DemoVue, { parent: proxy.$root })
81
-
82
- // mount to the end of document.body
83
- instance.mount()
84
-
85
- // unmount
86
- instance.unmount()
77
+ methods: {
78
+ showModal() {
79
+ const instance = mount(Modal, {
80
+ props: { title: 'Hello' },
81
+ parent: this.$root
82
+ })
83
+ }
87
84
  }
88
85
  }
89
86
  </script>
@@ -101,32 +98,8 @@ export default {
101
98
  }
102
99
  ```
103
100
 
104
- ```vue
105
- <!-- test.vue -->
106
- <script>
107
- import { getCurrentInstance } from '@vue/composition-api'
108
- import Mount from 'vue-mount-plugin'
109
- import DemoVue from './demo.vue'
110
-
111
- export default {
112
- setup() {
113
- const { proxy } = getCurrentInstance()
114
- const instance = new Mount(DemoVue, { parent: proxy.$root })
115
-
116
- // mount to the end of document.body
117
- instance.mount()
118
-
119
- // unmount
120
- instance.unmount()
121
- }
122
- }
123
- </script>
124
- ```
125
-
126
101
  ### Import in Browser
127
102
 
128
- Import `vue-mount-plugin` through browser HTML tags directly, and use global variable `VueMount`.
129
-
130
103
  ```html
131
104
  <head>
132
105
  <!-- Import vue3 or vue2 -->
@@ -138,62 +111,53 @@ Import `vue-mount-plugin` through browser HTML tags directly, and use global var
138
111
 
139
112
  ```html
140
113
  <script>
141
- const instance = new VueMount(DemoVue, { parent: this.$root })
142
-
143
- // mount to the end of document.body
144
- instance.mount()
145
-
146
- // unmount
114
+ // Global: VueMount.mount, VueMount.createMount, etc.
115
+ const instance = VueMount.mount(DemoVue, { props: { title: 'Hello' } })
147
116
  instance.unmount()
148
117
  </script>
149
118
  ```
150
119
 
151
- ### ES5 Support
120
+ ### IE11 Support
152
121
 
153
- For older browsers (IE11), use the ES5 build:
122
+ For IE11 compatibility, use the ES5 build:
154
123
 
155
124
  ```html
156
125
  <head>
157
126
  <!-- Import vue2 (Vue 3 does not support IE11) -->
158
127
  <script src="//unpkg.com/vue@2"></script>
159
- <!-- Import vue-mount-plugin ES5 build -->
128
+ <!-- Import ES5 build for IE11 -->
160
129
  <script src="//unpkg.com/vue-mount-plugin@4/dist/index.es5.min.js"></script>
161
130
  </head>
162
131
  ```
163
132
 
164
- ## API
165
-
166
- ### Constructor
133
+ > **Note:** Vue 3 does not support IE11. Use Vue 2 with the ES5 build for IE11 compatibility.
167
134
 
168
- ```typescript
169
- new Mount(component, options?)
170
- ```
135
+ ## API
171
136
 
172
- #### Parameters
137
+ ### Core Functions
173
138
 
174
- | Parameter | Type | Description |
175
- |-----------|------|-------------|
176
- | `component` | `Component` | Vue component to mount (supports async components) |
177
- | `options` | `Options` | Mount options (optional) |
139
+ | Function | Description |
140
+ |----------|-------------|
141
+ | `mount(component, options?)` | Create and immediately show component |
142
+ | `createMount(component, options?)` | Create instance without showing (manual control) |
178
143
 
179
- #### Options
144
+ ### Mount Options
180
145
 
181
146
  | Property | Type | Default | Description |
182
147
  |----------|------|---------|-------------|
183
- | `app` | `App` | - | Vue 3 app instance |
184
- | `children` | `unknown` | - | Children for VNode |
185
- | `context` | `object` | - | Vue 2 context (router, store, i18n) |
186
- | `parent` | `unknown` | - | Parent component instance |
187
148
  | `props` | `object` | - | Props to pass to component |
188
149
  | `target` | `Element \| string` | - | Mount target element or selector |
189
150
  | `tagName` | `string` | `'div'` | Tag name for auto-created container |
151
+ | `app` | `App` | - | Vue 3 app instance (for context inheritance) |
152
+ | `parent` | `unknown` | - | Parent component instance (Vue 2) |
153
+ | `context` | `object` | - | Vue 2 context (router, store, i18n) |
190
154
  | `listeners` | `Listeners` | - | Event listeners object |
191
155
  | `on` | `Listeners` | - | Event listeners (alias) |
192
156
  | `slots` | `Slots` | - | Slots object |
193
- | `ref` | `Ref` | - | Ref to get component instance |
194
- | `keepAlive` | `KeepAliveOptions \| boolean` | - | KeepAlive configuration |
157
+ | `singleton` | `boolean \| string` | - | Singleton mode |
158
+ | `zIndex` | `number` | - | z-index level |
195
159
 
196
- #### Lifecycle Hooks
160
+ ### Lifecycle Hooks
197
161
 
198
162
  | Hook | Description |
199
163
  |------|-------------|
@@ -206,46 +170,126 @@ new Mount(component, options?)
206
170
 
207
171
  | Method | Returns | Description |
208
172
  |--------|---------|-------------|
209
- | `mount()` | `this` | Mount the component to DOM |
210
- | `unmount()` | `void` | Unmount and destroy the component |
173
+ | `show()` | `this` | Show/mount the component |
174
+ | `hide()` | `this` | Hide component (keep instance) |
175
+ | `unmount()` | `void` | Unmount and destroy completely |
211
176
  | `destroy()` | `void` | Alias for `unmount()` |
212
177
  | `remove()` | `void` | Alias for `unmount()` |
213
- | `setProps(props)` | `this` | Set props (chainable) |
214
- | `setListeners(listeners)` | `this` | Set event listeners (chainable) |
215
- | `on(listeners)` | `this` | Alias for `setListeners()` |
216
- | `setSlots(slots)` | `this` | Set slots (chainable) |
178
+ | `setProps(props)` | `this` | Update props (chainable) |
217
179
  | `setTarget(target)` | `this` | Set mount target (chainable) |
180
+ | `setSlots(slots)` | `this` | Set slots (chainable) |
218
181
  | `setHooks(hooks)` | `this` | Set lifecycle hooks (chainable) |
182
+ | `on(event, handler)` | `this` | Add event listener (chainable) |
183
+ | `off(event, handler?)` | `this` | Remove event listener (chainable) |
184
+ | `emit(event, ...args)` | `this` | Emit event (chainable) |
219
185
 
220
186
  ### Instance Properties
221
187
 
222
188
  | Property | Type | Description |
223
189
  |----------|------|-------------|
224
- | `id` | `number` | Unique instance ID (readonly) |
225
- | `vNode` | `VNode` | Vue virtual node |
226
- | `target` | `Element` | Mount target element |
227
- | `componentInstance` | `ComponentPublicInstance` | Mounted component instance |
190
+ | `id` | `string` | Unique instance ID |
191
+ | `mounted` | `boolean` | Whether component is mounted |
192
+ | `el` | `HTMLElement \| null` | DOM element |
193
+ | `vm` | `ComponentPublicInstance \| null` | Vue component instance |
194
+ | `options` | `MountOptions` | Merged options |
195
+
196
+ ### Global Functions
197
+
198
+ | Function | Description |
199
+ |----------|-------------|
200
+ | `getInstances()` | Get all active instances |
201
+ | `getInstanceById(id)` | Get instance by ID |
202
+ | `unmountAll()` | Unmount all instances |
203
+ | `isMounted(id)` | Check if instance is mounted |
204
+ | `getActiveInstanceIds()` | Get all active instance IDs |
205
+ | `setGlobalConfig(config)` | Set global configuration |
206
+ | `globalConfig` | Global configuration object |
228
207
 
229
- ### Static Methods
208
+ ## Usage Examples
230
209
 
231
- | Method | Returns | Description |
232
- |--------|---------|-------------|
233
- | `Mount.instances` | `Mount[]` | Get all active instances |
234
- | `Mount.unmountAll()` | `void` | Unmount all instances |
235
- | `Mount.destroyAll()` | `void` | Alias for `unmountAll()` |
236
- | `Mount.getById(id)` | `Mount \| undefined` | Get instance by ID |
210
+ ### Basic Usage
237
211
 
238
- ## Usage Examples
212
+ ```typescript
213
+ import { mount } from 'vue-mount-plugin'
214
+ import Modal from './Modal.vue'
215
+
216
+ // Mount and show immediately
217
+ const instance = mount(Modal, {
218
+ props: { title: 'Hello World' }
219
+ })
220
+
221
+ // Unmount when done
222
+ instance.unmount()
223
+ ```
224
+
225
+ ### Promise Support
226
+
227
+ ```typescript
228
+ import { mount } from 'vue-mount-plugin'
229
+ import ConfirmDialog from './ConfirmDialog.vue'
230
+
231
+ // Await user confirmation
232
+ const result = await mount(ConfirmDialog, {
233
+ props: {
234
+ message: 'Are you sure?'
235
+ }
236
+ })
237
+
238
+ console.log(result ? 'Confirmed' : 'Cancelled')
239
+ ```
240
+
241
+ > The Promise resolves when the component emits a `close` event.
242
+
243
+ ### Singleton Mode
244
+
245
+ ```typescript
246
+ import { mount } from 'vue-mount-plugin'
247
+ import Toast from './Toast.vue'
248
+
249
+ // Only one toast instance exists at a time
250
+ mount(Toast, {
251
+ singleton: true,
252
+ props: { message: 'Hello!' }
253
+ })
254
+
255
+ // Using custom key for different singleton groups
256
+ mount(Toast, {
257
+ singleton: 'error-toast',
258
+ props: { message: 'Error!', type: 'error' }
259
+ })
260
+ ```
261
+
262
+ ### Event System
263
+
264
+ ```typescript
265
+ import { mount } from 'vue-mount-plugin'
266
+ import Modal from './Modal.vue'
267
+
268
+ const instance = mount(Modal)
269
+
270
+ // Listen to events
271
+ instance.on('submit', (data) => {
272
+ console.log('Submitted:', data)
273
+ })
274
+
275
+ // Chaining
276
+ instance
277
+ .on('close', () => console.log('Closed'))
278
+ .on('error', (err) => console.error(err))
279
+ ```
239
280
 
240
281
  ### Lifecycle Hooks
241
282
 
242
283
  ```typescript
243
- const instance = new Mount(DemoVue, {
284
+ import { createMount } from 'vue-mount-plugin'
285
+ import Modal from './Modal.vue'
286
+
287
+ const instance = createMount(Modal, {
244
288
  onBeforeMount: (instance) => {
245
- console.log('About to mount', instance.id)
289
+ console.log('About to mount')
246
290
  },
247
291
  onMounted: (instance) => {
248
- console.log('Mounted', instance.componentInstance)
292
+ console.log('Mounted', instance.el)
249
293
  },
250
294
  onBeforeUnmount: (instance) => {
251
295
  console.log('About to unmount')
@@ -254,167 +298,374 @@ const instance = new Mount(DemoVue, {
254
298
  console.log('Unmounted')
255
299
  }
256
300
  })
257
- instance.mount()
301
+
302
+ instance.show()
258
303
  ```
259
304
 
260
- ### Event Listeners
305
+ ### Manual Control
261
306
 
262
307
  ```typescript
263
- const instance = new Mount(DemoVue, {
264
- listeners: {
265
- click: (event) => console.log('Clicked!', event),
266
- close: () => instance.unmount()
267
- }
268
- })
269
- // or use 'on' alias
270
- const instance2 = new Mount(DemoVue, {
271
- on: {
272
- submit: (data) => console.log('Submitted:', data)
273
- }
308
+ import { createMount } from 'vue-mount-plugin'
309
+ import Modal from './Modal.vue'
310
+
311
+ // Create without showing
312
+ const instance = createMount(Modal, {
313
+ props: { title: 'Manual Control' }
274
314
  })
315
+
316
+ console.log(instance.mounted) // false
317
+
318
+ // Show when needed
319
+ instance.show()
320
+ console.log(instance.mounted) // true
321
+
322
+ // Hide but keep instance
323
+ instance.hide()
324
+ console.log(instance.mounted) // true (still tracked)
325
+
326
+ // Destroy completely
327
+ instance.unmount()
328
+ console.log(instance.mounted) // false
275
329
  ```
276
330
 
277
- ### Slots
331
+ ### Props Update
278
332
 
279
333
  ```typescript
280
- import { h } from 'vue'
334
+ import { mount } from 'vue-mount-plugin'
335
+ import Modal from './Modal.vue'
281
336
 
282
- const instance = new Mount(ModalComponent, {
283
- slots: {
284
- default: [h('p', 'Modal content')],
285
- header: [h('h2', 'Title')],
286
- footer: [h('button', 'Close')]
287
- }
337
+ const instance = mount(Modal, {
338
+ props: { title: 'Original' }
288
339
  })
340
+
341
+ // Update props dynamically
342
+ instance.setProps({ title: 'Updated!' })
343
+
344
+ // Chain with other methods
345
+ instance
346
+ .setProps({ loading: true })
347
+ .setProps({ loading: false, title: 'Done' })
289
348
  ```
290
349
 
291
- ### Ref Access
350
+ ### Context Inheritance (Vue 3)
292
351
 
293
352
  ```typescript
294
- import { ref } from 'vue'
353
+ import { mount } from 'vue-mount-plugin'
354
+ import { getCurrentInstance } from 'vue'
355
+ import Modal from './Modal.vue'
295
356
 
296
- const componentRef = ref(null)
297
- const instance = new Mount(DemoVue, { ref: componentRef })
357
+ // In Vue 3, pass app for context inheritance
358
+ const { appContext } = getCurrentInstance()!
298
359
 
299
- instance.mount()
300
- // Access the component instance
301
- console.log(componentRef.value) // ComponentPublicInstance
360
+ const instance = mount(Modal, {
361
+ app: appContext.app,
362
+ props: { title: 'With Context' }
363
+ })
364
+
365
+ // Component can now use router, store, i18n, etc.
302
366
  ```
303
367
 
304
- ### Async Components
368
+ ### useMount Composable
305
369
 
306
370
  ```typescript
307
- // Async component with dynamic import
308
- const instance = new Mount(
309
- () => import('./HeavyComponent.vue'),
310
- { parent: proxy.$root }
311
- )
312
- instance.mount()
313
- ```
371
+ import { useMount } from 'vue-mount-plugin'
372
+ import Modal from './Modal.vue'
314
373
 
315
- ### Chained API
374
+ const { mount, unmountAll, count, instances } = useMount()
316
375
 
317
- ```typescript
318
- const instance = new Mount(DemoVue)
319
- .setProps({ title: 'Hello' })
320
- .setListeners({ click: handleClick })
321
- .setTarget('#modal-container')
322
- .setHooks({ onMounted: () => console.log('Ready!') })
323
- .mount()
376
+ // Mount component (auto cleanup on unmount)
377
+ const instance = mount(Modal, { props: { title: 'Hello' } })
378
+
379
+ // Track active instances
380
+ console.log(count.value) // 1
381
+ console.log(instances.value) // [instance]
382
+
383
+ // Unmount all at once
384
+ unmountAll()
324
385
  ```
325
386
 
326
- ### Instance Management
387
+ ### Vue Plugin
327
388
 
328
389
  ```typescript
329
- // Get all active instances
330
- const allInstances = Mount.instances
331
- console.log(`Active instances: ${allInstances.length}`)
390
+ import { createApp } from 'vue'
391
+ import { MountPlugin } from 'vue-mount-plugin'
392
+ import App from './App.vue'
332
393
 
333
- // Get specific instance by ID
334
- const instance = Mount.getById(1)
394
+ const app = createApp(App)
335
395
 
336
- // Unmount all instances at once
337
- Mount.unmountAll()
396
+ // Install with default name ($show)
397
+ app.use(MountPlugin, { zIndex: 2000 })
398
+
399
+ // Or with custom name
400
+ app.use(MountPlugin, { name: '$mount' })
401
+
402
+ // Now available in templates
403
+ // this.$show(Component, options)
338
404
  ```
339
405
 
340
406
  ## Migration from v3.x to v4.0
341
407
 
342
- ### Breaking Changes
408
+ ### Overview
409
+
410
+ v4.0 is a major rewrite with a cleaner functional API. This guide will help you migrate from v3.x.
411
+
412
+ ### Quick Migration Checklist
413
+
414
+ - [ ] Replace `new Mount()` with `mount()` or `createMount()`
415
+ - [ ] Update property names (`id` is now string, `componentInstance` → `vm`)
416
+ - [ ] Update method calls (`.mount()` → `.show()`)
417
+ - [ ] Update static method calls (`.instances` → `getInstances()`)
418
+ - [ ] Update build file paths if using CDN
419
+
420
+ ### API Changes
343
421
 
344
- #### 1. Build Output File Names
422
+ #### Core API
345
423
 
346
- If you reference the build files directly, update the paths:
424
+ | v3.x | v4.0 | Notes |
425
+ |------|------|-------|
426
+ | `new Mount(component, options)` | `mount(component, options)` | Create + show immediately |
427
+ | `new Mount(component, options)` | `createMount(component, options)` | Create only, manual show |
428
+ | `instance.mount()` | `instance.show()` | Method renamed |
429
+ | `instance.destroy()` | `instance.unmount()` | Method renamed (alias still works) |
430
+ | `instance.remove()` | `instance.unmount()` | Alias still works |
431
+
432
+ #### Instance Properties
433
+
434
+ | v3.x | v4.0 | Notes |
435
+ |------|------|-------|
436
+ | `instance.id` (number) | `instance.id` (string) | Now string for better uniqueness |
437
+ | `instance.componentInstance` | `instance.vm` | Renamed for consistency |
438
+ | `instance.vNode` | - | Removed, use `instance.vm` |
439
+ | `instance.target` | `instance.el` | Renamed |
440
+ | - | `instance.mounted` | New: boolean state |
441
+
442
+ #### Static Methods → Functions
347
443
 
348
444
  | v3.x | v4.0 |
349
445
  |------|------|
350
- | `dist/index.esm-browser.js` | `dist/index.iife.js` |
351
- | `dist/index.esm-browser.prod.js` | `dist/index.iife.min.js` |
352
- | `dist/index.esm-bundler.js` | `dist/index.mjs` |
353
- | `dist/index.cjs.js` | `dist/index.cjs` |
354
- | `dist/index.global.js` | removed |
355
- | `dist/index.global.prod.js` | removed |
446
+ | `Mount.instances` | `getInstances()` |
447
+ | `Mount.getById(id)` | `getInstanceById(id)` |
448
+ | `Mount.unmountAll()` | `unmountAll()` |
449
+ | `Mount.destroyAll()` | `unmountAll()` |
356
450
 
357
- #### 2. Node.js Version
451
+ #### Options Changes
358
452
 
359
- Minimum Node.js version increased from `>=12.20` to `>=14.14.0`.
453
+ | v3.x | v4.0 | Notes |
454
+ |------|------|-------|
455
+ | `parent` | `parent` | Still supported (Vue 2) |
456
+ | - | `app` | New: Vue 3 context inheritance |
457
+ | - | `singleton` | New: singleton mode |
458
+ | - | `onBeforeMount` | New: lifecycle hook |
459
+ | - | `onMounted` | New: lifecycle hook |
460
+ | - | `onBeforeUnmount` | New: lifecycle hook |
461
+ | - | `onUnmounted` | New: lifecycle hook |
360
462
 
361
- #### 3. CDN Links
463
+ ### Code Migration Examples
362
464
 
363
- Update your CDN links:
465
+ #### Basic Usage
364
466
 
365
- ```html
366
- <!-- v3.x -->
367
- <script src="//unpkg.com/vue-mount-plugin@3/dist/index.esm-browser.prod.js"></script>
467
+ ```typescript
468
+ // v3.x
469
+ import Mount from 'vue-mount-plugin'
470
+ const instance = new Mount(Modal, { parent: this.$root })
471
+ instance.mount()
472
+ instance.unmount()
368
473
 
369
- <!-- v4.0 -->
370
- <script src="//unpkg.com/vue-mount-plugin@4/dist/index.iife.min.js"></script>
474
+ // v4.0
475
+ import { mount } from 'vue-mount-plugin'
476
+ const instance = mount(Modal, { app: this.$root })
477
+ instance.unmount()
371
478
  ```
372
479
 
373
- ### New Features (Optional Adoption)
480
+ #### Deferred Mount
374
481
 
375
- v4.0 introduces many new features that are backward compatible:
482
+ ```typescript
483
+ // ❌ v3.x
484
+ import Mount from 'vue-mount-plugin'
485
+ const instance = new Mount(Modal, options)
486
+ // ... later
487
+ instance.mount()
488
+
489
+ // ✅ v4.0
490
+ import { createMount } from 'vue-mount-plugin'
491
+ const instance = createMount(Modal, options)
492
+ // ... later
493
+ instance.show()
494
+ ```
495
+
496
+ #### Instance Management
376
497
 
377
498
  ```typescript
378
- // Lifecycle hooks
379
- const instance = new Mount(Component, {
380
- onBeforeMount: (instance) => console.log('before mount'),
381
- onMounted: (instance) => console.log('mounted'),
499
+ // v3.x
500
+ const all = Mount.instances
501
+ const found = Mount.getById(1)
502
+ Mount.unmountAll()
503
+
504
+ // ✅ v4.0
505
+ import { getInstances, getInstanceById, unmountAll } from 'vue-mount-plugin'
506
+ const all = getInstances()
507
+ const found = getInstanceById('mount-1-xxx')
508
+ unmountAll()
509
+ ```
510
+
511
+ #### Access Component Instance
512
+
513
+ ```typescript
514
+ // ❌ v3.x
515
+ const instance = new Mount(Modal)
516
+ instance.mount()
517
+ console.log(instance.componentInstance)
518
+
519
+ // ✅ v4.0
520
+ const instance = mount(Modal)
521
+ console.log(instance.vm)
522
+ ```
523
+
524
+ #### Event Listeners
525
+
526
+ ```typescript
527
+ // ❌ v3.x
528
+ const instance = new Mount(Modal, {
529
+ listeners: { close: handleClose }
382
530
  })
531
+ instance.mount()
383
532
 
384
- // Event listeners
385
- const instance = new Mount(Component, {
386
- listeners: { click: handleClick },
387
- // or
388
- on: { click: handleClick },
533
+ // v4.0 - Option 1: via options
534
+ const instance = mount(Modal, {
535
+ listeners: { close: handleClose }
389
536
  })
390
537
 
391
- // Ref support
392
- const ref = { value: null }
393
- new Mount(Component, { ref })
538
+ // v4.0 - Option 2: via method (new!)
539
+ const instance = mount(Modal)
540
+ instance.on('close', handleClose)
541
+ ```
542
+
543
+ #### Chained API
394
544
 
395
- // Chained API
396
- new Mount(Component)
545
+ ```typescript
546
+ // ❌ v3.x
547
+ const instance = new Mount(Modal)
397
548
  .setProps({ title: 'Hello' })
398
549
  .setTarget('#container')
399
550
  .mount()
400
551
 
401
- // Instance management
402
- const allInstances = Mount.instances
403
- Mount.unmountAll()
404
- const instance = Mount.getById(1)
552
+ // v4.0
553
+ const instance = createMount(Modal)
554
+ .setProps({ title: 'Hello' })
555
+ .setTarget('#container')
556
+ .show()
405
557
  ```
406
558
 
407
- ### No Code Changes Required
559
+ ### New Features in v4.0
408
560
 
409
- If you only use the basic API, no code changes are needed:
561
+ #### 1. Singleton Mode
562
+
563
+ Only one instance of a component exists at a time:
410
564
 
411
565
  ```typescript
412
- // This still works in v4.0
413
- const instance = new Mount(Component, { parent: this.$root })
414
- instance.mount()
415
- instance.unmount()
566
+ import { mount } from 'vue-mount-plugin'
567
+
568
+ // Multiple calls - only one toast shows
569
+ mount(Toast, {
570
+ singleton: true,
571
+ props: { message: 'Hello' }
572
+ })
416
573
  ```
417
574
 
575
+ #### 2. Promise Support
576
+
577
+ Await user interaction results:
578
+
579
+ ```typescript
580
+ import { mount } from 'vue-mount-plugin'
581
+
582
+ const confirmed = await mount(ConfirmDialog, {
583
+ props: { message: 'Are you sure?' }
584
+ })
585
+
586
+ if (confirmed) {
587
+ // User clicked confirm
588
+ }
589
+ ```
590
+
591
+ #### 3. hide() Method
592
+
593
+ Hide without destroying:
594
+
595
+ ```typescript
596
+ import { mount } from 'vue-mount-plugin'
597
+
598
+ const instance = mount(Modal)
599
+ instance.hide() // Hidden but instance preserved
600
+ instance.show() // Show again
601
+ instance.unmount() // Destroy completely
602
+ ```
603
+
604
+ #### 4. useMount Composable
605
+
606
+ Auto cleanup in Vue 3 components:
607
+
608
+ ```typescript
609
+ import { useMount } from 'vue-mount-plugin'
610
+
611
+ const { mount, unmountAll, count } = useMount()
612
+
613
+ // Instances auto-cleaned when component unmounts
614
+ const instance = mount(Modal)
615
+ ```
616
+
617
+ #### 5. Global Configuration
618
+
619
+ Set defaults for all instances:
620
+
621
+ ```typescript
622
+ import { setGlobalConfig, globalConfig } from 'vue-mount-plugin'
623
+
624
+ setGlobalConfig({ zIndex: 2000 })
625
+
626
+ // All instances inherit this config
627
+ mount(Modal) // zIndex: 2000
628
+ ```
629
+
630
+ ### Build Output Changes
631
+
632
+ | v3.x | v4.0 |
633
+ |------|------|
634
+ | `dist/index.esm-browser.js` | `dist/index.iife.js` |
635
+ | `dist/index.esm-browser.prod.js` | `dist/index.iife.min.js` |
636
+ | `dist/index.esm-bundler.js` | `dist/index.mjs` |
637
+ | `dist/index.cjs.js` | `dist/index.cjs` |
638
+ | `dist/index.global.js` | removed |
639
+ | `dist/index.global.prod.js` | removed |
640
+
641
+ ### CDN Migration
642
+
643
+ ```html
644
+ <!-- ❌ v3.x -->
645
+ <script src="//unpkg.com/vue-mount-plugin@3/dist/index.esm-browser.prod.js"></script>
646
+
647
+ <!-- ✅ v4.0 -->
648
+ <script src="//unpkg.com/vue-mount-plugin@4/dist/index.iife.min.js"></script>
649
+ ```
650
+
651
+ ### Node.js Version
652
+
653
+ Minimum Node.js version: `>=14.14.0` (was `>=12.20`)
654
+
655
+ ### Migration Script
656
+
657
+ For large projects, you can use this regex replacement guide:
658
+
659
+ | Find | Replace |
660
+ |------|---------|
661
+ | `new Mount\(([^)]+)\)` | `mount($1)` |
662
+ | `\.mount\(\)` | `.show()` |
663
+ | `Mount\.instances` | `getInstances()` |
664
+ | `Mount\.getById\(([^)]+)\)` | `getInstanceById($1)` |
665
+ | `Mount\.unmountAll\(\)` | `unmountAll()` |
666
+ | `\.componentInstance` | `.vm` |
667
+ | `\.target` | `.el` |
668
+
418
669
  ## Build Outputs
419
670
 
420
671
  | File | Format | Description |
@@ -423,8 +674,20 @@ instance.unmount()
423
674
  | `index.cjs` | CJS | CommonJS for Node.js |
424
675
  | `index.iife.js` | IIFE | Browser build |
425
676
  | `index.iife.min.js` | IIFE | Browser build (minified) |
426
- | `index.es5.js` | UMD | ES5 compatible build |
427
- | `index.es5.min.js` | UMD | ES5 compatible build (minified) |
677
+ | `index.es5.js` | UMD | ES5 compatible build (IE11 support) |
678
+ | `index.es5.min.js` | UMD | ES5 compatible build (minified, IE11 support) |
679
+
680
+ ## Browser Support
681
+
682
+ | Browser | Support |
683
+ |---------|---------|
684
+ | Chrome | ✅ Latest |
685
+ | Firefox | ✅ Latest |
686
+ | Safari | ✅ Latest |
687
+ | Edge | ✅ Latest |
688
+ | IE 11 | ✅ Use ES5 build (`index.es5.min.js`) |
689
+
690
+ > For IE11, use Vue 2 and the ES5 build. Vue 3 does not support IE11.
428
691
 
429
692
  ## Support & Issues
430
693
 
@@ -446,5 +709,3 @@ Please open an issue [here](https://github.com/saqqdy/vue-mount-plugin/issues).
446
709
  [gzip-url]: http://img.badgesize.io/https://unpkg.com/vue-mount-plugin/dist/index.iife.min.js?compression=gzip&label=gzip%20size:%20JS
447
710
  [license-image]: https://img.shields.io/badge/License-MIT-blue.svg
448
711
  [license-url]: LICENSE
449
- [sonar-image]: https://sonarcloud.io/api/project_badges/quality_gate?project=saqqdy_vue-mount-plugin
450
- [sonar-url]: https://sonarcloud.io/dashboard?id=saqqdy_vue-mount-plugin