组件是 Vue 最强大的功能之一。它让你可以将页面拆分成独立、可复用的模块,每个模块管理自己的状态和逻辑。就像搭积木一样,用小组件构建复杂的应用。
理解组件化思想,是掌握 Vue 开发的关键一步。从简单的按钮、输入框,到复杂的表单、列表,都可以封装成组件,提高代码的可维护性和复用性。
组件本质上是一个拥有预定义选项的 Vue 实例。它可以:
<!-- 定义一个简单的组件 -->
<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')
}
}
})
如何拆分组件?
看到一个页面,问自己几个问题:
以一个博客文章页面为例:
├── 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', { /* ... */ })
// ❌ 错误:与原生元素冲突
Vue.component('header', { /* ... */ })
Vue.component('footer', { /* ... */ })
// ✅ 正确:添加前缀
Vue.component('app-header', { /* ... */ })
Vue.component('app-footer', { /* ... */ })
组件化开发需要转变思维:
掌握组件基础后,你将能够构建更复杂、更易维护的应用。