Skip to content

Commit 814b1ac

Browse files
authored
feat: added support for slots in dynamic modal (#734)
1 parent 7d37291 commit 814b1ac

File tree

5 files changed

+47
-3
lines changed

5 files changed

+47
-3
lines changed

src/PluginCore.js

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const PluginCore = (Vue, options = {}) => {
1717
const showDynamicModal = (
1818
component,
1919
componentProps,
20+
componentSlots,
2021
modalProps = {},
2122
modalEvents
2223
) => {
@@ -26,6 +27,7 @@ const PluginCore = (Vue, options = {}) => {
2627
container?.add(
2728
component,
2829
componentProps,
30+
componentSlots,
2931
{ ...defaults, ...modalProps },
3032
modalEvents
3133
)

src/components/ModalsContainer.vue

+18-3
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@
1212
v-bind="modal.componentAttrs"
1313
v-on="$listeners"
1414
@close="$modal.hide(modal.modalAttrs.name, $event)"
15-
/>
15+
>
16+
<template v-for="(slot, key) in modal.componentSlots" #[key]="scope">
17+
<VNode :node="slot" :key="key" :scope="scope" />
18+
</template>
19+
</component>
1620
</modal>
1721
</div>
1822
</template>
1923
<script>
2024
import { generateId } from '../utils'
25+
import VNode from './VNode.vue'
2126
2227
const PREFIX = 'dynamic_modal_'
2328
@@ -27,6 +32,9 @@ export default {
2732
modals: []
2833
}
2934
},
35+
components: {
36+
VNode
37+
},
3038
created() {
3139
/**
3240
* Register ModalContainer so that it was availiable inside the plugin
@@ -39,7 +47,13 @@ export default {
3947
})
4048
},
4149
methods: {
42-
add(component, componentAttrs = {}, modalAttrs = {}, modalListeners = {}) {
50+
add(
51+
component,
52+
componentAttrs = {},
53+
componentSlots = {},
54+
modalAttrs = {},
55+
modalListeners = {}
56+
) {
4357
const id = generateId()
4458
const name = modalAttrs.name || PREFIX + id
4559
@@ -48,7 +62,8 @@ export default {
4862
modalAttrs: { ...modalAttrs, name },
4963
modalListeners,
5064
component,
51-
componentAttrs
65+
componentAttrs,
66+
componentSlots
5267
})
5368
5469
this.$nextTick(() => {

src/components/VNode.vue

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<script>
2+
import { isFunction } from '../utils/types'
3+
4+
export default {
5+
name: 'VNode',
6+
props: {
7+
node: {
8+
type: [Object, Function],
9+
required: true
10+
},
11+
scope: {
12+
type: Object,
13+
default: () => ({})
14+
}
15+
},
16+
render() {
17+
if (isFunction(this.node)) return this.node(this.scope)
18+
19+
return this.node
20+
}
21+
}
22+
</script>

src/utils/types.js

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ export const isObject = value => {
99
export const isFn = value => {
1010
return typeof value === 'function'
1111
}
12+
13+
export const isFunction = value => {
14+
return typeof value === 'function'
15+
}

types/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ declare interface VModal {
1414
show(
1515
component: typeof Vue | ComponentOptions<Vue> | AsyncComponent,
1616
componentProps?: object,
17+
componentSlots?: object,
1718
modalProps?: object,
1819
modalEvents?: object
1920
): void

0 commit comments

Comments
 (0)