如何在“<script setup>”中定义带有"require.context"的组件?
How to define components with "require.context" in "<script setup>"?
如何使用 require.context 添加组件?
script setup shows this 示例的 rfc。在示例中,必须导入每个组件。
在选项 API 中,我使用此代码从特定文件夹收集所有组件:
function getComponents() {
const context = require.context('../icons', true, /Icon[A-Z]\w+\.vue$/)
const res = {
components: {},
namesForValidator: [],
}
for (const key of context.keys()) {
const match = key.match(/\/(\w+)\.\w+$/)
if (match && match[1]) {
const name = kebabCase(match[1])
res.components[name] = context(key).default
res.namesForValidator.push(name)
}
}
return res
}
然后我将生成的组件对象添加到传递给 defineComponent 的选项对象中。
const { components, namesForValidator } = getIconsComponents()
export default defineComponent({
components,
// ...
})
一切正常。
但是我不清楚如何让它发挥作用。
也许有(或计划)一些未记录的 defineComponets 编译器宏可以解决这个问题?
使用下面的代码解决了这个问题。
<template>
<component :is="icon" />
</template>
<script lang="ts" setup>
import { kebabCase } from '@/helpers'
import { computed, toRefs } from 'vue'
import type { DefineComponent } from 'vue'
export interface IconComponentsList {
components: Record<string, DefineComponent>
}
function getIconsComponents(): IconComponentsList {
const context = require.context('../icons', true, /Icon[A-Z]\w+\.vue$/)
const res = {
components: {} as Record<string, DefineComponent>,
}
for (const key of context.keys()) {
const match = key.match(/\/(\w+)\.\w+$/)
if (match && match[1] && typeof match[1] === 'string') {
const name = kebabCase(match[1].replace('Icon', ''))
res.components[name] = context(key).default
}
}
return res
}
const { components }: IconComponentsList = getIconsComponents()
const { name } = toRefs(defineProps({
name: {
type: String,
required: true,
},
}))
const icon = computed(() => {
return components[name]
})
</script>
如何使用 require.context 添加组件? script setup shows this 示例的 rfc。在示例中,必须导入每个组件。
在选项 API 中,我使用此代码从特定文件夹收集所有组件:
function getComponents() {
const context = require.context('../icons', true, /Icon[A-Z]\w+\.vue$/)
const res = {
components: {},
namesForValidator: [],
}
for (const key of context.keys()) {
const match = key.match(/\/(\w+)\.\w+$/)
if (match && match[1]) {
const name = kebabCase(match[1])
res.components[name] = context(key).default
res.namesForValidator.push(name)
}
}
return res
}
然后我将生成的组件对象添加到传递给 defineComponent 的选项对象中。
const { components, namesForValidator } = getIconsComponents()
export default defineComponent({
components,
// ...
})
一切正常。 但是我不清楚如何让它发挥作用。 也许有(或计划)一些未记录的 defineComponets 编译器宏可以解决这个问题?
使用下面的代码解决了这个问题。
<template>
<component :is="icon" />
</template>
<script lang="ts" setup>
import { kebabCase } from '@/helpers'
import { computed, toRefs } from 'vue'
import type { DefineComponent } from 'vue'
export interface IconComponentsList {
components: Record<string, DefineComponent>
}
function getIconsComponents(): IconComponentsList {
const context = require.context('../icons', true, /Icon[A-Z]\w+\.vue$/)
const res = {
components: {} as Record<string, DefineComponent>,
}
for (const key of context.keys()) {
const match = key.match(/\/(\w+)\.\w+$/)
if (match && match[1] && typeof match[1] === 'string') {
const name = kebabCase(match[1].replace('Icon', ''))
res.components[name] = context(key).default
}
}
return res
}
const { components }: IconComponentsList = getIconsComponents()
const { name } = toRefs(defineProps({
name: {
type: String,
required: true,
},
}))
const icon = computed(() => {
return components[name]
})
</script>