vue组件之间通信方式汇总(5种)
方法一:使用props\$emit进行父子组件间传值
<body>
<div id="app">
<child-a :first-name="firstName" @bind-event="update"></child-a>
</div>
<template id="childA">
<div>firstName:{{firstName}}</div>
</template>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 子组件
const ChildA = {
template:'#childA',
props:['first-name'],
mounted() {
console.log(this.firstName); // 子组件接收到父组件传过来的firstName值
this.$emit('bind-event','张');
}
}
// 父组件
const app = new Vue({
el:'#app',
data:{
firstName:'zhang'
},
methods:{
update(res){
this.firstName = res; // 父组件接收到子组件传过来的值
console.log(this.firstName);
},
},
components:{
ChildA
}
})
</script>
父组件传值到子组件:在子组件上添加动态属性,并在子组件内部添加props,这样子组件内部具有了这个属性。
子组件传值到父组件:在子组件上绑定自定义事件,当该事件触发的时候调用update方法,在子组件内部使用$emit进行事件触发,第二个参数为要传递的值,这样父组件进入update方法,属性值成功更改。
方法二:使用$on\$emit进行所有组件间传值
app.$on('事件名',callback(res)); // 监听自定义事件
app.$emit('事件名',[...args]); // 触发自定义事件
<body>
<div id="app">
<child-a></child-a>
<child-b></child-b>
<child-c></child-c>
</div>
<template id="childA">
<div></div>
</template>
<template id="childB">
<div></div>
</template>
<template id="childC">
<div></div>
</template>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const bus = new Vue(); // 定义一个空vue,作为一个总线传递数据
// 子组件A
const ChildA = {
template:'#childA',
data(){
return{
name:'A',
age:30
}
},
mounted() {
bus.$on('data-b',res=>{
console.log(`${this.name}收到二弟的信息:${res}`);
})
}
};
// 子组件B
const ChildB = {
template:'#childB',
data(){
return{
name:'B',
age:20
}
},
mounted() {
setTimeout(()=>{
bus.$emit('data-b','我是B,马上到家!'); // 触发消息
})
}
};
// 子组件C
const ChildC = {
template:'#childC',
data(){
return{
name:'C',
age:10
}
},
mounted() {
bus.$on('data-b',res=>{
console.log(`${this.name}收到二哥的信息:${res}`);
})
}
};
// 父组件
const app = new Vue({
el:'#app',
data:{
name:'父亲'
},
mounted() {
bus.$on('data-b',res=>{
console.log(`${this.name}收到二儿子的信息:${res}`);
})
},
components:{
ChildA,
ChildB,
ChildC
}
})
</script>
依次打印:
A收到二弟的信息:我是B,马上到家!
C收到二哥的信息:我是B,马上到家!
父亲收到二儿子的信息:我是B,马上到家!
这种方法可以进行任何组件间的传值。
方法三:使用$parent\$refs进行父子组件组件间通信,使用$root获取祖先元素的属性
<body>
<div id="app">
<child-a ref="childA"></child-a>
</div>
<template id="childA">
<div></div>
</template>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 子组件A
const ChildA = {
template:'#childA',
data(){
return{
name:'A',
age:30
}
},
mounted() {
console.log(this.$parent.name);
}
};
// 父组件
const app = new Vue({
el:'#app',
data:{
name:'父亲'
},
mounted() {
console.log(this.$refs.childA.name);
},
components:{
ChildA,
}
})
</script>
依次打印出:
父亲
A
$refs可以获取子组件的属性,$parent可以获取父组件的属性,$root可以获取根组件的属性。
方法四:使用$attrs\$listeners通信组件,不论层次有多深
<body>
<div id="app">
<child-a :name="name" :age="age" :sex="sex"></child-a>
</div>
<template id="childA">
<div>
<grand-child v-bind="$attrs"></grand-child>
</div>
</template>
<template id="grandChild">
<div>grandChild</div>
</template>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 孙子组件
const GrandChild = {
template:'#grandChild',
mounted() {
console.log(this.$attrs);// {name: "张三", sex: "男"}
}
};
// 子组件A
const ChildA = {
template:'#childA',
props:['age'],
components:{
GrandChild
}
};
// 父组件
const app = new Vue({
el:'#app',
data:{
name:'张三',
age:50,
sex:'男'
},
components:{
ChildA,
}
})
</script>
关于$attrs的含义先来看官方文档:

看到这里可能很多朋友不是很理解意思,针对上面代码这里做个讲解。
1、先看父组件——>子组件A
父组件有三个属性(name、age、sex),并且全部向子组件A通过属性方式传递。
子组件A里面通过添加props接受,但是只接受age一个属性。
2、再看子组件A——>孙子组件
孙子组件添加属性v-bind="$attrs",这时候孙子组件具有除了父组件的props以外的所有属性(name和sex)。
一句话解释就是父组件往子组件传没有在props里声明过的值时子组件可以通过attrs接受且只包含父组件没有在props里声明的值
方法五:使用vuex
VueX是适用于在Vue项目开发时使用的状态管理工具。
因为有些vue项目没有使用vuex进行管理,所以具体使用方法详见vuex官方文档,这里不在赘述。
浙公网安备 33010602011771号