vue基础知识笔记(二)—— 组件

本文深入探讨Vue组件,解释组件化开发的优势,包括提升代码复用性和开发效率。介绍了单页面应用程序(SPA)的概念及其优缺点,并展示了如何创建Vue的SPA项目。详细讲解了Vue组件的构成,包括定义、注册、样式冲突处理、props、计算属性、事件监听、v-model、生命周期钩子和组件间的通信。此外,还涵盖了动态组件、插槽、自定义指令等内容,帮助读者全面理解Vue组件开发。
摘要由CSDN通过智能技术生成

 

目录

​编辑

组件

组件是什么?

什么是组件化开发

前端组件化开发的好处:

vue 中的组件化开发:

了解一下什么是单页面应用程序:

单页面应用程序的优点:

单页面应用程序的缺点:

创建 vue 的 SPA 项目

 创建 vite 的项目:

vite 项目的运行流程

回到组件:vue组件的构成

定义一个组件 

组件注册

全局注册

全局注册的问题:

局部注册

组件名格式

通过 name 属性注册组件

组件之间的样式冲突问题

组件的 props

props的使用

使用一个对象绑定多个 prop

 props 验证 

计算属性 computed

计算属性computed 和方法methods的区别:

触发与监听事件  emits

自定义事件的 3 个使用步骤

组件上的 v-model

 生命周期钩子

生命周期选项

侦听器 watch 

组件之间数据共享

父子组件数据共享

computed()#

ref引用

动态组件  组件

插槽 Slots

具名插槽

作用域插槽

#高级列表组件示例

 自定义指令

指令钩子#

钩子参数#

对象字面量#


组件

组件是什么?

组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。Vue 实现了自己的组件模型,使我们可以在每个组件内封装自定义内容与逻辑。在实际应用中,组件常常被组织成层层嵌套的树状结构:

什么是组件化开发

组件化开发指的是:根据封装的思想,把页面上可重用的部分封装为组件,从而方便项目的开发和维护。

前端组件化开发的好处:

  • 提高了前端代码的复用性和灵活性
  • 提升了开发效率和后期的可维护性

vue 中的组件化开发:

vue 是一个完全支持组件化开发的框架。vue 中规定组件的后缀名是 .vue。(App.vue 文件本质 上就是一个 vue 的组件。)

了解一下什么是单页面应用程序:

单页面应用程序(英文名:Single Page Application)简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。

特点就是:单页面应用程序将所有的功能局限于一个 web 页面中,仅在该 web 页面初始化时加载相应的资源( HTML、JavaScript 和 CSS)。一旦页面加载完成了,SPA 不会因为用户的操作而进行页面的重新加载或跳转。而是利用 JavaScript 动态地变换 HTML 的内容,从而实现页面与用户的交互。

单页面应用程序的优点:

① 良好的交互体验

  • 单页应用的内容的改变不需要重新加载整个页面
  • 获取数据也是通过 Ajax 异步获取
  • 没有页面之间的跳转,不会出现“白屏现象”

② 良好的前后端工作分离模式

  •  后端专注于提供 API 接口,更易实现 API 接口的复用
  •  前端专注于页面的渲染,更利于前端工程化的发展

③ 减轻服务器的压力

  • 服务器只提供数据,不负责页面的合成与逻辑的处理,吞吐能力会提高几倍单页面应用程序

单页面应用程序的缺点:

① 首屏加载慢

  • 路由懒加载
  • 代码压缩
  • CDN 加速
  • 网络传输压缩

② 不利于 SEO

  • SSR 服务器端渲染

创建 vue 的 SPA 项目

vue 官方提供了两种快速创建工程化的 SPA 项目的方式:

① 基于 vite 创建 SPA 项目

② 基于 vue-cli 创建 SPA 项目

 创建 vite 的项目:

项目名称建议使用英文。

项目目录:

 

  • node_modules 目录用来存放第三方依赖包
  • public 是公共的静态资源目录
  • src 是项目的源代码目录
  • .gitignore 是 Git 的忽略文件
  • index.html 是 SPA 单页面应用程序中唯一的 HTML 页面
  • package.json 是项目的包管理配置文件
在 src 这个项目源代码目录之下,包含:

  • assets 目录用来存放项目中所有的静态资源文件(如css、fonts、img等)
  • components 目录用来存放项目中所有的自定义组件
  • App.vue 是项目的根组件
  • index.css 是项目的全局样式表文件
  • main.js 是整个项目的打包入口文件

vite 项目的运行流程

在工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。
其中:
① App.vue 用来编写待渲染的模板结构 <template>
② index.html 中需要预留一个 el 区域
  <div id="app"></div>
③ main.js 把 App.vue 渲染到了 index.html 所预留的区域中
// 1. 按需导入 createApp 函数
import { createApp } from 'vue'

// 2. 导入待渲染的 App.vue 组件
import App from './App.vue'

// 3. 调用 createApp 函数,创建 SPA 应用的实例,返回值是SPA实例,用常量app接收,并且把App组件作为参数传递给createApp 函数,表示要把App渲染到index.html中
const app = createApp(App)

