Vue学习笔记之--组件通信

Vue 学习笔记之–组件通信

1.基本的props传递

vue可以像react一样使用props为子组件传递数据,来实现最基本的父组件向子组件间进行通信。

使用方式

  • 子组件显式生明

    • 子组件需要使用props属性对父组件传递下来的参数进行显示声明,
    • 同时,HTML不区分大小写,需要为驼峰式命名aBc转为a-bc.如:
1
2
3
4
5
6
7
8
9
10
Vue.component('child', {
// 声明 props,为驼峰式命名
props: ['myMsg'],
// prop 可以用在模板内
template: '<span>{{ myMsg }}</span>',
// 可以用 `this.myMsg ` 进行调用及设置
ready: function(){
alert(this.myMsg)
}
})
  • 父组件传递数据
1
2
3
4
//转为kebab-case
<child my-msg="hello"></child>
//绑定动态的数据时,使用
<child :my-msg="parentMsg"></child>
  • 设置数据绑定类型

    • props默认的传递及绑定方式为 父级 -> 子级 ,当父级属性改变时,会默认的传递到子级。为了防止子组件无意中改变父组件的属性,父级属性不会随props改变而变化。
    • 想要强制双向绑定,可以使用如下:
1
2
3
4
5
6
7
8
<!-- 默认为单向绑定 -->
<child :msg="parentMsg"></child>
<!-- 双向绑定 -->
<child :msg.sync="parentMsg"></child>
<!-- 单次绑定 -->
<child :msg.once="parentMsg"></child>
  • 引用类型传递

    如果props传递的对象类型为一个对象或者数组,为引用类型传递,子组件的修改都会影响到父级状态!

  • prop验证,设默

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Vue.component('example', {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型 (1.0.21+)
propM: [String, Number],
// 必需且是字符串
propB: {
type: String,
required: true
},
// 数字,有默认值
propC: {
type: Number,
default: 100
},
// 对象/数组的默认值应当由一个函数返回
propD: {
type: Object,
default: function () {
return { msg: 'hello' }
}
},
// 指定这个 prop 为双向绑定
// 如果绑定类型不对将抛出一条警告
propE: {
twoWay: true
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
},
// 转换函数(1.0.12 新增)
// 在设置值之前转换值
propG: {
coerce: function (val) {
return val + '' // 将值转换为字符串
}
},
propH: {
coerce: function (val) {
return JSON.parse(val) // 将 JSON 字符串转换为对象
}
}
}
})

2. slot内容分发

当我们想要对组件内部动态添加内容时,则需要使用slot进行内容分发。类似react的props.children,如下所示

子组件:

1
2
3
4
5
6
7
8
9
10
11
<div>
<h1>slot内容分发</h1>
//预留的标题位置
<slot name="title">
没有分发内容,默认显示这段话
</slot>
//预留的内容位置
<slot name="content">
没有分发内容,默认显示这段话
</slot>
</div>

父组件:

1
2
3
4
<child>
<h2 slot="title">这是想添加的标题</h2>
<p slot="content>这是想添加的<b>内容</b></p>
</child>

结果:

1
2
3
4
5
<div>
<h1>slot内容分发</h1>
<h2 slot="title">这是想添加的标题</h2>
<p slot="content>这是想添加的<b>内容</b></p>
</div>

3.自定义事件

vue提供了以下几种方式来进行组件间的通信:

  • $on() 监听事件
  • $emit() 触发事件
  • $dispatch() 派发事件,触发父链组件的某事件
  • $broadcast() 广播事件,触发所有后代的某事件

Vue 事件在冒泡过程中第一次触发回调之后自动停止冒泡,除非回调明确返回 true

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//子组件
Vue.component('child', {
template: '#child-template',
ready: function() {
//调用父链的child-msg方法并传递参数
this.$dispatch('child-msg', '我ready了!')
}
})
//父组件
//1.使用events进行监听
Vue.component('parent', {
template: '#parent-template',
events: {
//events自动调用$on,监听事件
'child-msg': function(msg){
alert(msg);
}
}
})
//2.使用v-on进行监听,调用handleMsgmsg方法,更直观
<child @child-msg="handleMsg"></child>

3.子组件索引

可以通过$refs直接引用子组件实例,如:

1
2
3
4
5
6
7
Vue.component('parent', {
template: '<child v-ref:child></child>',
ready: function(){
//访问子组件
var child = this.$refs.child;
}
})