通讯

  1. props
    父组件给子组件添加属性 :fatherName=”name” 传值,子组件通过 props:[‘fatherName’] 接收; 子组件可以通过 this.$emit(‘changeFatherName’,’吴彦祖’) 向父组件发送事件和数据, 父组件通过 @changeFatherName=”changeFatherName” 监听事件和传递过来的数据

  2. sync/update
    v2.3 新增语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器;
    子组件 update:propName 直接修改数据,父组件无需定义监听事件来接收数据 this.$emit(‘update:fatherName’, ‘吴彦祖’) 适合基本数据类型的传递和修改

  3. provide/inject
    父组件通过 provide:{fatherAge:30}传值,子组件通过 inject:[“fatherAge”]接收,provide 传递的数据, 不仅所有子组件都可以接收,所有后代组件均可以通过 inject 接收到

  4. $attrs/$listeners
    v2.4 新增
    $attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的属性绑定 (class 和 style 除外)。 例如,父组件传递了 fatherName,fatherAge,fatherJob 三个属性 而子组件只通过props接收了fatherName 属性 子组件会默认渲染成

    , inheritAttrs:false 可以阻止这种默认行为, 子组件可以通过 v-bind=”$attrs” 将这些属性传递给孙组件,相当于:fatherAge=”$attrs.fatherAge” :fatherJob=”$attrs.fatherJob”
    $listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器,它可以通过 v-on=”$listeners” 传入内部组件 本例中子组件 可以用$listeners 将父组件的 changeFatherName 事件监听传递给孙组件,使孙组件可以跨级修改父组件 data

  5. $children/$parent
    父组件通过$children访问子组件属性和方法,子组件通过$parent 访问父组件属性和方法,this.$children[0].age=2 修改子组件数据,同理this.$parent.age=30 修改父组件数据

  6. 子组件直接修改 props/inject 传过来的值

如果 props 是基本数据类型,子组件中的 prop 会变化,父组件中不会变化且控制台会报错
如果 props 是引用数据类型,父组件和子组件都会成功修改且不会报错(不建议这么做)

EventBus
eventBus 又称为事件总线,在 vue 中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心, 可以向该中心注册发送事件或接收事件, 所有组件都可以通知其他组件。 (维护困难,eventName 起名字困难,不易维护,不及时注销事件会产生各种问题,复杂项目中还是使用 Vuex)

localStorage/sessionStorage
本地存储,某些业务中使用较多,比如记住用户 tocken 系统设置等 window.localStorage.getItem(key) 获取数据,通过 window.localStorage.setItem(key,value) 存储数据; 注意:value 只能值字符串类型,需要用 JSON.parse() / JSON.stringify() 转换 sessionStorage 同理

父向子通信

父组件通过自定义属性向子组件通信,而子组件需要通过在 props 中接收该自定义属性名来完成通信,根据属性值的不同又分为静态和动态传参(例:为静态传参,如果 mian 是通过 v-bind 来绑定的数据,则为动态传参)
父组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div>
<Child :mian="title"></Child>
</div>
</template>

<script>
import Child from '@/Child'
export default{
name:'Parent',
data(){
title:'我是父亲'
},
components:{
Child
}
}
</script>

子组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>
{{title}}
</div>
</template>

<script>
export default{
name:'Child',
props:{
title:{
type:String
}
}
}
</script>

子向父通信

方案一:this.$emit(eventname,data)
父组件通过 v-on 来监听子组件,通过回调函数获取参数
子组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>
<button @click="val">点击</button>
</div>
</template>

<script>
export default{
name:'Child',
methods:{
val(){
this.$emit('list',123)
}
}
}
</script>

父组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<div>
<Child v-on:list="add"></Child>
</div>
</template>

<script>
import Child from '@/Child'
export default{
name:'Parent',
methods:{
add(data){
console.log(data) //123
}
},
components:{
Child
}
}
</script>

方案二:

父组件向子组件传递一个函数
子组件调用父组件的函数,并传入参数
父组件声明函数位置,就可以获得对应参数

父组件调用子组件函数

ref 获得子组件实例,调用函数即可
ref 获得子组件实例,通过实例派发一个事件发射器,子组件监听派发事件,触发函数

同级组件通讯

  • EventBus
  • EventHub

跨级组件通讯

provoder inject
父组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
<div>
父组件
</div>
</template>

<script>
import Child from '@/components/Child'
export default {
components:{
Child,
},
provide(){ //provide作为一个方法使用 ( 推荐使用 )。
return{
'userName' : 'zhangsan',
}
},
/*
provide : { //provide也可以作为一个对象进行使用.
"userName" : 'zhangsan',
}
*/
}
</script>

子组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<div>
子组件
</div>
</template>
<script>
export default {
// inject:['userName'] //inject后面用一个数组接收
inject:{ //inject后面可以是一个对象
userName:{
default:'默认值' //指定默认值
}
}
}
</script>

$attrs $listener

this.$attrs 使用方法:

父组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div>
我是父组件
<Child a='a' :b='b'></Child>
</div>
</template>

<script>
import Child from '@/components/Child'
export default {
name:'Parent',
data(){
return {
b:123
}
}
components:{
Child
}
}
</script>

子组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<div>
我是子组件
</div>
</template>

<script>
export default {
name:'Child',
mounted() {
console.log(this.$attrs) //返回值为对象,获取父组件上传的所有值 {a:a,b:123}
},
}
</script>