一、组件
1. 简介
Component 组件是可复用的Vue实例,且带有一个名字,可以把组件作为自定义元素来使用
将项目中重复出现的页面结构定义为Vue的一个组件实例,或将特殊功能封装成组件
2. 构造器继承函数
构造器继承函数,语法: Vue.extend(options)
- 以基础 Vue 构造器为蓝本,创建一个具有指定配置项的“子类”构造器,也称为组件构造器
- 可以使用该子类构造器来创建Vue实例(组件)
- data选项必须以函数形式声明,函数内返回一个包含初始数据的对象
二、定义组件
组件分类:
- 全局组件,在所有Vue实例中都可以使用
- 局部组件,只能在构建组件的 Vue实例的容器范围内使用
1. 全局组件
全局组件的定义,通过全局方法 Vue.component()
来定义
两种写法
方式1:
Vue.component(组件名, 组件构造器)
先创建组件构造器,然后由组件构造器创建组件
方式2:
Vue.component(组件名, 选项对象)
直接创建组件,传入一个选项对象
本质上还是自动调用 Vue.extend 先创建组件构造器
注:组件必须在一个已存在的Vue实例中使用,不能在页面独立使用和存在
2. 局部组件
局部组件的定义,依赖于某个Vue实例,通过选项 components:{}
来定义
用法:
1 | new Vue({ |
三、组件间数据传递
1. 组件间的关系
页面组件的关系结构,是一个由许多组件构成的树状结构,组件间存在着两种关系:父子关系、非父子关系
默认情况下,每个组件实例都是独立的,组件间无法直接访问数据,因此需要进行组件间的数据传递,也称为组件间的通信
2. 父子组件间的数据传递
2.1 父向子传递数据
技术:属性绑定+数据拦截
步骤:
- 父组件在调用子组件时,以属性绑定的方式将要传递的数据绑定在子组件标签上
- 在子组件对象中,使用props选项声明获取的数据,进行绑定属性的拦截,即接收来自父组件的数据
2.2 子向父传递数据
技术:事件监听+事件触发
步骤:
- 父组件在调用子组件时,监听子组件触发的自定义事件,并在父组件中定义回调方法,用来接收数据
- 在子组件中使用vm.$emit(事件名,数据)触发自定义事件
补充:
- 子组件向父组件传递数据是不具有响应式的,即子组件数据发生变化时并不会主动触发$emit更新父组件中数据
- 可以监视子组件数据的变化,当数据发生变化时手动触发$emit更新父组件中数据
四、内置全局组件
Vue提供了全局的内置组件,这些组件主要完成的都是功能封装
1. 动态组件
多个组件使用同一个挂载点,然后动态地在它们之间切换,称为动态组件
用法:<component :is=""></component>
2. 缓存组件
缓存非活动的组件,可以保留组件状态,避免重新渲染,默认每次都会销毁非活动组件并重新创建
一般会结合动态组件使用,用于缓存非活动的组件实例,避免组件的重复创建和删除,提高性能
用法:<keep-alive>动态组件</keep-alive>
注:<keep-alive>
是一个抽象组件,它自身不会渲染为一个 DOM 元素,也不会出现在组件链中
3. 分发组件
实现内容的分发,可以在定义组件时指定插槽位置,调用组件时提供要替换插槽位置的内容
- 在开发组件时,如果组件模板中部分内容暂时不确定,则可以通过
<slot>
插槽定义页面占位 - 当调用组件时,再定义对应的内容,会自动替换到插槽位置
用法:<slot></slot>
具名插槽:为插槽指定名称,根据插槽名称进行内容分发
- 在定义插槽时,在slot标签上通过name属性为插槽指定名称
- 在提供插槽内容时,通过为template标签指定v-slot指令,并以指令参数表示插槽名称
插槽数据作用域:让插槽内容能够访问子组件中的数据,通过作用域插槽控制内容分发时变量的取值范围
- 在定义插槽时,在slot标签上通过v-bind进行数据绑定
- 在提供插槽内容时,通过v-slot指令接收绑定的数据,获取的是一个自定义对象