0

I need to check for the existence of a component before dynamically displaying it in Nuxt. The component name is based on a route slug, therefore I can't know in advance if the component name is valid.

If there's no component for the slug, I would like to display a text using v-else. (see markup)

However, I'm not able to infer whether the component is available or not as return value is always a function.

<component :is="componentDynamic" v-if="componentDynamic" />
<h1 v-else>Component Not available</h1>
import Vue from 'vue'
export default Vue.extend({
  computed: {
    componentDynamic() {
      const componentName = this.$route.params.slug,
      const result = async () => await import(`@/components/${componentName}`)
      console.log(result)
      return result
    },
  },
})
Aerodynamic
  • 782
  • 5
  • 19
  • Pretty sure I've already seen this question here. Did you make a search? – kissu Nov 09 '21 at 11:41
  • https://stackoverflow.com/questions/69200097/how-do-i-properly-import-multiple-components-dynamically-and-use-them-in-nuxt https://stackoverflow.com/questions/51358922/load-component-dynamically-based-on-url-parameters-in-nuxt – mahatmanich Nov 09 '21 at 12:29
  • Does this answer your question? [How do I properly import multiple components dynamically and use them in Nuxt?](https://stackoverflow.com/questions/69200097/how-do-i-properly-import-multiple-components-dynamically-and-use-them-in-nuxt) – mahatmanich Nov 09 '21 at 12:29
  • Dynamic imports are not the problem. I should precise that the detection of the existence of a component is what I'm looking for. For example, the component parameter could be "notThere". If the :is= attribute is looking for that component, it won't find it. In that case, I would like to show the text in the v-else statement. However "v-if" doesn't work with 'is:=' for detecting if the component exists. – Aerodynamic Nov 09 '21 at 14:07

2 Answers2

3

Figured out if the component exists by trying to import it via import. If the import errors out, the component is not available and an alternative message is shown.

<template>
  <div>
    <component
      :is="componentName"
      v-if="componentIsAvailable"
    />
    <!-- Show if component doesn't exist -->
    <div v-else>
      <h1 class="text-5xl my-20">Component Not available</h1>
    </div>
  </div>
</template>
    data() {
      return {
        componentIsAvailable: false,
        componentName:  this.$route.params.componentName // nuxt components are in PascalCase, so your parameter / slug should be as well
      }
    },
    async fetch() {
      const name = this.componentName

      this.componentIsAvailable = await import(`@/components/${name}`)
        .then((_res) => {
          // console.log('result', _res)
          return true
        })
        .catch((_error) => {
          // console.log('error', _error)
          return false
        })

    },
Aerodynamic
  • 782
  • 5
  • 19
1

You can use resolveDynamicComponent as the following:

import { resolveDynamicComponent } from 'vue'

const isComponent = (name) => typeof resolveDynamicComponent(name) !== 'string'
Mahmoud
  • 1,703
  • 1
  • 9
  • 13