diff --git a/packages/core/createReusableTemplate/index.test.ts b/packages/core/createReusableTemplate/index.test.ts index a8d074de520..6494d7cb90a 100644 --- a/packages/core/createReusableTemplate/index.test.ts +++ b/packages/core/createReusableTemplate/index.test.ts @@ -64,6 +64,22 @@ describe.skipIf(isVue2)('createReusableTemplate', () => { expect(wrapper.text()).toBe('{"msg":"Foo"}{"msg":"Bar"}') }) + it('attrs', () => { + const [DefineFoo, ReuseFoo] = createReusableTemplate() + + const wrapper = mount({ + render() { + return h(Fragment, null, [ + h(DefineFoo, () => h('div', { class: 'foo' })), + h(ReuseFoo, { id: 'bar', class: 'bar' }), + ]) + }, + }) + + expect(wrapper.get('#bar')).toBeDefined() + expect(wrapper.get('#bar').classes()).toEqual(['foo', 'bar']) + }) + it('slots', () => { const [DefineFoo, ReuseFoo] = createReusableTemplate<{ msg: string }, { default: Slot }>() diff --git a/packages/core/createReusableTemplate/index.ts b/packages/core/createReusableTemplate/index.ts index 001347c9dd4..33ceeb35bb4 100644 --- a/packages/core/createReusableTemplate/index.ts +++ b/packages/core/createReusableTemplate/index.ts @@ -27,6 +27,15 @@ export type ReusableTemplatePair< reuse: ReuseTemplateComponent } +export interface CreateReusableTemplateOptions { + /** + * Inherit attrs from reuse component. + * + * @default true + */ + inheritAttrs?: boolean +} + /** * This function creates `define` and `reuse` components in pair, * It also allow to pass a generic to bind with type. @@ -34,8 +43,11 @@ export type ReusableTemplatePair< * @see https://vueuse.org/createReusableTemplate */ export function createReusableTemplate< - Bindings extends object, Slots extends Record = Record, ->(): ReusableTemplatePair { + Bindings extends object, + Slots extends Record = Record, +>( + options: CreateReusableTemplateOptions = {}, +): ReusableTemplatePair { // compatibility: Vue 2.7 or above if (!isVue3 && !version.startsWith('2.7.')) { if (process.env.NODE_ENV !== 'production') @@ -44,6 +56,10 @@ export function createReusableTemplate< return } + const { + inheritAttrs = true, + } = options + const render = shallowRef() const define = defineComponent({ @@ -55,12 +71,13 @@ export function createReusableTemplate< }) as DefineTemplateComponent const reuse = defineComponent({ - inheritAttrs: false, + inheritAttrs, setup(_, { attrs, slots }) { return () => { if (!render.value && process.env.NODE_ENV !== 'production') throw new Error('[VueUse] Failed to find the definition of reusable template') - return render.value?.({ ...keysToCamelKebabCase(attrs), $slots: slots }) + const vnode = render.value?.({ ...keysToCamelKebabCase(attrs), $slots: slots }) + return (inheritAttrs && vnode?.length === 1) ? vnode[0] : vnode } }, }) as ReuseTemplateComponent