typescriptvue.jsnuxt.jsnuxt3.js

How can I auto import component from @vueuse/component in nuxt 3


I'm new in nuxt 3, I want to auto import the component from @vueuse/component in nuxt 3, I have following this documentation but I still didn't get it why the auto import component from third party package is not working. this is my file nuxt.config.ts & my file app.vue

nuxt.config.ts

export default defineNuxtConfig({
  modules: ["@vueuse/nuxt"],
  imports: {
    presets: [
      {
        from: "@vueuse/components",
        imports: ["UseWindowSize"], // I want to auto import this, I change to `UseWindowSize` or `*` still not working
      },
    ],
  },
})

app.vue

<template>
    <UseWindowSize v-slot="{ width, height }">
          <div :style="{ height: `${height - 265}px` }"></div>
    </UseWindowSize>
  </template>

I take a look at the .nuxt/imports.d.ts yes it is imported imported component in file .nuxt/imports.d.ts

but when I try to call it in my app.vue it getting error like this

[Vue warn]: Failed to resolve component: UseWindowSize
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 

when I try to import it manual inside app.vue it's working, is that possible the component auto import globally? Thanks..


Solution

  • PREREQUISITES

    First, install @vueuse/components with npm install --save @vueuse/components.

    NOTE: I see you must have already done that, since you are saying that the component works if you import it manually. I will leave it in the solution though, to help people dealing with similar issues, as this step could be easily overlooked.

    At this point you can already use components from @vueuse/components in your app but you have to import them manually:

    <template>
      <UseWindowSize v-slot="{ width, height }">
        <!-- some content -->
      </UseWindowSize>
    </template>
    
    <script lang="ts" setup>
    import { UseWindowSize } from '@vueuse/components'
    </script>
    

    THE SOLUTION

    Next, let's make the auto-imports work. Add a local module that will auto-import this component:

    // modules/importVueUseComponents/index.ts
    import { addComponent, defineNuxtModule } from '@nuxt/kit'
    
    export default defineNuxtModule({
      setup() {
        addComponent({
          name: 'UseWindowSize',
          export: 'UseWindowSize',
          filePath: '@vueuse/components',
        })
      },
    })
    

    ... and then use it without importing it:

    // app.vue or any component in your Nuxt app, you no longer need to
    // import UseWindowSize component
    <template>
      <UseWindowSize v-slot="{ width, height }">
        <!-- some content -->
      </UseWindowSize>
    </template>
    

    You might need to re-run npm run dev for the above local module to work. Also, you would need to add appropriate addComponent call for every component from @vueuse/components you want to auto-import.

    I do understand that it is not perfect, but I don't think there is an alternative. Personally, I will just keep importing these components manually, hoping that the nuxt module @vueuse/nuxt takes care of the auto-imports in the future.

    MORE CONTEXT

    I was dealing with exactly the same issue you are dealing with, and I came across your question when googling! It inspired me to dig a little bit more into this.

    This issue has several causes, which I will try to cover one by one.

    1. @vueuse/components is not a dependency of vueuse's nuxt module @vueuse/nuxt. It is NOT installed when you add @vueuse/nuxt module to your project.

    You can verify that with the following command:

    > npm list @vueuse/components
    nuxt-app@1.0.0 /path/to/your/project
    └── (empty)
    

    As a result, you have to install @vueuse/components yourself with e.g. npm install --save @vueuse/components.

    Now you should be able to use components from vueuse in your app, but you have to import them manually in the file you are using them:

    <template>
      <UseWindowSize v-slot="{ width, height }">
        <!-- some content -->
      </UseWindowSize>
    </template>
    
    <script lang="ts" setup>
    import { UseWindowSize } from '@vueuse/components'
    </script>
    

    Regarding components' auto-imports, continue reading next points.

    1. @vueuse/nuxt module doesn't auto-import components. Instead, it only auto-imports composables from @vueuse/core. It doesn't seem to be a bug - it seems it is simply not implemented in the nuxt module. We can see it upon module's code inspection here.

    Whether this is intentional or a simple oversight from the module's authors is not clear to me.

    1. Property imports in nuxt.config.ts is for auto-importing composables only, not components - source. There is another property for configuring components auto-imports - components (source one, source two).

    Unfortunately, this components property doesn't seem to be able to auto-import components from npm packages. If we want to auto-import components from @vueuse/components we need to use use addComponent in a local module (source).

    In your scenario, you could create file modules/importVueUseComponents/index.ts in your project with below contents:

    import { addComponent, defineNuxtModule } from '@nuxt/kit'
    
    export default defineNuxtModule({
      setup() {
        addComponent({
          name: 'UseWindowSize',
          export: 'UseWindowSize',
          filePath: '@vueuse/components',
        })
      },
    })
    

    After re-running npm run dev, your component should be auto-imported. Hope this helps!