1 组件
css: 组件就是一段可以被复用的样式代码
js: 组件就是一段可以被复用的功能代码
vue: 组件是一个包含独立的结构,样式和脚本的代码。可以复用。
使用组件分成三步:
第一步:在模板中使用组件
组件名称字母小写,横线分割单词。注意:首字母不区分大小写。
第二步:在脚本中,定义组件类:Vue.extend({})
参数对象跟new Vue时候传递的参数对象是一样的
例如:可以传递data, compted, methods, watch 等属性。
这些属性的功能都是一样的 ,但是有些属性的写法是特殊的。
data属性:
是一个函数,返回值是绑定的数据。
this指向组件实例(由于该方法执行完毕,才能绑定数据,因此当前的this无法访问模型数据)
template 定义模板的,有两种用法:
第一种:属性值是模板字符串(将组件的模板写在了脚本中)
第二种:属性值是css选择器,此时会将页面中对应元素的内容作为组件的模板。
html定义模板有两种方式:
1 通过script模板标签定义(type="text/template")
2 通过template标签定义(vue建议)
注意:模板中最外层有且只有一个根元素。
第三步 注册组件,有两种方式:
1 全局注册:
Vue.component(name, Comp):全局注册的组件可以在任何组件中使用。
2 局部注册:
components: { name: Comp }:局部注册的组件只能在当前组件中使用
name表示组件名称,要使用驼峰式命名(首字母不区分大小写)
Comp表示组件类。
注意:组件是完成独立的,彼此之间数据,方法等不会共享。
父子组件
由于组件类继承了Vue类,因此组件实例化对象可以看成是vue实例化对象,反之vue实例化对象也可以看成是组件实例化对象。
在vue实例中使用组件,可以将vue实例看成是父组件,将自定义的组件看成是子组件。
2 动态组件
想使用动态组件(一个元素可以对应多个组件类),可以通过component组件实现。
通过is属性定义渲染哪个组件类
可以通过v-bind指令动态绑定
3 组件生命周期
对于一个组件来说,存在三个过程:创建,存在和销毁。因此vue为组件定义生命周期来说明这三个过程。
创建期
当创建组件的时候(如在页面中使用),组件将执行创建期的方法:
beforeCreate 组件创建前,此时数据,事件等还没有初始化
created 组件创建后,此时组件已经绑定了数据,事件等
beforeMount 组件构建前,此时确定了组件的模板,以及渲染的容器元素等。
mounted 组件构建后,此时组件上树了
一个组件在一生中只能创建一次,因此创建期的方法只能执行一次。
一旦组件的模型数据发生改变,组件将会执行存在期的方法
存在期
当组件创建完成,将进入存在期,共分两个阶段:
beforeUpdate 组件更新前,此时数据改变了,视图尚未更新
updated 组件更新后,此时数据和视图都更新了
在一个组件中,可以不停的改变模型数据,因此存在期的方法会不停的执行。
存在期的方法执行完毕,只是说一次更新的结束,存在期仍然继续。
销毁期
当组件从页面中删除(执行了$destroy方法),组件将进入销毁期,执行销毁期的方法,共分两个阶段:
beforeDestroy 组件销毁期,此时组件中的数据等还有监听器。
destroyed 组件销毁后,此时组件的数据所具有的监听器以及子组件等被销毁了。
一旦组件被销毁,就再也无法使用组件了,想使用只能创建新的组件。
以上周期方法this都指向组件实例,没有参数
4 keep-alive
当组件从页面中删除,组件将执行销毁期的方法,如果从页面中移除的时候,不想将组件销毁,可以使用keep-alive组件。
该组件会将从页面中移除的组件暂存到内存中,没有被销毁,再次显示的时候,直接从内存中读取。
由于组件没有被销毁,因此不会执行销毁期的方法。为了表示显示和隐藏的过程,keep-alive组件为内部的组件拓展了两个方法:
activated 组件被激活,可以在页面中看到
deactivated 组件被禁用,从也页面中移除了
5 组件通信
组件是一个完整独立的个体,彼此之间的数据,方法等不会共享,想在组件之间共享数据,可以使用组件通信的技术。
通常有三个方向:
1. 父组件向子组件通信
2. 子组件向父组件通信
3. 兄弟组件间通信
5.1 父组件向子组件通信
父组件向子组件通信就是将父组件的数据,方法传递给子组件。
需要两步:
第一步:在父组件模板中,为子组件元素传递数据
属性值默认是字符串,想传递变量或者方法,要使用v-bind指令动态传递。
命名规范:字母小写,横线分割单词
第二步:在子组件中,接收数据或者方法
在props属性中接收,有两种接收方式:
第一种:属性值是数组,每一个成员代表一个接收的属性名称。
第二种:属性值是对象
key:表示接收的属性名称
value:有三种方式
可以是类型的构造函数:Number, String等
可以是数组,每一个成员代表一种类型(定义多种类型)
可以是对象:
type:表示类型的构造函数
default:默认值,属性值可以是数据,属性值还可以是方法,返回值就是默认的数据。
validator:校验方法,在方法中,校验数据是否合法。
注意:接收属性的时候,属性命名规范:驼峰式命名。
props属性中接收的数据与模型中的数据一样,都添加给实例化对象自身,并设置了特性。
因此既可以在JS中使用,也可以在模板中使用。
子组件中还可以通过$parent属性访问父组件,因此就可以间接的获取父组件中的数据。
但是不建议这么使用,因为这种方式与父组件耦合并且无法校验数据,
所以要使用父组件向子组件传递属性的方式实现通信。
例如定义一个组件在其它组件中使用的话,不能保证其它组件就有msg,color这些属性,所以$parent属于强耦合,而使用props接收数据可以通过default设置默认值,当其它组件没有这个属性时不会报错;
自定义事件
vue也实现了观察者模式,提供了订阅消息,发布消息,注销消息等方法。
$on(type, fn) 订阅消息方法
type:消息名称,
fn:消息回调函数,参数是由$emit方法传递的。
$emit(type, ...args) 发布消息方法
type:消息名称,
...args:从第二个参数开始,表示传递的数据
$off(type, fn) 注销消息方法
type:消息名称
fn:消息回调函数
组件是一个完整独立的个体,因此彼此之间数据不会共享,所以发布消息与订阅消息必须是同一个组件。
自定义事件可以实现子组件向父组件通信,但是不建议,因为访问了$parent,产生了耦合
5.2 子组件向父组件通信
子组件向父组件通信的实现:
在父组件中,订阅消息
在子组件中,通过this.$parent访问父组件,发布消息并传递数据
在父组件中,接收并存储数据
在通信过程中,访问了$parent,因此产生了耦合,所以这种方式不常用。
子组件向父组件通信有两种常用方式:
1、模拟DOM事件
2、传递属性方法
5.2.1 模拟DOM事件
绑定DOM事件:v-on:click=”fn”
模拟DOM事件:v-on:demo=”fn”
demo事件名称就是自定义事件名称
子组件向父组件通信:
1在父组件模板中,为子组件元素绑定自定义事件。
消息名称:字母小写横线分割单词。
注意:绑定事件的时候,不要添加参数集合
如果没有添加参数集合,可以接收所有的数据
如果添加了参数集合,不能接收数据,即使传递了$event也只能接收一条数据
2 在子组件中,通过$emit发布消息,并传递子组件中的数据。
消息名称:字母小写横线分割单词。
注意:这是唯一一个不需要做驼峰式命名转换的地方。
5.2.2 传递属性方法
我们可以向子组件传递父组件方法,让子组件执行父组件方法并传递数据的形式,来实现通信。
第一步:在父组件模板中,为子组件传递父组件中的方法。
第二步:在子组件中,接收方法,执行方法并传递数据,
第三步:在父组件的方法中,接收数据,并存储数据。
5.3 兄弟组件间通信
两个兄弟组件之间没有必然的联系,但是它们都与父组件有联系,因此要实现兄弟组件间通信就是综合使用以上两种通信方式。
父组件向子组件通信
子组件向父组件通信
1 将一个子组件的数据传递给父组件。
2 父组件存储数据,再将新的数据传递给另一个子组件。
---------------------------------------------------------------------------------------------------------------------------
6 组件实现数据双向绑定
vue为简化数据双向绑定,提供了v-model指令。数据双向绑定有两个方向
一个方向是数据由模型进入视图:
通过为元素的value属性绑定数据实现的。
一个方向是数据由视图进入模型:
通过为元素订阅input事件实现的。
v-model指令可以看成是语法糖指令,简化了数据双向绑定的实现。
对于组件实现数据双向绑定与input元素是一样的。在组件中:
通过value属性接收父组件传递的数据(父组件向子组件通信)
通过input事件向父组件传递数据 $emit发布消息(子组件向父组件通信)
------------------------------------------------------------------------------------------------------------------------------------------
7 ref属性
想在脚本中,获取模板中的元素或者组件,可以使用ref属性。
分成两步:
第一步:为元素或者组件添加ref属性。属性值代表它的名称
第二步:在脚本中,通过this.$refs属性,即可获取对应的元素或者组件。
为元素设置ref,获取的是源生的DOM对象,要使用源生的API操作
对组件设置ref,获取的是组件实例化对象。
8 插槽
可以在组件的模板中,使用组件元素内部的其它元素(内容)。
使用插槽分成两步:
第一步:为组件元素内部的子元素设置slot属性,定义插槽名称
第二步:在组件模板中,通过slot组件,插入内容
通过name属性定义插槽名称,如果没有定义name属性,将插入默认的的元素。
如果不想引入slot属性所在的元素,可以使用template模板元素。
此时slot属性要改成v-slot指令
使用方式: v-slot:name
v-slot指令语法糖:# 可以写成 #name
注意:不能在普通的元素上使用v-slot指令。
插槽作用域就是说,在组件元素内部的子元素中,使用的数据存储在哪里。
在父组件模板中,组件元素内部的子元素仍然使用的是父组件中的数据。
插槽作用域技术就是让我们在组件元素内部的子元素中,可以使用子组件中的数据
共分两步:
第一步:在子组件模板中,为slot组件传递属性数据。
命名规范:字母小写,横线分割单词。
想动态传递数据,要使用v-bind指令。
第二步:在子组件元素内,通过v-slot指令定义数据的命名空间
命名空间中的数据名称:要使用驼峰式命名。