【Vue】组件化 && 组件的注册 && App.vue

文章目录

  • [Ⅰ. 组件及组件化](#Ⅰ. 组件及组件化)
    • 一、为什么需要组件?
      • [1. 思考](#1. 思考)
      • [2. 解决方案](#2. 解决方案)
    • 二、组件及组件化
      • [1. 组件](#1. 组件)
      • [2. 组件化](#2. 组件化)
    • [三、根组件 `App.vue`](#三、根组件 App.vue)
      • [1. 根组件](#1. 根组件)
      • [2. 组件是由三部分构成](#2. 组件是由三部分构成)
    • 四、组件的使用
      • [1. 创建组件](#1. 创建组件)
      • [2. 导入组件](#2. 导入组件)
      • [3. 注册组件💥](#3. 注册组件💥)
      • [4. 使用组件](#4. 使用组件)
      • [5. 练习](#5. 练习)
    • 五、组件的全局注册
      • [1. 步骤](#1. 步骤)
      • [2. 使用组件(与局部组件一样)](#2. 使用组件(与局部组件一样))
      • [3. 注意](#3. 注意)
      • [4. 语法](#4. 语法)
      • [5. 练习](#5. 练习)

Ⅰ. 组件及组件化

一、为什么需要组件?

1. 思考

以可折叠面板为例,现要展示3个,如何操作?

可折叠面板案例的代码:

javascript 复制代码
<script setup>
    import { ref } from 'vue'
    const visible = ref(false)
</script>

<template>
  <h3>可折叠面板</h3>
  <div class="panel">
    <div class="title">
      <h4>自由与爱情</h4>
      <span class="btn" @click="visible = !visible"> {{ visible ? '收起' : '展开' }} </span>
    </div>
    <div class="container" v-show="visible">
      <p>生命诚可贵,</p>
      <p>爱情价更高。</p>
      <p>若为自由故,</p>
      <p>两者皆可抛。</p>
    </div>
  </div>
</template>

<style lang="scss">
body {
  background-color: #ccc;
}

#app {
  width: 400px;
  margin: 20px auto;
  background-color: #fff;
  border: 4px solid green;
  border-radius: 1em;
  box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
  padding: 1em 2em 2em;
}

#app h3 {
  text-align: center;
}

.panel {
  .title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1px solid #ccc;
    padding: 0 1em;
  }
  .title h4 {
    line-height: 2;
    margin: 0;
  }
  .container {
    border: 1px solid #ccc;
    padding: 0 1em;
    border-top-color: transparent;
  }
  .btn {
    cursor: pointer;
  }
}
</style>

2. 解决方案

  1. 把需要复用的一段标签,抽离并封装到一个单独的 vue 文件里,连同相关 JSCSS 放到一起
  2. 哪里要用这个组件,哪里导入,当做标签使用即可

新建一个 src/components/MyPanel.vue 文件:

javascript 复制代码
<script setup>
    import { ref } from 'vue'
    const visible = ref(false)
</script>

<template>
  <div class="panel">
    <div class="title">
      <h4>自由与爱情</h4>
      <span 
        class="btn" 
        @click="visible = !visible">
        {{ visible ? '收起' : '展开' }}
      </span>
    </div>
    <div 
      class="container" 
      v-show="visible">
      <p>生命诚可贵,</p>
      <p>爱情价更高。</p>
      <p>若为自由故,</p>
      <p>两者皆可抛。</p>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.panel {
  .title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1px solid #ccc;
    padding: 0 1em;
  }
  .title h4 {
    line-height: 2;
    margin: 0;
  }
  .container {
    border: 1px solid #ccc;
    padding: 0 1em;
    border-top-color: transparent;
  }
  .btn {
    cursor: pointer;
  }
}
</style>

然后在 App.vue 导入并使用该组件:

javascript 复制代码
<script setup>
    // 导入
    import MyPanel from './components/MyPanel.vue'
</script>

<template>
  <h3>可折叠面板</h3>
  <!-- 使用 -->
  <MyPanel />
  <MyPanel />
  <MyPanel />
</template>

<style>
body {
  background-color: #ccc;
}

#app {
  width: 400px;
  margin: 20px auto;
  background-color: #fff;
  border: 4px solid green;
  border-radius: 1em;
  box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
  padding: 1em 2em 2em;
}

#app h3 {
  text-align: center;
}
</style>

二、组件及组件化

1. 组件

组件是一个 独立的、可复用Vue 实例,也是一段 独立的 UI 视图 ,代码上体现在是一个独立的 .vue 文件,包含 JS + HTML + CSS 三部分组成。

类似乐高和积木一样,我们可以通过任意的乐高或积分进行组合,拼装成我们需要的成品。

2. 组件化

定义: 一种代码的开发思想,体现在一个页面可以拆分成一个个组件,每个组件有着自己独立的结构、样式、行为;通过 组件的组合与拼装 形成一个完整的页面,本质是代码的一种拆分思想,化大为小、化繁为简、分而治之

好处: 各自独立、便于复用

比如:下面这个页面,可以把所有的代码都写在一个页面中,但是这样显得代码比较混乱,难以维护。我们可以按模块进行组件拆分

三、根组件 App.vue

1. 根组件

根组件是整个应用最上层的组件,包裹所有普通小组件,如下图所示:

2. 组件是由三部分构成

  • template:HTML 结构
  • script:JS 逻辑
  • style:CSS 样式(可支持less/scss,需要装包)
  • 让组件支持less/scss
    • style标签,lang="less/scss"开启less/scss功能
    • 装包:npm i less less-loader -D 或者 npm i sass -D

四、组件的使用

组件的一系列场景命名规范如下所示:

场景 ✅推荐写法 可选写法 说明
文件名 MyHeader.vue my-header.vue 官方推荐 PascalCase,和类名一样清晰
import 引入 import MyHeader from './MyHeader.vue' import Haha from './MyHeader.vue' 变量名随意,但最好和文件名一致,便于阅读
局部注册 components: { MyHeader } components: { Haha } 名字和模板里的标签要对应
模板 (SFC 内部) Vue 自动识别两种形式
HTML 文件直接写 (非 .vue) ❌ 不支持 HTML 标签不区分大小写,必须用短横线

1. 创建组件

新建 .vue 文件,编写组件的三部分代码

2. 导入组件

在需要的 vue 文件中的 <script setup> 中导入需要的组件即可!

注意:导入的组件对象名称,推荐保持和文件名一致

javascript 复制代码
import 组件对象 from '相对路径'

// 例子:
import MyPanel from './components/MyPanel.vue'

3. 注册组件💥

💥注意:局部组件无需注册全局组件要在 main.js 中注册

之所以局部组件不需要注册,是因为 vue3 <script setup> 自动完成了局部注册 ,如果是 vue2 或者普通的 <script> 的话,则需要手动注册局部组件,如下面所示:

javascript 复制代码
<script>
    import MyHeader from './components2/MyHeader.vue'
    
    // 如果是 vue2 或者普通的 <script> 的话,则需要手动注册局部组件
    export default {
      components: {
        MyHeader
      }
    }
</script>

<template>
  <my-header></my-header>
</template>

4. 使用组件

把组件当做自定义标签使用:(单双标签均可)

javascript 复制代码
<组件名></组件名>

<组件名 />

// 例子:
<!-- 大驼峰 双标签 -->
<MyPanel></MyPanel>

<!-- 大驼峰 自闭合的单标签 -->
<MyPanel />

<!-- 烤串法(更推荐这种) 双标签 -->
<my-panel></my-panel>

<!-- 烤串法 自闭合的单标签 -->
<my-panel />

5. 练习

components2/MyHeader.vue文件:

javascript 复制代码
<script setup></script>

<template>
  <div class="my-header">我是my-header</div>
</template>

<style>
.my-header {
  height: 100px;
  line-height: 100px;
  background-color: #8064a2;
}
</style>

components2/MyMain.vue文件:

javascript 复制代码
<script setup></script>

<template>
  <div class="my-main">我是my-main</div>
</template>

<style>
.my-main {
  height: 400px;
  margin: 20px 0;
  line-height: 400px;
  background-color: #f79646;
}
</style>

components2/MyFooter.vue文件:

javascript 复制代码
<script setup></script>

<template>
  <div class="my-footer">我是my-footer</div>
</template>

<style>
.my-footer {
  height: 100px;
  line-height: 100px;
  background-color: #4f81bd;
}
</style>

App.vue文件:

javascript 复制代码
<template>
  <my-header></my-header>
  <my-main></my-main>
  <my-footer></my-footer>
</template>

<script setup>
    import MyHeader from './components2/MyHeader.vue';
    import MyMain from './components2/MyMain.vue';
    import MyFooter from './components2/MyFooter.vue';
</script>

<style>
* {
  margin: 0;
}

#app {
  height: 100vh;
  padding: 10px;
  background: skyblue;
  font-size: 30px;
  color: #fff;
  text-align: center;
}
</style>

五、组件的全局注册

全局注册的组件,在项目的任何组件中都能使用

1. 步骤

  1. 创建 .vue 组件(三个组成部分)
  2. main.js 中进行全局注册

2. 使用组件(与局部组件一样)

当成 HTML 标签直接使用:

  • 双标签:<组件名></组件名>
  • 自闭合的单标签:<组件名 />

3. 注意

组件名规范:大驼峰命名法(推荐)烤串法 ,如 MyHeadermy-header

4. 语法

main.js 中通过导入组件,并且使用 app.component() 方法注册组件:

javascript 复制代码
// main.js文件
import MyPanel from './components/MyPanel.vue'

// 注册全局组件语法:
// app.component('组件名', 组件对象)

// 大驼峰组件名(更推荐这种,因为使用标签时候既可以用大驼峰,也可以用烤串法)
app.component('MyPanel', MyPanel)

// 烤串法组件名(需要注意:使用标签时候,只能用烤串法,而不能再用大驼峰了)
app.component('my-panel', MyPanel)

注意,上面代码中的 app 对象,是 createApp(App) 得到的应用对象!

5. 练习

components3/MyButton.vue文件:

javascript 复制代码
<script setup></script>

<template>
  <button class="my-button">通用按钮</button>
</template>

<style scoped>
.my-button {
  height: 50px;
  line-height: 50px;
  padding: 0 15px;
  background-color: #3bae56;
  border-radius: 5px;
  font-size: 16px;
  color: white;
  border: none;
  cursor: pointer;
}
</style>

main.js 中,导入并全局注册:

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import MyButton from './components3/MyButton.vue'

const app = createApp(App) // 拿到应用对象
app.component("MyButton", MyButton)

app.mount('#app') // 最后再去挂载即可

components3/MyHeader.vue文件:

javascript 复制代码
<script setup></script>

<template>
  <div class="my-header">
    我是my-header
    <my-button />
  </div>
</template>

<style>
.my-header {
  height: 100px;
  line-height: 100px;
  background-color: #8064a2;
}
</style>

components3/MyMain.vue文件:

javascript 复制代码
<script setup></script>

<template>
  <div class="my-main">
    我是my-main
    <my-button />
  </div>
</template>

<style>
.my-main {
  height: 400px;
  margin: 20px 0;
  line-height: 400px;
  background-color: #f79646;
}
</style>

components3/MyFooter.vue文件:

javascript 复制代码
<script setup></script>

<template>
  <div class="my-footer">
    我是my-footer
    <my-button />
  </div>
</template>

<style>
.my-footer {
  height: 100px;
  line-height: 100px;
  background-color: #4f81bd;
}
</style>

App.vue文件:

javascript 复制代码
<template>
  <my-header></my-header>
  <my-main></my-main>
  <my-footer></my-footer>
</template>

<script setup>
    import MyHeader from './components3/MyHeader.vue';
    import MyMain from './components3/MyMain.vue';
    import MyFooter from './components3/MyFooter.vue';
</script>

<style>
* {
  margin: 0;
}

#app {
  height: 100vh;
  padding: 10px;
  background: skyblue;
  font-size: 30px;
  color: #fff;
  text-align: center;
}
</style>
相关推荐
Whisper_Sy2 小时前
Flutter for OpenHarmony移动数据使用监管助手App实战 - 周报告实现
开发语言·javascript·网络·flutter·php
Anastasiozzzz2 小时前
leetcodehot100--最小栈 MinStack
java·javascript·算法
一起养小猫2 小时前
Flutter for OpenHarmony 实战:按钮类 Widget 完全指南
前端·javascript·flutter
css趣多多2 小时前
Vux store实例的模块化管理
前端
我是伪码农3 小时前
Vue 1.26
前端·javascript·vue.js
晚霞的不甘3 小时前
Flutter for OpenHarmony 创意实战:打造一款炫酷的“太空舱”倒计时应用
开发语言·前端·flutter·正则表达式·前端框架·postman
2601_949480063 小时前
Flutter for OpenHarmony音乐播放器App实战:定时关闭实现
javascript·flutter·原型模式
这儿有一堆花4 小时前
CSS 拟真光影设计:从扁平到深度的技术复盘
前端·css
_OP_CHEN4 小时前
【前端开发之CSS】(三)CSS 常用元素属性宝典(上):从字体到文本,手把手教你打造高颜值网页!
前端·css·html·网页开发·文本属性·字体属性·页面美化