我们通常会把整个页面被分成小组件,这些组件有自己的功能和 UI。 有时,我们需要一种方法来在这些组件之间进行通信。
我们可以使用 Vuex(状态管理工具)来存储数据并跨组件使用。 但有时,我们需要一种方法将数据从一个组件发送到另一个组件,而无需使用 Vuex 存储。
请看下面:
1、使用Props (父组件通信子组件)
2、使用Events 事件(子组件通信父组件)
3、使用Event Bus 事件总线(父通信子,子通信父)
4、使用provide/inject 提供和注入对(父组件通信子组件)
5、使用this.$refs (子组件通信父组件)
第一种:Props
[父到子]使用Props可以将我们需要传输的数据从父组件传递到子组件。下面我们将使用props从parent.vue发送数据到child.vue
<!-- child.vue 代码 -->
<template>
<div>
{{message}}
</div>
</template>
<script>
export default {
name: "child",
props: ['message'] // 定义一个名为message的变量,在页面进行渲染
}
</script>
<!-- parent 组件 代码 -->
<template>
<div>
<!-- 使用子组件 child,绑定一个参数,参数名为message,值为当前组件变量名为message的值-->
<child :message="message"/>
</div>
</template>
<script>
import Child from "./child"; <!-- 使用子组件 -->
export default {
name: "parent",
components: {Child},
data() {
return {
message: '我是父类的数据'
}
}
}
</script>
第二种:Events
[子到父]通过子组件触发事件将数据发送到父组件,父组件使用v-on进行捕获,捕获时需要和发送事件同名,还可以检索参数this.$emit(‘事件名’, args1, args2, args3,…) 就是一种触发事件的方法
<!-- child 子组件 代码 -->
<template>
<div>
<div @click="sendMessageToParent"></div>
</div>
</template>
<script>
export default {
name: "child",
message: "数据",
methods: {
sendMessageToParent() {
// 点击后触发一个事件 事件名为childSuccess,参数为message
this.$emit("childSuccess", this.message);
}
}
}
</script>
<!-- parent 父组件 代码 -->
<template>
<div>
<!-- 使用子组件 监听事件名为childSuccess的事件,一旦监听到后触发getData方法-->
<child @childSuccess="getData"/>
</div>
</template>
<script>
import Child from "./child";
export default {
name: "parent",
components: {Child},
methods: {
getData(_val) {
// _val 就是子组件的事件携带的参数
console.log(_val)
}
}
}
</script>
第三种:Event Bus
[父到子,子到父]当两个需要互相通信的组件不存在父子关系的时候,需要手动去监听组件上的事件的时候,就可以使用此方法(事件总线)。所以事件总线用于在任何两个组件之间进行通信(组件不需要具有父子关系)。操作方法: 在一个组件使用this.r o o t . root.root.emit(‘事件名’,args1,args2,args3,…); 在另一个组件中使用this.r o o t . root.root.on(‘相同的事件名’,args1,args2,args3,…)
<!--component_one 组件 监听事件-->
<template>
</template>
<script>
export default {
name: "component_one",
mounted() {
this.$root.$on("success", (msg) => {
console.log(msg)
})
}
}
</script>
<!--component_two组件 发布事件-->
<template>
<div @click="sendMessageToComponentOne">
<router-link to="/component_one">点我!</router-link>
</div>
</template>
<script>
export default {
name: "component_two",
methods: {
sendMessageToComponentOne() {
let msg = '你好呀!';
this.$root.$emit("success",msg)
}
}
}
</script>
第四种:provide/inject
[父到子]此类主要是用于更深层嵌套组件的结构,使用这种方式可以更快捷更方便,且子孙后代后可以使用inject
<!-- parent 父组件 -->
<template>
<child />
</template>
<script>
import Child from "./child";
export default {
name: "parent",
components: {Child},
provide() {
return {"eventName": "参数"}
}
}
</script>
<!-- child 子组件 -->
<template>
<div>{{eventName}}</div>
</template>
<script>
export default {
name: "child",
inject: ['eventName'],
}
</script>
第五种:this.$refs
[子到父]一般都不推荐使用此种方法进行数据通信。 使用这种方式的时候,我们需要为子组件一个引用id
<!-- child 子组件 -->
<template>
</template>
<script>
export default {
name: "child",
data() {
return {
value: '你好呀!'
}
}
}
</script>
<!-- parent 父组件 -->
<template>
<child ref="child"/>
</template>
<script>
import Child from "./child";
export default {
name: "parent",
components: {Child},
data() {
return {
message: null
}
},
mounted() {
// 获取子组件上的value值
this.message = this.$refs.child.value;
}
}
</script>