Как проверить, зарегистрирован ли компонент с определенным именем в Composition API (Vue 3)

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

<template>
      <div>
        <div>
          <div>
            <component
              :is = "getFormRenderer"
            ></component>
          </div>
        </div>
      </div>
</template>

getFormRenderer возвращает строку (она поступает из API), которая идентифицирует компонент по имени.

Все возможные подкомпоненты (в этом примере импортируются и регистрируются только telegram_send_message и time_time:


<script>
import { useStore } from "vuex";
import { computed } from "vue";

import exampleComponentOne from "@/components/forms/exampleComponentOne.vue";
import exampleComponentTwo from "@/components/forms/exampleComponentTwo.vue";
import defaultComponentTwo from "@/components/forms/defaultComponent.vue";

export default {
  name: "ActionEditor",
  setup() {
    const store = useStore();

    const getFormRenderer = computed(() => {
      return (
        store.state.level.actionSelected.plugin
      );
    });
    return {
      getFormRenderer,
    };
  },
  components: {
    exampleComponentOne,
    exampleComponentTwo,
    defaultComponent
  },
};
</script>

Теперь я хочу изменить динамический <component> таким образом, чтобы он по умолчанию был defaultComponent.vue, если getFormRenderer возвращает имя компонента, которого не существует.

Но я не могу найти способ осознать это. Я думал об использовании this.hasOwnProperty (), но внутри setup () он не определен.

Есть стандартный способ сделать это?

Вы можете установить defaultComponent в getFormRenderer, если плагин не поддерживает ed или null.

larizzatg 30.03.2021 22:02

да. я тоже так думал, но как я могу проверить, является ли плагин нулевым? Я пока не нашел способа проверить из setup (), зарегистрирован ли компонент или нет. Или вы бы сделали это иначе, чем проверить это?

gauguerilla 30.03.2021 22:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
42
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Чтобы проверить, зарегистрирован ли компонент с определенным именем глобально в приложении, вы можете использовать функцию app.component (), передающую только первый аргумент (имя компонента)

Чтобы сделать это в любом компоненте вашего приложения, вы можете использовать (довольно редко документированную) функцию getCurrentInstance - эту функцию можно вызывать только внутри setup или хуков, и вы можете использовать ее возвращаемое значение, чтобы проверить, зарегистрирован ли компонент.

  1. Для глобальных компонентов используйте функцию getCurrentInstance().appContext.app.component() (где свойство appContext.app представляет основной объект app, созданный с помощью createApp())

  2. Для локально зарегистрированных компонентов используйте getCurrentInstance().components['name']

См. Пример ниже для глобальных компонентов (обратите внимание, что в примере используется Vue из CDN, поэтому он использует глобальный объект Vue. В обычной разработке вместо этого используется импорт - например, import { getCurrentInstance } from 'vue')

const app = Vue.createApp({})

app.component('mainComponent', {
  template: `
    <component :is = "getComp1OrDefault"></component>
    <component :is = "getComp2OrDefault"></component>
  `,
  setup() {  
    const vm =  Vue.getCurrentInstance()
    //console.info(vm) 
    const getComp1OrDefault = Vue.computed(() => {
      return vm.appContext.app.component('comp1') ? 'comp1' : `defaultComp`
    });
    
    const getComp2OrDefault = Vue.computed(() => {
      return vm.appContext.app.component('comp2') ? 'comp2' : `defaultComp`
    });
    
    return {
      getComp1OrDefault,
      getComp2OrDefault
    };
  }
})

app.component('comp1', {
  template: `<div>Comp1</div>`
})

app.component('defaultComp', {
  template: `<div>defaultComp</div>`
})

app.mount("#app")
<script src = "https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.7/vue.global.js" integrity = "sha512-+i5dAv2T8IUOP7oRl2iqlAErpjtBOkNtREnW/Te+4VgQ52h4tAY5biFFQJmF03jVDWU4R7l47BwV8H6qQ+/MfA= = " crossorigin = "anonymous"></script>

<div id = "app">
  <main-component />
</div>
Ответ принят как подходящий

Простой способ проверить, существует ли компонент в setup(), - использовать resolveComponent() или resolveDynamicComponent(), которые ищут компонент по имени. Обратите внимание, что в документации для resolveDynamicComponent() указано, что он выдает предупреждение для несуществующих компонентов, но на самом деле это делает resolveComponent() (начиная с v3.0.9).

Обе функции возвращают заданное имя компонента, если компонент не найден, поэтому вы можете определить, существует ли компонент, проверив, что тип возвращаемого значения не является строкой:

import { computed, resolveDynamicComponent } from 'vue'

export default {
  setup() {
    const isComponent = name => typeof resolveDynamicComponent(name) !== 'string'

    const store = useStore();
    const getFormRenderer = computed(() => 
      isComponent(store.state.level.actionSelected.plugin)
        ? store.state.level.actionSelected.plugin
        : 'DefaultComponent'
    );

    return {
      getFormRenderer
    }
  },
  components: {
    //...
  },
}

демонстрация

Другие вопросы по теме