目录
一、组件介绍
1.概念
Vue.js中的组件是可复用的Vue实例,具有自己的模板、逻辑和样式。组件允许开发者将页面分割成独立、可复用的模块,使得代码更易维护、可读性更高。
2.特点
- 模块化: 组件可以根据功能或UI部分进行划分,使得代码更加模块化,易于管理和维护。
- 可复用性: 组件可以被多次使用,不同的页面或应用中都可以引用同一个组件,提高了代码的复用性。
- 独立性: 每个组件都是相互独立的,组件之间的状态和逻辑不会相互影响,有利于代码的解耦和扩展。
- 单文件组件: Vue提供了单文件组件(.vue文件),将组件的模板、样式和逻辑封装在一个文件中,使得组件的结构更清晰,易于维护。
3.作用
- 页面划分: 将页面划分为独立的组件,提高了代码的组织性和可维护性。
- 代码复用: 将常用的UI部分或功能封装成组件,可以在不同的地方重复使用,减少了重复代码的编写。
- 提高开发效率: 组件化开发使得团队协作更加高效,每个成员可以专注于开发独立的组件,提高了开发效率。
4.应用
- Web应用开发: Vue组件广泛应用于Web应用开发中,用于构建各种UI组件、页面布局等。
- 移动应用开发: 结合Vue的移动端框架(如Vue Native、Weex等),可以开发跨平台的移动应用,组件在移动应用中也扮演着重要角色。
- 插件开发: Vue组件可以作为插件独立开发和维护,供其他开发者使用。
5.分类
- UI组件: 用于构建界面的各种UI元素,如按钮、表单、对话框等。
- 功能性组件: 实现特定功能的组件,如轮播图、导航菜单等。
- 布局组件: 用于页面布局的组件,如网格布局、卡片布局等。
- 业务逻辑组件: 实现业务逻辑的组件,如用户登录、购物车功能等。
二、组件语法
1.定义挂载vue应用
每个 Vue 应用都是通过用 createApp 函数创建的,传递给 createApp 的选项用于配置根组件。当我们挂载应用时,该组件被用作渲染的起点。
一个应用需要被挂载到一个 DOM 元素中。
以下实例我们将 Vue 应用挂载到 <div id="app"></div>,应该传入 #app:
const RootComponent = { /* 选项 */ }
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')
2.注册全局组件
注册一个全局组件语法格式如下:
const app = Vue.createApp({...})
app.component('my-component-name', {
/* ... */
})
my-component-name 为组件名,/* ... */ 部分为配置选项。注册后,我们可以使用以下方式来调用组件
<my-component-name></my-component-name>
一个简单的 Vue 组件的实例:
实例
1.自定义组件
<div id="app">
<runoob></runoob>
</div>
<script>
// 创建一个Vue 应用
const app = Vue.createApp({})
// 定义一个名为 runoob的新全局组件
app.component('runoob', {
template: '<h1>自定义组件!</h1>'
})
app.mount('#app')
</script>
2.计数器
// 创建一个Vue 应用
const app = Vue.createApp({})
// 定义一个名为 button-counter 的新全局组件
app.component('button-counter', {
data() {
return {
count: 0
}
},
template: `
<button @click="count++">
点了 {{ count }} 次!
</button>`
})
app.mount('#app')
</script>
3.组件的复用
你可以将组件进行任意次数的复用:
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
4.局部组件
全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。
在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:
const ComponentA = {
/* ... */
}
const ComponentB = {
/* ... */
}
const ComponentC = {
/* ... */
}
然后在 components 选项中定义你想要使用的组件:
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字(component-a、component-b),其属性值就是这个组件的选项对象(ComponentA、ComponentB)。
我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用:
实例
注册一个简单的局部组件 runoobA,并使用它:
<div id="app">
<runoob-a></runoob-a>
</div>
<script>
var runoobA = {
template: '<h1>自定义组件!</h1>'
}
const app = Vue.createApp({
components: {
'runoob-a': runoobA
}
})
app.mount('#app')
</script>
5.Prop
prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。
父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop":
<div id="app">
<site-name title="Google"></site-name>
<site-name title="Runoob"></site-name>
<site-name title="Taobao"></site-name>
</div>
<script>
const app = Vue.createApp({})
app.component('site-name', {
props: ['title'],
template: `<h4>{{ title }}</h4>`
})
app.mount('#app')
</script>
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
6.动态Prop
类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
<div id="app">
<site-info
v-for="site in sites"
:id="site.id"
:title="site.title"
></site-info>
</div>
<script>
const Site = {
data() {
return {
sites: [
{ id: 1, title: 'Google' },
{ id: 2, title: 'Runoob' },
{ id: 3, title: 'Taobao' }
]
}
}
}
const app = Vue.createApp(Site)
app.component('site-info', {
props: ['id','title'],
template: `<h4>{{ id }} - {{ title }}</h4>`
})
app.mount('#app')
</script>
7.Prop 验证
组件可以为 props 指定验证要求。
为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
type 可以是下面原生构造器:
String
Number
Boolean
Array
Object
Date
Function
Symbol
三、创建组件的关键概念和语法
1. 组件定义
在 Vue 中,你可以使用 Vue.component() 方法来定义一个组件。例如:
Vue.component('my-component', {
// 组件选项
})
2. 组件选项
组件选项是一个包含组件配置的对象,它可以包含以下选项:
- data: 一个函数,返回组件的初始数据。每个组件必须将 data 返回为一个对象。
- props: 用于接收父组件传递的数据。可以是数组或对象。
- methods: 包含组件中使用的方法。
- computed: 计算属性,可以根据其他数据的变化自动计算返回值。
- watch: 监听数据变化并执行相应的操作。
- template: 组件的模板,可以是字符串模板、template 元素或单文件组件。
- components: 包含组件引用的对象,用于注册子组件。
- created(): 组件创建时执行的钩子函数。
- mounted(): 组件挂载到 DOM 后执行的钩子函数。
- 等等...
3. 单文件组件
Vue 提供了单文件组件 (.vue),它将模板、样式和逻辑封装在一个文件中。单文件组件通常包含三个部分:
- <template>: 组件的 HTML 模板。
- <script>: 组件的 JavaScript 代码,包含组件选项。
- <style>: 组件的样式。
4. Props
Props 是父组件传递给子组件的数据。子组件通过 props 接收数据并在自己的作用域内使用。例如:
// 父组件
<my-component :message="parentMsg"></my-component>
// 子组件
props: ['message']
5. Emit 事件
子组件可以通过 $emit() 方法触发自定义事件,并且可以传递数据给父组件。父组件可以通过监听子组件的事件来执行相应的操作。例如:
// 子组件
this.$emit('my-event', eventData)
// 父组件
<my-component @my-event="handleEvent"></my-component>
四、总结
-
组件定义与注册:
- 使用 Vue.component() 方法或单文件组件 (.vue) 定义组件。
- 使用 Vue 实例中的 components 选项或局部/全局注册组件。
-
组件通信:
- 使用 Props:父组件向子组件传递数据。
- 使用 Emit 事件:子组件向父组件发送消息。
-
组件生命周期:
- 生命周期钩子函数:created、mounted、updated、destroyed 等。
-
组件选项:
- data: 组件的初始数据。
- props: 接收父组件传递的数据。
- methods: 包含组件中使用的方法。
- computed: 根据其他数据计算返回值的计算属性。
- watch: 监听数据变化并执行相应的操作。
- template: 组件的模板。
- components: 注册子组件。
-
单文件组件:
- 使用 .vue 文件封装组件的模板、样式和逻辑。
-
组件复用与组合:
- 提高代码复用性,将常用的功能封装为组件。
- 使用 mixin 或 extends 实现组件的复用。
- 使用插槽 (slot) 实现组件的组合。
-
动态组件:
- 使用动态组件 (dynamic component) 根据条件渲染不同的组件。
-
组件样式:
- 使用作用域样式 (scoped style) 使样式仅在当前组件中生效。
-
组件库与框架:
- 使用现有的组件库或框架加速开发。
- 如 Element UI、Vuetify、Bootstrap Vue 等。
-
测试与调试:
- 编写单元测试以确保组件功能的正确性。
- 使用 Vue DevTools 调试 Vue.js 应用程序。