// 4. 调用 mount() 把 App 组件的模板结构,渲染到指定的 el 区域中
app.mount('#app)

回到组件:vue组件的构成

.vue 组件都由 3 部分构成,分别是:
  • template -> 组件的模板结构 
    • vue 提供的容器标签,只起到包裹性质的作用,不会被渲染为真正的 DOM 元素
    • vue 2.x 的版本中,<template> 节点内的 DOM 结构仅支持单个根节点,但在 vue 3.x 的版本中,<template> 中支持定义多个根节点
    • 在组件的 <template> 节点中,支持使用前面所学的指令语法,来辅助开发者渲染当前组件的 DOM 结构。
  • script -> 组件的 JavaScript 行为
    • 可以在 <script> 节点中封装组件的 JavaScript 业务逻辑,之后的data数据已经各种方法需要在export default {}中定义导出 
    • script 中的 name 节点 可以通过 export default {name: ; }节点为当前组件定义一个名称。(自定义的组件名称可以清晰的区分每个组件)
    • vue 组件渲染期间需要用到的数据,可以定义在 data 节点中,需要return出去。且组件中的 data 必须是一个函数,不能直接指向一个数据对象。
    • export default {
        data () {
          return {
          }
        },
      }
    • 组件中的事件处理函数,必须定义到 methods 节点中
  • style -> 组件的样式
    • 可以在 <style> 节点中编写样式美化当前组件的 UI 结构。
    • 如果希望使用 less 语法编写组件的 style 样式,可以按照如下两个步骤进行配置:
      ① 运行 npm install less -D 命令安装依赖包,从而提供 less 语法的编译支持
      ② 在 <style> 标签上添加 lang="less" 属性,即可使用 less 语法编写组件的样式
    • <style lang='less' scoped>
      </style>
      
其中,每个组件中必须包含 template 模板结构,而 script 行为和 style 样式是可选的组成部分。

定义一个组件 

使用构建步骤时,一般会将 Vue 组件定义在一个单独的.vue  文件中,这被叫做单文件组件 (简称 SFC):

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">You clicked me {
  { count }} times.</button>
</template>

当不使用构建步骤时,一个 Vue 组件以一个包含 Vue 特定选项的 JavaScript 对象来定义,也可以使用 ID 选择器来指向一个元素 (通常是原生的 <template> 元素),Vue 将会使用其内容作为模板来源。 :

import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return { count }
  },
  template: `
    <button @click="count++">
      You clicked me {
  { count }} times.
    </button>`
  // 或者 `template: '#my-template-element'`
}

也可以使用 ID 选择器来指向一个元素 (通常是原生的 <template> 元素),Vue 将会使用其内容作为模板来源。 

组件注册

组件之间可以进行相互的引用,vue 中组件的引用原则:先注册后使用。

组件注册有两种方式:全局注册和局部注册。

全局注册

被全局注册的组件,可以在全局任何一个组件内使用

可以使用 Vue 应用实例的app.component() 方法注册,让组件在当前 Vue 应用中全局可用。

import { createApp } from 'vue'

const app = createApp({})

app.component(
  // 注册的名字
  'MyComponent',
  // 组件的实现
  {
    /* ... */
  }
)

 如果使用单文件组件,你可以注册被导入的 . Vue 文件:(在main.js中注册)

import MyComponent from './App.vue'

app.component('MyComponent', MyComponent)

app.component() 方法可以被链式调用

app
  .component('ComponentA', ComponentA)
  .component('ComponentB', ComponentB)
  .component('ComponentC', ComponentC)

在其他组件中使用时直接以标签的形式进行使用:

<template>

<MyComponent></MyComponent>

</template>

全局注册的问题:

  1. 全局注册,但并没有被使用的组件无法在生产打包时被自动移除 (也叫“tree-shaking”)。如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的 JS 文件中。

  2. 全局注册在大型项目中使项目的依赖关系变得不那么明确。在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性。

 相比之下,局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。它的优点是使组件之间的依赖关系更加明确,并且对 tree-shaking 更加友好。 

局部注册

被局部注册的组件,只能在当前注册的范围内使用。
在使用<script setup>的单文件组件中,导入的组件可以直接在模板中使用,无需注册:
<script setup>
import ComponentA from './ComponentA.vue'
</script>

<template>
  <ComponentA />
</template>

如果没有使用 <script setup>,则需要使用 components 选项来显式注册:(组件内局部注册)

<script>
import ComponentA from './ComponentA.js'

export default {
  components: {
   // components 对象里的属性,它们的 key 名就是注册的组件名,而值就是相应组件的实现
    ComponentA: ComponentA
  }
  // ...
}
</script>

注意:局部注册的组件在后代组件中并不可用。局部注册后仅在当前组件可用,而在任何的子组件或更深层的子组件中都不可用。

组件名格式

在进行组件的注册时,定义组件注册名称的方式有两种:
① 使用 kebab-case 命名法(俗称短横线命名法,例如 my-swiper 和 my-search,使用必须严格按照短横线名称进行使用 )
② 使用 PascalCase 命名法(俗称帕斯卡命名法或大驼峰命名法,例如 MySwiper 和 MySearch使用既可以严格按照帕斯卡名称进行使用,又可以转化为短横线名称进行使用 )

注:帕斯卡命名法(PascalCase) 它的标签名在 DOM 模板中是不可用的,详情参见 DOM 模板解析注意事项

通过 name 属性注册组件

在注册组件期间,除了可以直接提供组件的注册名称之外,还可以把组件的 name 属性作为注册后组件的名称。
Swiper.vue中:
<script>
export default {
  name: 'MySwiper',
}
</script>

main.js中:

import Swiper from './components/Swiper.vue'
//导入Swiper.vue后,可以把组件的 name 属性作为注册后组件的名称。
app.component(Swiper.name, Swiper)

组件之间的样式冲突问题

默认情况下,写在 .vue 组件中的样式会全局生效,就容易造成多个组件之间的样式冲突问题:
  • 单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的
  • 每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素

解决样式冲突问题就需要为每个组件分配唯一的自定义属性。vue 为 style 节点提供了 scoped 属性,从而防止组件之间的样式冲突问题。原理就是在编写组件样式时࿰

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白芸哆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值