Динамический компонент внутри компонента, который отображается с помощью функции render()

#vue.js #vuejs2 #vue-component #vue-class-components

#vue.js #vuejs2 #vue-компонент #vue-class-components

Вопрос:

Я видел в документах, что вы можете иметь динамический компонент внутри вашего VueComponent следующим образом :

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

Я пытаюсь разместить один из этих динамических компонентов внутри динамически отображаемого компонента (с render() функцией, а не с HTML-шаблоном). Без особых надежд я попробовал это :

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

но я получил

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

Итак, опять же, не слишком надеясь на чудо, я попытался импортировать Component и объявить его как компонент :

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

Но тогда я получаю

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

Есть идеи, как это может быть возможно?

Ответ №1:

Первый параметр createElement() должен быть либо

  • Имя тега HTML,
  • параметры компонента,
  • или асинхронная функция, разрешающая один из них.

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

Итак, в функции рендеринга вы можете просто создать функцию *, которая возвращает параметры того или иного компонента на основе желаемых критериев, и пусть это будет вашим первым аргументом. * Эта функция идентична функции, которую вы бы написали, чтобы определить, что входит в :is prop)

Вам нужен только динамический компонент <component /> и :is поддержка в шаблоне, где у вас нет возможности сделать это программно.

Вы можете использовать этот компонент smart-list из документов vue в качестве примера.

Комментарии:

1. Спасибо, похоже, это работает, за исключением одного случая: с <component :is="cmp"> когда cmp это пустая строка, там ничего не отображается и ошибка не выдается, теперь я должен вставить компонент или я получу ошибку

2. Вы могли бы позволить ему возвращать 'div' вместо пустой строки в вашей функции. Он отобразит один ‘div’, но, по крайней мере, не приведет к сбою. Или вы могли бы вызвать функцию createElement только тогда, когда элемент соответствует действительности (например, v-if). Не совсем уверен, как встроенный «компонент» обрабатывает пустые строки, но с функцией рендеринга вам придется переопределить решение самостоятельно.