1

How can I add components with require.context using ? The rfc for script setup shows this example. In the example, each component has to be imported.

In the Options API I used this code to collect all the components from a particular folder:

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
}

Then I add the resulting components object to the options object passed to defineComponent.

const { components, namesForValidator } = getIconsComponents()

export default defineComponent({
  components,

  // ...
})

All this works fine. But in the it's not clear to me how to make it work. Maybe there is (or is planned) some undocumented defineComponets compiler macros that would solve this problem?

1 Answer 1

1

Solved this problem with the code below.

<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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.