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. 核心选项对比

选项类型说明
nameString组件标识(必填)
propsObject/Array接收父组件数据
dataFunction返回组件状态对象
methodsObject组件方法集合
computedObject计算属性
watchObject监听器

三、组件通信机制

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)

六、最佳实践建议

  1. 命名规范

    • 组件名:PascalCase(MyComponent)
    • 事件名:kebab-case(update-data)
  2. 设计原则

    • 单一职责原则(一个组件只做一件事)
    • 控制组件体积(不超过400行代码)
    • 避免深层嵌套(超过3层应考虑拆分)
  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组件库
  • 实现清晰的代码组织结构
  • 提高项目维护性
  • 促进团队协作开发

进阶学习:下一步可研究:

  1. 异步组件
  2. 递归组件
  3. 动态组件
  4. 过渡动画系统

添加新评论