组件基础

组件是 Vue 最强大的功能之一。它让你可以将页面拆分成独立、可复用的模块,每个模块管理自己的状态和逻辑。就像搭积木一样,用小组件构建复杂的应用。

理解组件化思想,是掌握 Vue 开发的关键一步。从简单的按钮、输入框,到复杂的表单、列表,都可以封装成组件,提高代码的可维护性和复用性。

什么是组件

组件本质上是一个拥有预定义选项的 Vue 实例。它可以:

  • 拥有自己的模板、数据、方法
  • 接收外部传入的数据(props)
  • 向外部发送事件($emit)
  • 被多次复用,相互独立
<!-- 定义一个简单的组件 -->
<div id="app">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

<script>
Vue.component('button-counter', {
  data: function() {
    return {
      count: 0
    }
  },
  template: '<button @click="count++">点击了 {{ count }} 次</button>'
})

new Vue({ el: '#app' })
</script>

三个按钮各自维护自己的 count,互不干扰。这就是组件的独立性。

为什么需要组件化

代码复用

相同的 UI 和逻辑,封装成组件后可以在多处使用:

<!-- 用户头像组件 -->
<user-avatar :user="user1"></user-avatar>
<user-avatar :user="user2"></user-avatar>
<user-avatar :user="user3"></user-avatar>

关注点分离

每个组件只关注自己的逻辑,代码更清晰:

// 用户列表组件只关心用户数据
Vue.component('user-list', {
  props: ['users'],
  template: '...'
})

// 分页组件只关心分页逻辑
Vue.component('pagination', {
  props: ['total', 'current'],
  template: '...'
})

易于维护

修改某个功能,只需要改对应的组件,不会影响其他部分。

团队协作

不同开发者可以负责不同的组件,并行开发。

组件的基本结构

一个完整的组件通常包含:

Vue.component('my-component', {
  // 模板
  template: '<div>{{ message }}</div>',
  
  // 数据(必须是函数)
  data: function() {
    return {
      message: 'Hello'
    }
  },
  
  // 接收外部数据
  props: {
    title: String
  },
  
  // 计算属性
  computed: {
    reversedMessage: function() {
      return this.message.split('').reverse().join('')
    }
  },
  
  // 方法
  methods: {
    doSomething: function() {
      console.log('doing something')
    }
  },
  
  // 生命周期钩子
  created: function() {
    console.log('组件创建完成')
  },
  
  // 监听器
  watch: {
    message: function(newVal, oldVal) {
      console.log('message changed')
    }
  }
})

本章内容

  • 组件的定义:学习如何创建组件,理解 data 为什么必须是函数
  • 组件的注册:全局注册与局部注册的区别和使用场景
  • 组件的复用:组件实例的独立性,避免数据污染
  • 组件的组织:组件嵌套和组件树的概念

组件化思维

如何拆分组件?

看到一个页面,问自己几个问题:

  1. 哪些部分是重复的? → 提取成可复用组件
  2. 哪些部分是独立的? → 封装成独立组件
  3. 哪些部分逻辑复杂? → 拆分成更小的组件

以一个博客文章页面为例:

├── ArticlePage(文章页)
│   ├── ArticleHeader(文章头部)
│   │   ├── AuthorInfo(作者信息)
│   │   └── ArticleMeta(文章元信息)
│   ├── ArticleContent(文章内容)
│   ├── CommentList(评论列表)
│   │   └── CommentItem(评论项)
│   └── Pagination(分页)

组件命名规范

组件命名遵循几个原则:

使用短横线分隔

// ✅ 推荐
Vue.component('my-component', { /* ... */ })
Vue.component('user-avatar', { /* ... */ })

// ❌ 避免(可能导致冲突)
Vue.component('mycomponent', { /* ... */ })

使用语义化名称

// ✅ 推荐
Vue.component('todo-item', { /* ... */ })
Vue.component('user-profile', { /* ... */ })

// ❌ 避免
Vue.component('item1', { /* ... */ })
Vue.component('comp', { /* ... */ })

避免与 HTML 元素冲突

// ❌ 错误:与原生元素冲突
Vue.component('header', { /* ... */ })
Vue.component('footer', { /* ... */ })

// ✅ 正确:添加前缀
Vue.component('app-header', { /* ... */ })
Vue.component('app-footer', { /* ... */ })

学习建议

组件化开发需要转变思维:

  1. 从页面到组件:不再是一个大页面,而是多个小组件组合
  2. 从全局到局部:每个组件管理自己的状态,减少耦合
  3. 从实现到接口:关注组件的输入(props)和输出(events)

掌握组件基础后,你将能够构建更复杂、更易维护的应用。