Vue2极简教程009-组件基础
Vue2极简教程009:组件基础完全指南
一、组件核心概念
1. 什么是Vue组件?
Vue组件是可复用的Vue实例,包含:
- 专属的HTML模板
- 独立的JavaScript逻辑
- 可选的CSS样式
- 通过props接收外部数据
- 通过events与父组件通信
2. 组件注册方式
全局注册(慎用)
// main.js
Vue.component('my-button', {
template: '<button @click="$emit(\'click\')">全局按钮</button>'
})
局部注册(推荐)
// MyButton.vue
export default {
name: 'MyButton',
template: '<button class="btn"><slot></slot></button>'
}
// 父组件中使用
import MyButton from './MyButton.vue'
export default {
components: {
MyButton
}
}
二、组件基础结构
1. 单文件组件(SFC)规范
<template>
<!-- 必须有一个根元素 -->
<div class="component-root">
<h2>{{ title }}</h2>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'MyComponent', // 组件名(必填)
props: {
title: String
},
data() {
return {
localData: '组件内部状态'
}
}
}
</script>
<style scoped>
.component-root {
border: 1px solid #eee;
}
</style>
2. 核心选项对比
选项 | 类型 | 说明 |
---|---|---|
name | String | 组件标识(必填) |
props | Object/Array | 接收父组件数据 |
data | Function | 返回组件状态对象 |
methods | Object | 组件方法集合 |
computed | Object | 计算属性 |
watch | Object | 监听器 |
三、组件通信机制
1. Props向下传递
// 子组件定义
props: {
// 基础类型检查
count: Number,
// 复杂验证
userInfo: {
type: Object,
required: true,
validator: value => value.id !== undefined
}
}
2. Events向上通知
<!-- 子组件 -->
<button @click="$emit('update', newValue)">提交</button>
<!-- 父组件 -->
<child-component @update="handleUpdate"></child-component>
3. 双向绑定简化(.sync)
<!-- 父组件 -->
<child :title.sync="pageTitle"></child>
<!-- 等价于 -->
<child
:title="pageTitle"
@update:title="val => pageTitle = val">
</child>
四、插槽(Slot)系统
1. 基础插槽
<!-- 组件定义 -->
<div class="card">
<slot>默认内容</slot>
</div>
<!-- 使用 -->
<my-card>自定义内容</my-card>
2. 具名插槽
<!-- 组件定义 -->
<div class="layout">
<header><slot name="header"></slot></header>
<main><slot></slot></main>
</div>
<!-- 使用 -->
<app-layout>
<template v-slot:header>
<h1>页面标题</h1>
</template>
<p>主要内容</p>
</app-layout>
3. 作用域插槽
<!-- 组件定义 -->
<ul>
<li v-for="item in items">
<slot :item="item">{{ item.name }}</slot>
</li>
</ul>
<!-- 使用 -->
<item-list :items="users">
<template v-slot:default="slotProps">
{{ slotProps.item.id }} - {{ slotProps.item.name }}
</template>
</item-list>
五、生命周期图示
graph TD
A[创建阶段] --> B(beforeCreate)
B --> C(created)
C --> D[挂载阶段]
D --> E(beforeMount)
E --> F(mounted)
F --> G[更新阶段]
G --> H(beforeUpdate)
H --> I(updated)
I --> J[销毁阶段]
J --> K(beforeDestroy)
K --> L(destroyed)
六、最佳实践建议
命名规范:
- 组件名:PascalCase(MyComponent)
- 事件名:kebab-case(update-data)
设计原则:
- 单一职责原则(一个组件只做一件事)
- 控制组件体积(不超过400行代码)
- 避免深层嵌套(超过3层应考虑拆分)
性能优化:
// 函数式组件(无状态) Vue.component('functional-button', { functional: true, render(h, context) { return h('button', '点击我') } })
七、常见问题解决
1. 组件模板必须单根元素
<!-- Vue2解决方案 -->
<template>
<div><!-- 根元素 -->
<h1>标题</h1>
<p>内容</p>
</div>
</template>
<!-- Vue3支持多根 -->
2. 样式污染问题
<!-- 使用scoped -->
<style scoped>
.btn { /* 只作用于当前组件 */ }
</style>
<!-- 深度作用选择器 -->
<style scoped>
::v-deep .el-input { /* 影响子组件 */ }
</style>
3. 动态组件切换
<component :is="currentComponent"></component>
<script>
export default {
data() {
return {
currentComponent: 'ComponentA'
}
}
}
</script>
通过掌握这些组件基础知识,你可以:
- 构建可复用的UI组件库
- 实现清晰的代码组织结构
- 提高项目维护性
- 促进团队协作开发
进阶学习:下一步可研究:
- 异步组件
- 递归组件
- 动态组件
- 过渡动画系统