任何一个人处理信息的逻辑能力都是有限的, 所以,当面对一个非常复杂的问题时,我们不太可能一次性搞定一大堆的内容
但是我们可以将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放在整体当中
组件化也是类似的思想:
- 我们将一个完整的⻚面按照功能点分成很多个组件
- 每个组件都用于实现⻚面的一个功能块,拥有属于自己这部分独立的功能
- 每一个组件又可以进行细分
- 组件本身又可以在多个地方进行复用
- 组件完成后,可以像搭 建积木一下来进行整合,从而搭建我们的项目
createApp函数传入的参数对象App,这个对象其实本质上就是一个组件,也是我们应用程序的根组件
组件化提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用
任何的应用都会被抽象成一颗组件树
组件本质就是一个拥有自己独立html,css和js的可复用功能模块
组件
| 分类 | 说明 |
|---|---|
| 全局组件 | 全局注册后,在任何其他的组件中都可以使用的组件 |
| 局部组件 | 只有在注册的组件中才能使用的组件 |
全局组件
全局组件需要使用我们全局创建的app来注册组件
通过component方法传入组件名称、组件对象即可注册一个全局组件了
之后,我们可以在App组件的template中直接使用这个全局组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@3.2.37/dist/vue.global.min.js"></script>
</head>
<body>
<div id="app">
<!--
注意: 在DOM模板中,使用组件只能通过<cpn></cpn>
不能使用<cpn />
使用<cpn />的时候只能显示一次组件,不能多次重复调用
-->
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
<!-- 组件模板 -->
<template id="cpn">
<h2>this is a global component</h2>
</template>
<script>
const app = Vue.createApp({})
// 通过app.component方法注册全局组件
// 参数一: 组件名
// 参数二: 组件对象 --> SFC文件最后也会被解析为类似的JS配置对象
app.component('my-cpn', {
template: '#cpn'
})
app.mount('#app')
</script>
</body>
</html>
局部组件
局组件往往是在应用程序一开始就会全局组件完成,那么就意味着如果某些组件我们并没有用到,也会一起被注册
- 比如我们注册了三个全局组件:ComponentA、ComponentB、ComponentC
- 在开发中我们只使用了ComponentA、ComponentB,如果ComponentC没有用到但是我们依然在全局进行了注册,那么就意 味着类似于webpack这种打包工具在打包我们的项目时,我们依然会对其进行打包
- 这样最终打包出的JavaScript包就会有关于ComponentC的内容,用户在下载对应的JavaScript时也会增加包的大小
所以在开发中我们通常使用组件的时候采用的都是局部注册:
- 局部注册是在我们需要使用到的组件中,通过components属性选项来进行注册
- 该components选项对应的是一个对象,对象中的键值对是 组件的名称: 组件对象
<div id="app">
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
<!-- 组件模板 -->
<template id="cpn">
<h2>this is a global component</h2>
</template>
<script>
const MyCpn = {
template: '#cpn'
}
const app = Vue.createApp({
// 使用components选项对组件进行局部组件
// 只有注册了该局部组件的组件,才可以使用该局部组件
components: {
MyCpn
}
})
app.mount('#app')
</script>
组件命名
| 方式 | 说明 |
|---|---|
| kebab-case (短横线标识符) | 当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my- component-name> |
| PascalCase (大驼峰标识符) | 当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用 也就是说 <my-component-name>和 <MyComponentName> 都是可接受的 |
但是因为html是不区分大小写的,所以在html模板中,<MyComponentName>会被解析为<mycomponentname>,导致组件无法识别
但是在字符串模板中,因为对应的模板会优先被vue所进行解析,所以使用<MyComponentName>, 定义的组件
既可以用过<MyComponentName>进行使用,也可以通过<my-component-name>进行使用
所以推荐在定义组件名称的时候,使用PascalCase命名法,而在使用的时候使用kebab-case命名法进行使用
vue开发模式
目前我们都是在html文件中通过dom模板的方式去使用vue,通过template编写自己的模板、脚本逻辑、样式等
但是随着项目越来越复杂,我们会采用组件化的方式来进行开发
这就意味着每个组件都会有自己的模板、脚本逻辑、样式等,当然我们依然可以把它们抽离到单独的js、css文件中,但是它们还是会分离开
也包括我们的script是在一个全局的作用域下,很容易出现命名冲突的问题,并且我们的代码为了适配一些浏览器,必须使用ES5的语法
在我们编写代码完成之后,依然需要通过工具对代码进行构建、代码
所以在真实开发中,我们可以通过一个后缀名为 .vue 的single-file components (单文件组件) 来进行开发
通过使用webpack 或者vite或者rollup等构建工具,我们可以将SFC文件转变为组件的配置对象,结合vue框架后,就可以在浏览器中直接运行
SFC的支持
浏览器是不支持直接识别SFC文件的,默认也不支持使用SFC来进行vue项目的开发
所以我们需要自己搭建开发环境以便于支持SFC环境,常见的形式有使用vue的脚手架或者自己使用构建工具从零进行搭建