vue2面试题:vue组件之间的通信方式有哪些?
- 回答思路:1.组件通信的目的-->2.组件通信的分类-->3.组件通信的方案
-
- 1.组件通信的目的
- 2.组件通信的分类
- 3.组件通信的方案
-
- (1)通过props传递数据
- [(2)emit触发自定义事件](#(2)emit触发自定义事件)
- (3)ref
- (4)EventBus
- (5)parent、root
- (6)attrs与listeners
- (7)provide与inject
- (8)vuex
- 小结
回答思路:1.组件通信的目的-->2.组件通信的分类-->3.组件通信的方案
1.组件通信的目的
每个组件之间都有自己独自的作用区域,组件之间的数据是无法共享的,但在实际开发工作中,我们常常需要让座组件之间共享数据,这也是组件通信的目的
2.组件通信的分类
组件间通信的分类可分为以下:
1.父子组件之间的通信
2.兄弟组件之间的通信
3.祖孙与后代组件之间的通信
4.非关系组件之间的通信
3.组件通信的方案
(1)通过props传递数据
1.适用场景:父组件传递数据给子组件
2.组件设置props属性,定义接收父组件传过来的参数
3.父组件在使用子组件标签中通过字面量来传递值
children.vue:
javascript
props:{
name:String
age:{
type:Number,
default:18,
require:true
}
}
father.vue:
javascript
<children name="tom" age=18>
(2)$emit触发自定义事件
1.适用场景:子组件传递数据给父组件
2.子组件通过$emit触发自定义事件,
$emit第二个参数为传递的值
3.父组件绑定监听器获取到子组件传过来的参数
children.vue:
javascript
this.$emit('add',1)
father.vue:
javascript
<children @add="numAdd($event)" />
(3)ref
1.适用场景:子组件传递数据给父组件
2.父组件通过设置子组件ref来获取数据
father.vue:
javascript
<children ref="foo">
<div>this.$refs.foo</div>
(4)EventBus
1.适用场景:兄弟组件传值
2.创建一个中央事件总线EventBus
3.兄弟组件通过$emit触发自定义事件,第二个参数传递的值
4.另一个兄弟组件通过$on监听自定义事件
javascript
//
class Bus {
constructor() {
this.callbacks = {}; // 事件的名字
}
$on(name, fn) {
this.callbacks[name] = this.callbacks[name] || [];
this.callbacks[name].push(fn);
}
$emit(name, args) {
if (this.callbacks[name]) {
this.callbacks[name].forEach((cb) => cb(args));
}
}
}
// main.js
Vue.prototype.$bus = new Bus() // 将$bus挂载到 vue实例的原型上
// 另一种方法
Vue.prototype.$bus = new Vue() // Vue已经实现了 Bus的功能
children1.vue:
javascript
this.$bus.$emit('foo')`在这里插入代码片`
children2.vue:
javascript
this.$bus.$on('foo',2)
(5)parent、root
通过共同祖辈$parent或者
$root搭建通信桥
兄弟组件:
javascript
this.$parent.on('add',this.add)
另一个兄弟组件:
javascript
this.$parent.emit('add')
(6)attrs与listeners
1.适用场景:祖先传递数据给子孙
2.设置批量向下传属性$attrs和
$listeners
3.class,style等非props属性也是通过$attrs可以将父组件中的这些特定绑定属性传递给子组件
4.可以通过v-bind="$attrs"传入内部组件
javascript
// child:没有在 props中声明 foo
<p>{{$attrs.foo}}</p>
// parent
<HelloWorld foo="foo"/>
javascript
// 给Grandson隔代传值
<Child2 msg="lalala" @some-event="onSomeEvent"></Child2>
// Child2 的儿子
<Grandson v-bind="$attrs" v-on="$listeners"></Grandson>
// Grandson 中
<div @click="$emit('some-event', 'msg from grandson')">
{{msg}}
</div>
(7)provide与inject
1.在祖先组件定义Provide属性返回传递的值
2.在后代组件通过inject接收组件传递过来的值
祖先组件:
javascript
<!-- 祖先组件 -->
<template>
<div>
<child-component></child-component>
</div>
</template>
<script>
export default {
provide: {
message: 'Hello from ancestor',
count: 10
},
components: {
ChildComponent
}
}
</script>
后代组件:
javascript
<!-- 后代组件 -->
<template>
<div>
<p>{{ message }}</p>
<p>{{ count }}</p>
</div>
</template>
<script>
export default {
inject: ['message', 'count']
}
</script>
(8)vuex
1.适用场景:复杂关系的组件数据传递
2.vuex作用相当于一个用来存储共享变量的容器
3.state用来存放共享变量的地方
3.getter:可以增加一个getter派生状态,相当于store中的计算属性,用来获得共享变量的值
4.mutations用来存放修改state的方法
5.actions也是用来存放修改state的方法,在mutations的基础上进行,常用来做一些异步操作
小结
1.父子数据传递:props,$emit,ref
1.1:父传子:props
1.2:子传父:$emit、ref
2.兄弟数据传递:eventbus,$parent
3.祖孙与后代数据传递:attrs与listeners或provide与inject
4.复杂关系数据传递:vuex