Vue import component within functional component

Viewed 1239

I have a component called SpotifyButton in the components directory that looks like this:

<template functional>
  <b-button pill size="sm" :href="props.spotifyUri" class="spotify-green">
    <b-img-lazy
      src="~/assets/Spotify_Icon_RGB_White.png"
      height="20"
      width="20"
    />
    View on Spotify
  </b-button>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name: 'SpotifyButton',
  props: {
    spotifyUri: {
      type: String,
      required: true
    }
  }
});
</script>

I'm able to import and use this in a component in the pages directory like so without any problem:

<template>
    <spotify-button :spotify-uri="artist.uri"/>
</template>

<script lang="ts">
import Vue from 'vue';
import { Context } from '@nuxt/types';
import FullArtist from '@/types/FullArtist';
import SpotifyButton from '@/components/SpotifyButton.vue';

export default Vue.extend({
  name: 'ArtistPage',
  components: {
    SpotifyButton
  },
  async asyncData({ $axios, params, error }: Context) {
    try {
      const artist: FullArtist = await $axios.$get(`/api/artists/${params.id}`);
      return { artist };
    } catch (e) {
      error({ statusCode: 404, message: 'Artist not found' });
    }
  },
  data() {
    return {
      artist: {
        name: ''
      } as FullArtist
    };
  }
});
</script>


However if I try to import SpotifyButton into another component in the components directory in the same way, I get the following errordid you register the component correctly error.

Here is the ArtistPreview component, which is in the components directory:

<template functional>
  <spotify-button :spotify-uri="props.artist.uri"/>
</template>

<script lang="ts">
import Vue, { PropType } from 'vue';
import SpotifyButton from '@/components/SpotifyButton.vue';
import SimpleArtist from '@/types/SimpleArtist';

export default Vue.extend({
  name: 'ArtistPreview',
  components: {
    SpotifyButton
  },
  props: {
    artist: {
      type: Object as PropType<SimpleArtist>,
      required: true
    }
  }
});
</script>

Am I missing something? Why does an import that works perfectly fine in a pages directory component not work in a components directory component?

2 Answers

This was happening because I'm using functional components. It turns out you can't nest functional components without doing some funky workarounds. Here's the GitHub issue with a few solutions.

I went with the first solution, so my ArtistPreview component now looks something like this:

<template functional>
  <spotify-button :spotify-uri="props.artist.uri"/>
</template>

<script lang="ts">
import Vue, { PropType } from 'vue';
import SpotifyButton from '@/components/SpotifyButton.vue';
import SimpleArtist from '@/types/SimpleArtist';

Vue.component("spotify-button", SpotifyButton);

export default Vue.extend({
  name: 'ArtistPreview',
  props: {
    artist: {
      type: Object as PropType<SimpleArtist>,
      required: true
    }
  }
});
</script>

Go with:

import SpotifyButton from '~/components/SpotifyButton.vue'

With Typescript is better use another approach: Add 'nuxt-property-decorator' and follow his flow.

So, you define your component as follow:

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'

import SpotifyButton from '~/components/SpotifyButton.vue'

@Component({
  components: {
    SpotifyButton
  },
})
class AnotherComponent extends Vue {
  ...
}
export default AnotherComponent
</script>

[Nuxt Property Decorator on Github][1]

I think is important to read the official [Nuxt Typescript documentation][2] to a proper setup.

I hope it helps!


  [1]: https://github.com/nuxt-community/nuxt-property-decorator
  [2]: https://typescript.nuxtjs.org/
Related