你想系统掌握 Vue 3 组件的核心用法,包括组件定义、引入、传值、插槽、生命周期等开发必备知识,我会用最简洁、实用的方式带你学会 Vue 3 组件开发。
一、什么是 Vue 3 组件?
组件是 Vue 中可复用的代码块,把页面拆分成独立的小模块(如头部、按钮、列表、弹窗),每个组件有自己的结构、样式和逻辑,方便维护和复用。
Vue 3 推荐使用 <script setup> 语法(官方标准写法,代码更简洁)。
二、基础组件写法(最常用)
1. 单个组件文件(.vue)
Vue 组件由三部分组成:
<template>:HTML 结构<script setup>:JS 逻辑<style>:CSS 样式
vue
<!-- components/MyButton.vue -->
<template>
<!-- 模板:组件的 HTML 结构 -->
<button class="my-btn" @click="handleClick">
{{ btnText }}
</button>
</template>
<!-- script setup:Vue3 组合式API 语法糖 -->
<script setup>
// 1. 定义数据
const btnText = '点击我'
// 2. 定义方法
const handleClick = () => {
alert('按钮被点击了!')
}
</script>
<!-- scoped:样式只作用于当前组件,不污染全局 -->
<style scoped>
.my-btn {
padding: 8px 16px;
background: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
三、组件的引入与使用
在父组件中导入、注册、使用子组件:
vue
<script setup>
// 1. 导入子组件
import MyButton from './components/MyButton.vue'
// 2. 无需注册!script setup 会自动注册
</script>
<!-- App.vue(父组件) -->
<template>
<div>
<h1>Vue 3 组件演示</h1>
<!-- 3. 使用子组件(直接用标签形式) -->
<MyButton />
<MyButton />
</div>
</template>
✅ 特点:导入后直接当标签用,无需 components 注册。
四、组件传值(核心通信)
组件之间不能直接共享数据,需要用传值机制:
1. 父传子:props(最常用)
父组件给子组件传递数据/参数。
子组件接收(MyButton.vue)
vue
<script setup>
// 接收父组件传过来的值
const props = defineProps({
text: {
type: String,
default: '默认按钮'
},
type: {
type: String,
default: 'primary'
}
})
</script>
<template>
<button :class="type">{{ text }}</button>
</template>
父组件传递(App.vue)
vue
<script setup>
import MyButton from './components/MyButton.vue'
</script>
<template>
<MyButton text="确认按钮" type="success" />
<MyButton text="取消按钮" type="danger" />
</template>
2. 子传父:defineEmits
子组件向父组件发送消息/事件。
子组件发送(MyButton.vue)
vue
<script setup>
// 接收父组件传过来的值
const props = defineProps({
text: {
type: String,
default: '默认按钮'
},
type: {
type: String,
default: 'primary'
}
})
// 定义要触发的事件名
const emit = defineEmits(['btn-click'])
const handleClick = () => {
// 向父组件传值
emit('btn-click', '子组件的消息')
}
</script>
<template>
<button @click="handleClick" :class="type">{{ text }}</button>
</template>
父组件接收(App.vue)
vue
<script setup>
import { ref } from 'vue'
// 引入子组件
import MyButton from './MyButton.vue'
// 存储子组件传递的数据
const msg = ref('')
const getChildMsg = (data) => {
msg.value = data
console.log('子组件说:', data)
}
</script>
<template>
<div class="parent">
<h2>父组件</h2>
<p>接收子组件数据:{{ msg }}</p>
<MyButton @btn-click="getChildMsg" text="确认按钮" type="success" />
</div>
</template>
五、插槽(slot):内容分发
让父组件给子组件传递 HTML 结构,让组件更灵活。
1. 默认插槽
子组件(Card.vue)
vue
<template>
<div class="card">
<!-- 插槽:父组件的内容会放在这里 -->
<slot>默认内容</slot>
</div>
</template>
父组件使用
vue
<Card>
<h3>我是插槽内容</h3>
<p>这是父组件写的 HTML</p>
</Card>
2. 具名插槽(多个插槽)
vue
<!-- 子组件 -->
<slot name="header"></slot>
<slot name="content"></slot>
<!-- 父组件 -->
<Card>
<template #header>
标题部分
</template>
<template #content>
内容部分
</template>
</Card>
六、Vue 3 组件常用生命周期(组合式 API)
组件从创建到销毁的过程,常用钩子:
vue
<script setup>
import { onMounted, onUpdated, onUnmounted } from 'vue'
// 组件挂载完成(DOM 渲染完毕,请求数据用这个)
onMounted(() => {
console.log('组件渲染完成')
// 这里可以发接口请求
})
// 组件更新时
onUpdated(() => {})
// 组件销毁时(清除定时器/事件监听)
onUnmounted(() => {})
</script>
七、全局组件(一次注册,全项目使用)
在 main.js 中注册,所有组件无需导入直接使用:
javascript
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import MyButton from './components/MyButton.vue'
const app = createApp(App)
// 注册全局组件
app.component('MyButton', MyButton)
app.mount('#app')
八、组件核心总结
- 组件拆分:页面拆成小模块,复用+维护更简单
- script setup:Vue 3 官方推荐写法,代码最简
- 通信方式 :
- 父 → 子:
defineProps - 子 → 父:
defineEmits
- 父 → 子:
- 插槽 :
slot传递 HTML 结构 - 生命周期 :
onMounted最常用(请求数据)