Vue.js 组件是 Vue 框架中的核心概念之一。通过组件,开发者可以将应用划分为独立、可复用的部分。每个组件可以包含自己的模板、数据、逻辑和样式,像搭积木一样构建整个应用。
为什么要用组件?
组件的好处在于:
- 复用性:可以在不同地方多次使用同一个组件。
- 模块化:让代码更有组织,逻辑更清晰。
- 维护性:每个组件只负责自己的一部分功能,方便独立维护。
组件的基础结构
一个 Vue 组件由模板(template)、脚本(script)、和样式(style)构成。它们可以放在一个 .vue
文件里,或者直接通过 Vue 的 component
方法来注册。
1. 全局组件定义
这是定义组件最基本的方式,直接用 Vue.component
来注册一个全局组件,所有的地方都可以使用它。
例子:简单的全局组件
html
复制代码
<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> </head> <body> <div id="app"> <!-- 使用组件 --> <hello-world></hello-world> </div> <script> // 定义全局组件 Vue.component('hello-world', { template: '<h1>Hello, Vue!</h1>' }); // 创建 Vue 实例 new Vue({ el: '#app' }); </script> </body> </html>
这个例子定义了一个名为 hello-world
的全局组件,显示了一行简单的 Hello, Vue!
。在任何地方都可以使用这个组件。
2. 局部组件定义
局部组件只在特定的 Vue 实例中可用。如果你不需要全局注册组件,局部组件更适合。
例子:局部组件
html
复制代码
<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> </head> <body> <div id="app"> <!-- 使用局部组件 --> <custom-message></custom-message> </div> <script> var app = new Vue({ el: '#app', components: { 'custom-message': { template: '<p>This is a custom message!</p>' } } }); </script> </body> </html>
这里的 custom-message
组件只在 #app
这个 Vue 实例中可以使用。
3. 组件中的 data
属性
每个组件都有自己的状态(数据),通过 data
函数返回一个对象来定义组件的数据。
例子:带数据的组件
html
复制代码
<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> </head> <body> <div id="app"> <!-- 使用组件 --> <counter></counter> </div> <script> // 定义带有数据的组件 Vue.component('counter', { template: '<button @click="count++">点击次数:{{ count }}</button>', data: function() { return { count: 0 } } }); new Vue({ el: '#app' }); </script> </body> </html>
每次点击按钮,组件内部的 count
数据都会自增。这里 data
必须是一个函数,确保每个组件实例都有自己独立的数据。
4. 组件的 props
传递数据
props
是 Vue 组件接收外部数据的方式,它允许父组件向子组件传递数据。
例子:使用 props
html
复制代码
<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> </head> <body> <div id="app"> <!-- 使用组件,并传递属性 --> <greeting-message name="Tom"></greeting-message> </div> <script> Vue.component('greeting-message', { props: ['name'], // 接收父组件传递的属性 template: '<p>Hello, {{ name }}!</p>' }); new Vue({ el: '#app' }); </script> </body> </html>
在这个例子中,name
是从父组件传递到子组件的 props
,因此子组件能显示个性化的消息。
5. 组件通信:父子组件之间的事件
子组件可以通过 $emit
触发事件,通知父组件执行一些操作。
例子:子组件触发事件
html
复制代码
<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> </head> <body> <div id="app"> <!-- 使用组件,并监听事件 --> <like-button @liked="handleLike"></like-button> </div> <script> Vue.component('like-button', { template: '<button @click="likePost">点赞</button>', methods: { likePost: function() { this.$emit('liked'); // 触发父组件的 'liked' 事件 } } }); new Vue({ el: '#app', methods: { handleLike: function() { alert('你点赞了这篇文章!'); } } }); </script> </body> </html>
在这个例子中,子组件 like-button
通过 $emit
向父组件发送 liked
事件,父组件捕获这个事件后,执行 handleLike
方法。
6. 插槽(Slots)
插槽允许父组件向子组件传递任意内容,而不仅仅是通过 props
传递数据。
例子:插槽的使用
html
复制代码
<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> </head> <body> <div id="app"> <!-- 使用组件,并在插槽中传递内容 --> <custom-card> <h2>我是标题</h2> <p>这是一些描述内容</p> </custom-card> </div> <script> Vue.component('custom-card', { template: ` <div class="card"> <slot></slot> <!-- 插槽会显示父组件传递的内容 --> </div> ` }); new Vue({ el: '#app' }); </script> </body> </html>
这里 slot
就是插槽,它允许父组件传递的内容嵌入到子组件的指定位置。
总结:
Vue 组件就是将页面的不同功能模块拆分成一个个小块,每个小块都有自己的模板、逻辑和样式。通过组件化开发,代码更加清晰、易维护,并且大大提高了代码的复用性。