Vue.js组件

241 阅读8分钟

Vue.js 组件

  • 组件用于封装页面的部分功能,将功能的结构、样式、逻辑代码封装为整体。
  • 提高功能的复用性与可维护性,更好的专注于业务逻辑。
  • 组件使用时为自定义 HTML 标签形式,通过组件名作为自定义标签名。

image.png

组件注册

全局注册

全局注册的组件在注册后可以用于任意实例或组件中

image.png 注意:全局注册必须设置在根 Vue 实例创建之前

组件基础

  • 本质上,组件是可复用的 Vue 实例,所以它们可与 new Vue 接收相同的选项,例如 data、methods 以及生命周期钩子等。
  • 仅有的例外是像 el 这样根实例特有的选项。

组件命名规则

组件具有两种命名规则:

  • kebab-case:'my-component'
  • PascalCase:'MyComponent'

image.png 注意:无论采用哪种命名方式,在 DOM 中都只有 kebab-case 可以使用。

template 选项

template 选项用于设置组件的结构,最终被引入根实例或其他组件中。

image.png

注意:组件必须只有一个根元素。

data 选项

data 选项用于存储组件的数据,与根实例不同,组件的 data 选项必须为函数,数据设置在返回值对象中。

image.png

采用函数的原因:这种实现方式是为了确保每个组件实例可以维护一份被返回对象的独立的拷贝,不会相互影响。

局部注册

局部注册的组件只能用在当前实例或组件中。

image.png

单独配置组件的选项对象:

image.png

ES6 的对象属性简写:

image.png

组件通信

  • 子组件如何获取父组件中的数据?
  • 父组件如何得知子组件的数据变更?
  • 如果是更加复杂的组件关系呢?
  • 在组件间传递数据的操作,称为组件通信。

父组件向子组件传值

通过子组件的 props 选项接收父组件的传值

image.png

注意:props 不要与 data 存在同名属性。

父组件设置方式如下:

image.png

Props 命名规则

建议 prop 命名使用 camelCase,因为子组件写-作为属性名时需要加引号;父组件绑定时使用 kebab-case。因为父组件不识别大小写

image.png

单向数据流

  • 父子组件间的所有 prop 都是单向下行绑定的
  • 如果子组件要处理 prop 数据,应当存储在 data 中后操作

image.png

注意,如果 prop 为数组或对象时,子组件操作将会影响到父组件的状态。

Props 类型

Prop 可以设置类型检查,这时需要将 props 更改为一个带有验证需求的对象,并指定对应类型。

image.png

image.png

prop 还可以同时指定多个类型,通过数组方式保存即可

image.png

Props 验证

  • 当 prop 需要设置多种规则时,可以将 prop 的值设置为选项对象。
  • 之前的类型检测功能通过 type 选项设置

image.png

required 用于设置数据为必填项。

image.png

default 用于给可选项指定默认值,当父组件未传递数据时生效。

image.png

注意:当默认值为数组或对象时,必须为工厂函数返回的形式。

image.png

validator 用于给传入的 prop 设置校验函数,return 值为 false 时 Vue.js 会发出警告。

image.png

注意:验证函数中无法使用实例的 data、methods 等功能。

非 Props 属性

当父组件给子组件设置了属性,但此属性在 props 中不存在,这时会自动绑定到子组件的根元素上。

image.png

如果组件根元素已经存在了对应属性,则会替换组件内部的值。

class 与 style 是例外,当内外都设置时,属性会自动合并。

image.png

如果不希望继承父组件设置的属性,可以设置 inheritAttrs: false,但只适用于普通属性,class 与 style 不受影响。

image.png

子组件向父组件传值

子向父传值需要通过自定义事件实现。

商品为子组件,购物车为父组件,父组件需要统计商品个数,就需要在子组件个数变化时传值给父组件

image.png

image.png

子组件数据变化时,通过 $emit() 触发自定义事件。

image.png

自定义事件名称建议使用 kebab-case。

父组件监听子组件的自定义事件,并设置处理程序

image.png

自定义事件传值

子组件触发事件时可以向父组件传值。 image.png

父组件在监听事件时需要接收子组件传递的数据。 image.png 还可以通过事件处理程序来接收数据: image.png

组件与 v-model

v-model 用于组件时,需要通过 props 与自定义事件实现。

image.png

image.png $event.target.value如果在自定义的事件处理程序中:

image.png

非父子组件传值

非父子组件指的是兄弟组件或完全无关的两个组件。

兄弟组件传值

兄弟组件可以通过父组件进行数据中转

image.png image.png

image.png image.png

EventBus

  • 当组件嵌套关系复杂时,根据组件关系传值会较为繁琐。
  • 组件为了数据中转,data 中会存在许多与当 前组件功能无关的数据。
  • EventBus (事件总线)是一个独立的事件中心,用于管理不同组 件间的传值操作。
  • EventBus 通过一个新的 Vue 实例来管理组件传值操作,组件通 过给实例注册事件、调用事件来实现数据传递。 image.png

