У меня есть шаблон, загружающий динамические компоненты по их имени:
<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 () он не определен.
Есть стандартный способ сделать это?
да. я тоже так думал, но как я могу проверить, является ли плагин нулевым? Я пока не нашел способа проверить из setup (), зарегистрирован ли компонент или нет. Или вы бы сделали это иначе, чем проверить это?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Чтобы проверить, зарегистрирован ли компонент с определенным именем глобально в приложении, вы можете использовать функцию app.component (), передающую только первый аргумент (имя компонента)
Чтобы сделать это в любом компоненте вашего приложения, вы можете использовать (довольно редко документированную) функцию getCurrentInstance - эту функцию можно вызывать только внутри setup или хуков, и вы можете использовать ее возвращаемое значение, чтобы проверить, зарегистрирован ли компонент.
Для глобальных компонентов используйте функцию getCurrentInstance().appContext.app.component() (где свойство appContext.app представляет основной объект app, созданный с помощью createApp())
Для локально зарегистрированных компонентов используйте 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: {
//...
},
}
Вы можете установить defaultComponent в getFormRenderer, если плагин не поддерживает ed или null.