Skip to content

4. Nuxt 3 使用组件

4.1 创建组件

在 Nuxt 3 中,组件都放置在 components 目录下。Nuxt 3 会自动导入该目录下的所有组件,无需手动注册即可使用。

4.1.1 基本组件

创建一个简单的按钮组件 components/BaseButton.vue

vue
<template>
  <button class="base-button">
    <slot></slot>
  </button>
</template>

<style scoped>
.base-button {
  padding: 8px 16px;
  border-radius: 4px;
  background-color: #4CAF50;
  color: white;
  border: none;
  cursor: pointer;
}
</style>

4.1.2 组件命名规范

  • 单词大写: BaseButton.vue
  • 使用连字符: base-button.vue
  • 使用目录嵌套: base/Button.vue

4.2 组件传值

4.2.1 Props 传值

vue
<!-- components/UserCard.vue -->
<script setup lang="ts">
interface Props {
  name: string
  age?: number
}

defineProps<Props>()
</script>

<template>
  <div class="user-card">
    <h3>{{ name }}</h3>
    <p>Age: {{ age ?? 0 }}</p>
  </div>
</template>

使用组件:

vue
<template>
  <UserCard name="John Doe" :age="25" />
</template>

4.2.2 事件传递

vue
<!-- components/SearchInput.vue -->
<script setup lang="ts">
interface Emits {
  (event: 'search', value: string): void
}

const emit = defineEmits<Emits>()

const handleSearch = (event: Event): void => {
  emit('search', (event.target as HTMLInputElement).value)
}
</script>

<template>
  <input 
    type="text" 
    @input="handleSearch"
    placeholder="Search..." 
  />
</template>

4.3 动态组件

vue
<template>
  <component :is="currentComponent" />
</template>

<script setup lang="ts">
import { ref } from 'vue'

type ComponentName = 'UserCard' | 'SearchInput'
const currentComponent = ref<ComponentName>('UserCard')
</script>

4.4 异步组件

Nuxt 3 支持使用 lazy 前缀实现组件懒加载:

vue
<template>
  <LazyUserCard name="John" :age="25" />
</template>

4.5 组件生命周期

在 Nuxt 3 中,可以使用 Vue 3 的组合式 API 来处理生命周期:

vue
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'

onMounted((): void => {
  console.log('Component mounted')
})

onUnmounted((): void => {
  console.log('Component unmounted')
})
</script>

4.6 最佳实践

  1. 保持组件单一职责
  2. 使用 Props 验证
  3. 合理使用插槽(slots)
  4. 适时使用异步组件
  5. 注意组件的性能优化

4.7 常见问题

4.7.1 组件不自动导入

检查以下几点:

  • 组件文件是否在 components 目录下
  • 文件名是否符合规范
  • nuxt.config.ts 中是否禁用了自动导入功能