发送数据的组件触发 bus 事件,接收的组件给 bus 注册对应事件。 image.png

给 bus 注册对应事件通过 $on() 操作。 image.png

最后创建根实例执行代码即可。 image.png

其他传值方式

其他通信方式

$root

$root 用于访问当前组件树根实例,设置简单的 Vue 应用时可以通过此方式进行组件传值。

image.png image.png

$root 用于访问当前组件树根实例,设置简单的 Vue 应用时可以通过此方式进行组件传值。

image.png image.png

除了 $root , Vue.js 中还提供了 $parent$children 用于便捷访问父子组件。

不便于维护查找数据更改源头,不建议使用

$refs

$refs 用于获取设置了 ref 属性的 HTML 标签或子组件。

给普通 HTML 标签设置 ref 属性,$refs 可以获取 DOM 对象。

image.png image.png

给子组件设置 ref 属性,渲染后可通过 $refs 获取子组件实例。 image.png image.png image.png

组件插槽

组件插槽可以便捷的设置组件内容。

image.png

单个插槽

如果我们希望组件标签可以像 HTML 标签一样设置内容,那么组件的使用灵活度会很高。

image.png

但平常我们书写的组件,组件首尾标签中书写的内容会被抛弃。 我们需要通过 <slot> 进行插槽设置。 image.png

需要注意模板内容的渲染位置: image.png image.png

我们可以在 <slot> 中为插槽设置默认值,也称为后备内容。

image.png

具名插槽

如果组件中有多个位置需要设置插槽,据需要给 <slot> 设置 name,称为具名插槽。

image.png image.png

v-slot:header可以简写为#header

作用域插槽

用于让插槽可以使用子组件的数据。

组件将需要被插槽使用的数据通过 v-bind 绑定给 <slot>,这种 用于给插槽传递数据的属性称为插槽 prop。

image.png

组件绑定数据后,插槽中需要通过 v-slot 接收数据。

image.png

如果只存在默认插槽,同时又需要接收数据,可以进行简写:

image.png image.png

还可以通过 ES6 的解构操作进行数据接收

image.png

内置组件

动态组件

动态组件适用于多个组件频繁切换的处理。

<component> 用于将一个‘元组件’渲染为动态组件,以 is 属性值决定渲染哪个组件。

image.png

用于实现多个组件的快速切换,例如选项卡效果。 image.png image.png image.png

is 属性会在每次切换组件时,Vue 都会创建一个新的组件实例。

image.png

keep-alive组件

主要用于保留组件状态或避免组件重新渲染。

image.png include 属性用于指定哪些组件会被缓存,具有多种设置方式。

image.png image.png image.png

exclude 属性用于指定哪些组件不会被缓存。

image.png max 属性用于设置最大缓存个数。

image.png

过渡组件

用于在 Vue 插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡、动画效果。

transition 组件

  • 用于给元素和组件添加进入/离开过渡:
    • 条件渲染 (使用 v-if )
    • 条件展示 (使用 v-show )
    • 动态组件
    • 组件根节点
  • 组件提供了 6个 class,用于设置过渡的具体效果。
  • 进入的类名:
    • v-enter 入场前
    • v-enter-to 入场结束,动画结束
    • v-enter-active 设置入场过程
  • 离开的类名:
    • v-leave 离场前
    • v-leave-to 离场结束
    • v-leave-active
    v-leave一般不设置,采用元素的默认位置 image.png

image.png

相关属性
  • 给组件设置 name 属性,可用于给多个元素、组件设置不同的过 渡效果,这时需要将 v- 更改为对应 name- 的形式。
  • 例如:
    • <transition name="demo"> 的对应类名前缀为:
      • demo-enter
      • demo-leave
      • .. 通过 appear 属性,可以让组件在初始渲染时实现过渡。

image.png

自定义过渡类名

自定义类名比普通类名优先级更高,在使用第三方 CSS 动画库时非常有用。

  • 用于设置自定义过渡类名的属性如下:
    • enter-class
    • enter-active-class
    • enter-to-class
    • leave-class
    • leave-active-class
    • leave-to-class
  • 用于设置初始过渡类名的属性如下:
    • appear-class
    • appear-to-class
    • appear-active-class

image.png

Animate.css 是一个第三方 CSS 动画库,通过设置类名来给元素 添加各种动画效果。官网:animate.style

  • 使用注意:
    • animate__ 前缀与 compat 版本
    • 基础类名 animated

image.png

transition-group 组件

  • <transition-group> 用于给列表(指一系列组件)统一设置过渡动画。
    • tag 属性用于设置容器元素,默认为 <span>
    • 过渡会应用于内部元素,而不是容器。
    • 子节点必须有独立的 key,动画才能正常工作。 当列表元素变更导致元素位移,可以通过 .v-move 类名设置移动时的效果。

image.png