组件的通信方式
1.props/$emits
props的方法比较简单,
e
m
i
t
的方法只需要在子组件调用
t
h
i
s
.
emit的方法只需要在子组件调用this.
emit的方法只需要在子组件调用this.emit,父组件通过下面的方式接受子组件传来的参数(SonData(data))
<Son @SonMethods="SonData"></Son>
父组件
<template>
<div>
<div>Son给APP传递的数据:{{ Sname === "" ? "点击按钮传递" : Sname }}</div>
<Parent :sendName="Pname"></Parent>
<Son @SonMethods="SonData"></Son>
</div>
</template>
<script>
import Son from "./components/Son.vue";
import Parent from "./components/Parent.vue";
export default {
components: {
Parent,
Son,
},
data() {
return {
Pname: "张三",
Sname: "",
};
},
methods: {
SonData(data) {
this.Sname = data;
},
},
};
</script>
<style></style>
Parent子组件
<template>
<div style="width: 300px; height: 200px; background-color: skyblue">
App通过props传给Parent的姓名是:{{ sendName }}
</div>
</template>
<script>
export default {
data() {
return {};
},
props: ["sendName"],
};
</script>
<style></style>
Son子组件
<template>
<div style="width: 300px; height: 200px; background-color: antiquewhite">
<button @click="SendData">点击给父组件传递数据</button>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
SendData() {
this.$emit("SonMethods", "张三儿子");
},
},
};
</script>
<style></style>
2. ref 与 $parent / $children
ref的使用,在子组件标签上进行ref绑定,之后通过
this.$refs.parent
来调用子组件中的数据和方法
$parent / $children 的使用与ref类似,可以不用绑定,通过
this.$children[1]
this.$parent
来获取当前组件的父组件或子组件的实例
父组件
<template>
<div>
APP:{{ msg }}
<Parent ref="parent"></Parent>
<Son></Son>
</div>
</template>
<script>
import Parent from "./components/Parent.vue";
import Son from "./components/Son.vue";
export default {
components: {
Parent,
Son,
},
data() {
return {
msg: "我是APP组件的数据",
};
},
// 这里调用子组件的方法,指的是在子组件中进行调用的方法
mounted() {
this.$refs.parent.change(this.msg);
this.$children[1].sonMoney("APP给Son200元");
},
};
</script>
<style></style>
Parent子组件
<template>
<div style="width: 300px; height: 200px; background-color: skyblue">
我是Parent组件:{{ msg }}
</div>
</template>
<script>
export default {
data() {
return {
msg: "马牛逼",
};
},
methods: {
change(msg) {
this.msg = msg;
},
},
};
</script>
<style></style>
Son子组件
<template>
<div style="width: 300px; height: 200px; background-color: antiquewhite">
Son组件
</div>
</template>
<script>
export default {
data() {
return {
msg: "",
};
},
mounted() {
console.log("son的父组件", this.$parent.msg);
},
methods: {
sonMoney(money) {
console.log(money);
},
},
};
</script>
<style></style>
3.EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信
这个就是把想要的数据传递到一条公共的总线上,在此之前需要配置一下main.js文件
发送数据时
this.$bus.$emit("SendData", this.msg);
接收数据时
this.$bus.$on("SendData", (data) => {
this.msg = data;
});
main.js
const vm = new Vue({
render: h => h(App),
beforeCreate() {
Vue.prototype.$bus = this
}
}).$mount('#app')
App组件
<template>
<div>
APP:{{ msg }}
<Parent></Parent>
<Son></Son>
</div>
</template>
<script>
import Parent from "./components/Parent.vue";
import Son from "./components/Son.vue";
export default {
components: {
Parent,
Son,
},
data() {
return {
msg: "我是APP组件的数据",
};
},
};
</script>
<style></style>
Parent子组件
<template>
<div style="width: 300px; height: 200px; background-color: skyblue">
我是Parent组件:{{ msg }}
<button @click="gogogo">点击按钮传递数据</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "Parent组件的数据",
};
},
methods: {
gogogo() {
this.$bus.$emit("SendData", this.msg);
},
},
};
</script>
<style></style>
Son组件
<template>
<div style="width: 300px; height: 200px; background-color: antiquewhite">
Son组件:{{ msg }}
</div>
</template>
<script>
export default {
data() {
return {
msg: "Son组件的数据",
};
},
mounted() {
this.$bus.$on("SendData", (data) => {
this.msg = data;
});
},
};
</script>
<style></style>
4. $attrs /$listeners 适用于 隔代组件通信
用法:
当隔代传递数据时使用(组件关系app > parent > son),app想给son组件传递数据时使用
在parent组件中给son组件绑定
a
t
t
r
s
和
attrs和
attrs和listeners,使用过的props数据则不会传递,剩下的数据在$attrs中
App组件
<template>
<div>
APP:{{ msg1 }}
<Parent :data1="msg1" :data2="msg2"></Parent>
</div>
</template>
<script>
import Parent from "./components/Parent.vue";
export default {
components: {
Parent,
},
data() {
return {
msg1: "我是APP组件的数据1",
msg2: "我是APP组件的数据2",
};
},
};
</script>
<style></style>
Parent组件
<template>
<div style="width: 300px; height: 200px; background-color: skyblue">
我是Parent组件:{{ msg }} <br />
props:{{ data1 }} <br />
$attrs:{{ $attrs }}
<Son v-bind="$attrs" v-on="$listeners"></Son>
</div>
</template>
<script>
import Son from "./Son.vue";
export default {
components: {
Son,
},
props: ["data1"],
data() {
return {
msg: "Parent组件的数据",
};
},
methods: {},
};
</script>
<style></style>
Son组件
<template>
<div style="width: 300px; height: 200px; background-color: antiquewhite">
Son组件:{{ msg }} <br />
props:{{ data2 }} <br />
$attrs:{{ $attrs }}
</div>
</template>
<script>
export default {
data() {
return {
msg: "Son组件的数据",
};
},
props: ["data2"],
mounted() {},
};
</script>
<style></style>
效果图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kYzxta5K-1662558126196)(C:\Users\王路飞\AppData\Roaming\Typora\typora-user-images\1662554579863.png)]
5. provide / inject 适用于 隔代组件通信
用法:
在祖先组件中使用provide来提供变量,也可以传递方法从而让son组件可以通过调用App组件中的方法来改变App组件中的数据(此写法为响应式)
provide() {
return {
newmsg: this.obj,
newchangedata: this.changedata,
};
},
inject: ["newmsg", "newchangedata"],
methods: {
newChange() {
this.newchangedata("我是更新后APP组件的数据");
},
},
inject:{{ newmsg.msg }}
<button @click="newChange">(Son按钮)改变APP中的数据</button>
App
<template>
<div>
APP:{{ obj.msg }}
<Parent></Parent>
<button @click="changedata('我是更新后APP组件的数据')">
(App按钮)改变数据
</button>
</div>
</template>
<script>
import Parent from "./components/Parent.vue";
export default {
components: {
Parent,
},
data() {
return {
obj: {
msg: "我是APP组件的数据",
},
};
},
methods: {
changedata(val) {
this.obj.msg = val;
},
},
provide() {
return {
newmsg: this.obj,
newchangedata: this.changedata,
};
},
};
</script>
<style></style>
parent组件
<template>
<div style="width: 300px; height: 200px; background-color: skyblue">
我是Parent组件:{{ msg }} <br />
<Son></Son>
</div>
</template>
<script>
import Son from "./Son.vue";
export default {
data() {
return {
msg: "Parent组件的数据",
};
},
components: {
Son,
},
};
</script>
<style></style>
son组件
<template>
<div style="width: 300px; height: 200px; background-color: antiquewhite">
Son组件:{{ msg }} <br />
inject:{{ newmsg.msg }}
<button @click="newChange">(Son按钮)改变APP中的数据</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "Son组件的数据",
};
},
inject: ["newmsg", "newchangedata"],
methods: {
newChange() {
this.newchangedata("我是更新后APP组件的数据");
},
},
};
</script>
<style></style>
5.provide / inject 适用于 隔代组件通信
用法:
先下载插件
npm i pubsub-js
引入
import pubsub from "pubsub-js";
使用(发布一个名为‘hello’的消息,数据是第二个参数)
pubsub.publish("hello", this.msg);
在需要的组件中接收
mounted() {
this.pubId = pubsub.subscribe("hello", this.demo);
},
beforeDestroy() {
pubsub.unsubscribe(this.pubId);
},
methods: {
demo(msgName, content) {
this.msgName = msgName;
this.content = content;
},
},
App
<template>
<div>
APP:{{ msg }} <br />
发布的消息:{{ msgName }} <br />
内容:{{ content }}
<Parent></Parent>
</div>
</template>
<script>
import pubsub from "pubsub-js";
import Parent from "./components/Parent.vue";
export default {
components: {
Parent,
},
data() {
return {
msg: "我是APP组件的数据",
msgName: "",
content: "",
};
},
mounted() {
// 监听hello的消息发布
pubsub.subscribe("hello", this.demo);
},
methods: {
demo(msgName, content) {
this.msgName = msgName;
this.content = content;
},
},
};
</script>
<style></style>
Parent子组件
<template>
<div style="width: 300px; height: 200px; background-color: skyblue">
我是Parent组件:{{ msg }} <br />
<Son></Son>
</div>
</template>
<script>
import Son from "./Son.vue";
export default {
data() {
return {
msg: "Parent组件的数据",
};
},
components: {
Son,
},
};
</script>
<style></style>
Son子组件
<template>
<div style="width: 300px; height: 200px; background-color: antiquewhite">
Son组件:{{ msg }} <br />
<button @click="sendMsg">发布消息</button>
</div>
</template>
<script>
import pubsub from "pubsub-js";
export default {
data() {
return {
msg: "Son组件的数据",
};
},
methods: {
sendMsg() {
pubsub.publish("hello", this.msg);
},
},
};
</script>
<style></style>
|