vue.jsvuejs2vue-componentvue-class-components

Dynamic component inside a component that is rendered with render() function


I saw in the docs that you can have a dynamic component inside your VueComponent like this :

<component :is="componentName" v-bind="componentProps" @custom-event="doSomething" />

I am trying to have one of these dynamic components inside a dynamically rendered component (with the render() function, not with an HTML template). Without too much hope, I've tried this :

render(createElement: CreateElement) {
  return createElement('component', props: {
    'is': 'TestComponent'
  });
}

but I got

[Vue warn]: Unknown custom element: <component> - did you register the component correctly?

So again, not hoping too much for a miracle, I tried to import Component and declare it as a component :

@Component({
  components: {
    Component,
    TestComponent
  }
})
export default class DynamicThingy extends Vue {
  render(createElement: CreateElement): VNode {
    return createElement('Component', {
      props: {
        'is': 'TestComponent'
      }
    });
  }
}

But then I get

[Vue warn]: Do not use built-in or reserved HTML elements as component id: Component

Any idea how that could be possible ?


Solution

  • The first parameter of createElement() must be either

    • An HTML tag name,
    • component options,
    • or async function resolving to one of these.

    https://v2.vuejs.org/v2/guide/render-function.html#createElement-Arguments

    So in a render function, you can simply create a function* that returns one or another component's options based on your desired criteria, and let that be your first argument. *This function is identical to the function you'd write to determine what goes into the :is prop)

    You only need the dynamic component <component /> and :is prop in a template where you don't have the possibility to do it programmatically.

    You can use this smart-list component from the vue docs as an example.