-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
index.ts
57 lines (50 loc) · 1.61 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import type { DefineComponent, Slot } from 'vue-demi'
import { defineComponent } from 'vue-demi'
import { __onlyVue27Plus, makeDestructurable } from '@vueuse/shared'
export type DefineTemplateComponent<
Bindings extends object,
Slots extends Record<string, Slot | undefined>,
Props = {},
> = DefineComponent<Props> & {
new(): { $slots: { default(_: Bindings & { $slots: Slots }): any } }
}
export type ReuseTemplateComponent<
Bindings extends object,
Slots extends Record<string, Slot | undefined>,
> = DefineComponent<Bindings> & {
new(): { $slots: Slots }
}
/**
* This function creates `define` and `reuse` components in pair,
* It also allow to pass a generic to bind with type.
*
* @see https://vueuse.org/createReusableTemplate
*/
export function createReusableTemplate<
Bindings extends object,
Slots extends Record<string, Slot | undefined> = Record<string, Slot | undefined>,
>(name?: string) {
__onlyVue27Plus()
let render: Slot | undefined
const define = defineComponent({
setup(_, { slots }) {
return () => {
render = slots.default
}
},
}) as DefineTemplateComponent<Bindings, Slots>
const reuse = defineComponent({
inheritAttrs: false,
setup(_, { attrs, slots }) {
return () => {
if (!render && process.env.NODE_ENV !== 'production')
throw new Error(`[VueUse] Failed to find the definition of template${name ? ` "${name}"` : ''}`)
return render?.({ ...attrs, $slots: slots })
}
},
}) as ReuseTemplateComponent<Bindings, Slots>
return makeDestructurable(
{ define, reuse },
[define, reuse] as const,
)
}