Nuxt3 components目录学习

2,269 阅读1分钟

组件名称

Nuxt3中的组件全部都放在/components目录下,并自动注册,组件名称为目录名+组件名,并以大驼峰式命名,重复的名称会被去除。如

image.png

<template>
    <div class="header">
        <LayoutHeader></LayoutHeader>
    </div>
    <div class="container">
        <slot></slot>
    </div>
    <div class="footer">
        <LayoutFooter></LayoutFooter>
    </div>
</template>

动态导入

<template>
    <div class="header">
        <button v-if="!show" @click="show = true">Show Header</button>
        <LazyLayoutHeader v-if="show"></LazyLayoutHeader>
    </div>
    <div class="container">
        <slot></slot>
    </div>
    <div class="footer">
        <LayoutFooter></LayoutFooter>
    </div>
</template>

<script>
export default {
    data() {
        return {
            show: false
        }
    }
}
</script>

在组件名称前加入前缀Lazy,使组件成动态加载,监视network,当show为true时,LayoutHeader组件才加载。

image.png

客户端组件

使用Nuxt3内置组件ClientOnly包裹组件,使得被包裹组件只在客户端渲染,并以fallback插槽的形式加入默认样式。

<template>
    <div class="footer">
        <ClientOnly>
            <LayoutFooter></LayoutFooter>
            <template #fallback>
                <p>Loading comments...</p>
            </template>
        </ClientOnly>  
    </div>
</template>

刷新页面可发现,页面从Loading comments变成footer组件样式。

注意:因为footer组件只从mounted生命周期后由客户端渲染,所有mounted之前的生命周期内都无法获得浏览器环境。

库作者

Nuxt3.js官网显示构建如下路径结构,创建nuxt.js内容如下便可引入第三方组件库,此内容我还没有成功验证,验证成功后后续补上。

| node_modules/
---| awesome-ui/
------| components/
---------| Alert.vue
---------| Button.vue
------| nuxt.js
| pages/
---| index.vue
| nuxt.config.js

awesome-ui/nuxt.js

import { join } from 'pathe'
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  hooks: {
    'components:dirs'(dirs) {
      // Add ./components dir to the list
      dirs.push({
        path: join(__dirname, 'components'),
        prefix: 'awesome'
      })
    }
  }
})

nuxt.config.ts

export default {
  buildModules: ['awesome-ui/nuxt']
}

pages/index.vue

<template>
  <div>
    My <AwesomeButton>UI button</AwesomeButton>!
    <awesome-alert>Here's an alert!</awesome-alert>
  </div>
</template>