说明:App.vue(爷爷组件) ----> Song.vue(爸爸组件) ----> Detail.vue(孙子组件)
一.父组件向子组件传值
1.vue2 写法
父组件
<template>
<div id="App">
<h1>我是父组件</h1>
<Child :msgData="msg"></Child>
</div>
</template>
<script>
import Child from "@/components/Child.vue";
export default {
components: { Child },
name: "App",
data() {
return {
msg:'我是父组件向子组件'
};
},
};
</script>
子组件
<template>
<div class="child">
<!-- 使用 -->
<h3>我是child子组件 :{{ msgData }}</h3>
</div>
</template>
<script>
export default {
name: "Child",
//使用 props接收
props: ["msgData"],
},
};
</script>
2.vue3写法:也是使用props 接收
注意:props 是单向的,只适用于父子组件之间
二.子组件向父组件传值
1.vue2写法
父组件
<template>
<div id="App">
<h1>我是父组件</h1>
<!-- 第一步:在父组件内 给子组件标签,添加自定义事件getData -->
<Child @getData="fn"></Child>
<h3>父组件从子组件中获取的数据:{{ childData }}</h3>
<ul v-for="item in childData" :key="item.id">
<li>{{ item.id }} --- {{ item.name }}</li>
</ul>
</div>
</template>
<script>
import Child from "@/components/Child.vue";
export default {
components: { Child },
name: "App",
data() {
return {
msg: "我是父组件向子组件",
// 第二步:定义一个变量用来接收 子组件传递过来的值
childData: "",
};
},
methods: {
fn(fromChildValue) {
this.childData = fromChildValue;
},
},
};
</script>
子组件
<template>
<div class="child">
<!-- 第三步:子组件内 在某个时机内 触发 父组件内 自定义事件 -->
<button @click="childFn">点击触发自定义事件</button>
</div>
</template>
<script>
export default {
name: "Child",
data() {
return {
list: [
{ id: 1, name: "薛之谦" },
{ id: 2, name: "孙燕姿" },
{ id: 3, name: "李荣浩" },
{ id: 4, name: "华晨宇" },
],
};
},
methods: {
childFn() {
// 在子组件内触发父组件内定义事件
this.$emit("getData", this.list);
},
},
};
</script>
2.vue3写法
父组件中与vue2类似定义
子组件
<script>
import { ref } from "vue";
export default {
name: "Child",
setup(props, { emit }) {
emit("getData", list);
},
};
</script>
子组件通过events给父组件发送消息,实际上就是把自己的数据发送到父组件
三.祖孙组件之间的通信
爷爷组件Home.vue
<template>
<div class="home">
<h1>我是爷爷组件</h1>
<Child></Child>
</div>
</template>
<script>
import Child from "@/components/Child.vue";
import { provide, ref } from "vue";
export default {
name: "Home",
components: { Child },
setup() {
const msg = ref("我是爷爷给孙子的数据");
//要传递一个msgData 里面装着一个msg这个数据
provide("msgData", msg.value);
return {};
},
};
</script>
爸爸组件 Child.vue
<template>
<h2>我是爸爸组件</h2>
<Sun></Sun>
</template>
<script>
import Sun from "./Sun.vue";
import { ref } from "vue";
export default {
name: "Child",
components: { Sun },
};
</script>
孙子组件Sun.vue
<template>
// 使用
<h3>我是孙子组件:{{ msgFromGrandFather }}</h3>
</template>
<script>
import { inject, ref } from "vue";
export default {
name: "Sun",
setup() {
// 接收
const msgFromGrandFather = inject("msgData");
return {
msgFromGrandFather,
};
},
};
</script>
四.任意组件之间传值 - 使用全局事件总线(总栈)
1.第一步:在vm上挂载自定义事件 vm上触发自定义事件
main/index.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App),
beforeCreate() {
console.log(this)
//把vm对象挂载到Vue的原型对象上去 为了方便 各个组件的vc对象能获取 vm
Vue.prototype.$bus = this
}
}).$mount('#app')
2.祖孙之间传值
爷爷组件 App.vue
<template>
<div id="App">
<button @click="sendDetail">App父组件 将数据发送给 Detail组件</button>
</div>
</template>
<script>
import Song from "./views/Song.vue";
export default {
components: { Song },
name: "App",
data() {
return {
msg: "我是父组件向孙组件传递的数据",
};
},
methods: {
sendDetail() {
console.log(this.$bus);
this.$bus.$emit("changeMsg", this.msg);
},
},
};
</script>
孙子组件 Detail.vue
<template>
<div class="detail">
{{ dataApp }}
</div>
</template>
<script>
export default {
name: "Detail",
created() {
console.log(this.$bus);
this.$bus.$on("changeMsg", (value) => {
console.log(value);
this.dataApp = value;
});
},
};
</script>