有人可以帮我创建一个基于 NUXT3 中的 JSON 数据的动态组件吗?
我有这样的 DataTable 主体组件:
<tbody class="divide-y divide-gray-200">
<tr v-for="item in data" :key="item._id">
<td v-for="column in columns" class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
<div v-if="column.definition">
<component :is="resolveComponent(column?.definition(item[column.key]).component)" v-bind="column?.definition(item[column.key]).component.props" >
{{ column?.definition(item[column.key]).slot }}
</component>
</div>
<div v-else>{{ item[column.key] }}</div>
</td>
</tr>
</tbody>
如您所见,我想渲染一个组件,其中
:is
属性在 column?.definition(item[column.key]).component
中定义
定义函数返回一个对象,.component 属性包含一个简单的字符串,如下所示
{title: 'Email', key: 'email', definition: (item)=>{return {component: 'GeneralButton', props: {to: item._id}, slot: item}}}
所以这个例子中应该渲染的结果实际上是:
<component :is="resolveComponent('GeneralButton')" ... >
这就是问题所在,当我在其中传递变量时,resolveComponent 不起作用。如果我直接传递相同的字符串(由定义函数返回),效果很好。
我尝试了一些其他选项,但没有一个起作用。最常用的是使用全局组件,因此 GeneralButton 应该是全局的。这种方法有效,但我想创建一个完全可定制的组件,但我实际上不知道将来我想使用哪个组件,所以这对我来说不是一个好的解决方案。 (我还看到了将所有组件设置为全局的建议,我想避免这种导致性能问题的原因)。
另一种方法是覆盖 Nuxt3 自动导入并手动将所需组件导入到 DataTableBody 组件中。这也有效,并且
resolveComponent()
函数比 varibale :is
更有效,但它与前一个有同样的问题,我不知道我将在定义()函数中获得哪个组件。如果有一种方法可以根据变量动态定义导入,那么这实际上应该有效,但我很确定这是不可能的,例如:
import {`$componentToRender`} from '#components' //This does not work and I didnt find any solution which works
实际上有办法做到这一点吗?谢谢:)
您无法将变量传递给resolveComponent()方法。
<template>
<component :is="resolveComponent(aVariableThatHoldsComponentName)" />
This is Not OK ❌
<component :is="resolveComponent('MyComponent')" />
This is OK ✅
<component :is="conditionalComponent" />
This is OK ✅
<component :is="getComponent(key)" />
This is OK ✅
</template>
<script setup>
const aVariableThatHoldsComponentName = 'MyComponent';
const conditionalComponent = computed(() => {
return condition ? resolveComponent('ComponentA') : resolveComponent('ComponentB')
})
const componentMap = {
key1: resolveComponent('MyComponentA'),
key2: resolveComponent('MyComponentB'),
key3: resolveComponent('MyComponentC'),
}
const getComponent = (key) => {
return componentMap[key]
}
const key = "key2";
</script>
但是,如果您的组件是全局的(例如:~/components/global/MyComponentName.vue 或~/components/MyComponent.global.vue),您可以像这样使用它:
<template>
<component :is="aVariableThatHoldsComponentName" />
This is OK ✅
</template>
请注意,只有在确定需要全局组件时才应该使用全局组件,因为即使不使用全局组件,也会在每个页面中导入。