知食记
搜索文档…
组件间通信

方法1 props/$emit

父组件A通过props的方式向子组件B传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现。

方法2 空组件实例的$emit/$on

这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。

方法3 vuex

方法4 $attrs/$listeners

$attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。
$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件
实现 A 传递数据 到 C
A组件
1
<template>
2
<div>
3
<h2>组件A 数据项:{{myData}}</h2>
4
<B @changeMyData="changeMyData" :myData="myData"></B>
5
</div>
6
</template>
7
<script>
8
import B from "./B";
9
export default {
10
data() {
11
return {
12
myData: "100"
13
};
14
},
15
components: { B },
16
methods: {
17
changeMyData(val) {
18
this.myData = val;
19
}
20
}
21
};
22
</script>
23
复制代码
Copied!
B组件
1
<template>
2
<div>
3
<h3>组件B</h3>
4
<C v-bind="$attrs" v-on="$listeners"></C>
5
</div>
6
</template>
7
<script>
8
import C from "./C";
9
export default {
10
components: { C },
11
};
12
</script>
Copied!
C组件
1
<template>
2
<div>
3
<h5>组件C</h5>
4
<input v-model="myc" @input="hInput" />
5
</div>
6
</template>
7
<script>
8
export default {
9
props: { myData: { String } },
10
created() {
11
this.myc = this.myData; // 在组件A中传递过来的属性
12
console.info(this.$attrs, this.$listeners);
13
},
14
methods: {
15
hInput() {
16
this.$emit("changeMyData", this.myc); // // 在组件A中传递过来的事件
17
}
18
}
19
};
20
</script>
Copied!

方法5 provide/inject

provideinject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。
假设有两个组件: A.vue 和 B.vue,B 是 A 的子组件
1
// A.vue
2
export default {
3
provide: {
4
name: 'Mike'
5
}
6
}
Copied!
1
// B.vue
2
export default {
3
inject: ['name'],
4
mounted () {
5
console.log(this.name); // Mike
6
}
7
}
Copied!
provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。比如使用Vue.obserbable 方法响应式provide

方法6 $parent/$children 与 ref

    ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
    $parent / $children:访问父 / 子实例
需要注意的是:这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。
不过,这两种方法的弊端是,无法在跨级或兄弟间通信
1
// component-a 子组件
2
export default {
3
data () {
4
return {
5
title: 'Vue.js'
6
}
7
},
8
methods: {
9
sayHello () {
10
window.alert('Hello');
11
}
12
}
13
}
14
复制代码
Copied!
1
// 父组件
2
<template>
3
<component-a ref="comA"></component-a>
4
</template>
5
<script>
6
export default {
7
mounted () {
8
const comA = this.$refs.comA;
9
console.log(comA.title); // Vue.js
10
comA.sayHello(); // 弹窗
11
}
12
}
13
</script>
Copied!
最近更新 1yr ago