Vue 组件基础
组件(Component)是 Vue 最强大的功能之一。组件可以将 UI 拆分为独立可复用的 pieces,并让你对每个 piece 进行独立开发。
什么是组件?
组件是可复用的 Vue 实例,拥有独立的模板、逻辑和样式。比如,一个按钮组件可以在多个地方使用:
<MyButton />
<MyButton />
<MyButton />
创建组件
单文件组件
Vue 推荐使用单文件组件(.vue)来组织代码:
<!-- MyComponent.vue -->
<script setup>
// 组件逻辑
</script>
<template>
<!-- 组件模板 -->
</template>
<style scoped>
/* 组件样式 */
</style>
组件命名规范
- PascalCase(帕斯卡命名):推荐,如
MyComponent - kebab-case(短横线命名):HTML 中使用,如
my-component
注册组件
全局注册
在 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>
import MyButton from './components/MyButton.vue'
import MyCard from './components/MyCard.vue'
</script>
<template>
<MyButton />
<MyCard />
</template>
使用组件
基本用法
<!-- App.vue -->
<script setup>
import MyComponent from './components/MyComponent.vue'
</script>
<template>
<MyComponent />
</template>
传递 Props
父组件向子组件传递数据:
<!-- 子组件: MyButton.vue -->
<script setup>
defineProps({
text: {
type: String,
default: '按钮'
},
type: {
type: String,
default: 'primary'
}
})
</script>
<template>
<button :class="type">{{ text }}</button>
</template>
<style scoped>
.primary {
background: #42b883;
color: white;
}
.secondary {
background: #666;
color: white;
}
</style>
<!-- 父组件 -->
<template>
<MyButton text="登录" type="primary" />
<MyButton text="取消" type="secondary" />
</template>
监听事件
子组件向父组件传递消息:
<!-- 子组件: MyDialog.vue -->
<script setup>
const emit = defineEmits(['close', 'confirm'])
function handleClose() {
emit('close')
}
</script>
<template>
<div class="dialog">
<p>这是一个对话框</p>
<button @click="handleClose">关闭</button>
</div>
</template>
<!-- 父组件 -->
<template>
<MyDialog @close="handleClose" @confirm="handleConfirm" />
</template>
<script setup>
function handleClose() {
console.log('对话框关闭')
}
function handleConfirm() {
console.log('确认')
}
</script>
组件示例:计数器
<!-- Counter.vue -->
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
</script>
<template>
<div class="counter">
<h3>计数器: {{ count }}</h3>
<button @click="increment">增加</button>
</div>
</template>
<style scoped>
.counter {
text-align: center;
padding: 20px;
}
button {
padding: 8px 16px;
background: #42b883;
color: white;
border: none;
cursor: pointer;
}
</style>
组件示例:用户卡片
<!-- UserCard.vue -->
<script setup>
defineProps({
name: String,
email: String,
avatar: String
})
</script>
<template>
<div class="user-card">
<img :src="avatar || 'https://via.placeholder.com/100'" alt="头像" />
<h3>{{ name }}</h3>
<p>{{ email }}</p>
</div>
</template>
<style scoped>
.user-card {
text-align: center;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
max-width: 200px;
}
img {
width: 100px;
height: 100px;
border-radius: 50%;
}
</style>
<!-- 使用 -->
<template>
<UserCard
name="张三"
email="[email protected]"
avatar="https://i.pravatar.cc/100"
/>
</template>
小结
本章我们学习了 Vue 组件的基础知识:
- 组件概念:可复用的 Vue 实例
- 单文件组件:.vue 文件格式
- 组件注册:全局和局部注册
- Props 传递:父组件向子组件传数据
- 事件监听:子组件向父组件传消息
练习
- 创建一个 ProductsList 组件,显示商品列表
- 创建一个 Modal 组件,支持 open 和 close 事件
- 创建一个 FormInput 组件,支持 label 和 error 属性
准备好进入下一章,学习组件通信的内容了吗?