vue3 - 组件化基础

156 阅读5分钟

任何一个人处理信息的逻辑能力都是有限的, 所以,当面对一个非常复杂的问题时,我们不太可能一次性搞定一大堆的内容

但是我们可以将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放在整体当中

I8XXNu.png

组件化也是类似的思想:

  1. 我们将一个完整的⻚面按照功能点分成很多个组件
  2. 每个组件都用于实现⻚面的一个功能块,拥有属于自己这部分独立的功能
  3. 每一个组件又可以进行细分
  4. 组件本身又可以在多个地方进行复用
  5. 组件完成后,可以像搭 建积木一下来进行整合,从而搭建我们的项目

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的脚手架或者自己使用构建工具从零进行搭建