一、父传子(Props)
1、父组件向子组件传递数据
在父组件的模板中,通过属性绑定的方式将数据传递给子组件。
<template>
<Childvue :message='name' />
</template>
<script>
import Childvue from './views/Childvue .vue';
export default {
components: {
Childvue ,
},
data() {
return {
name: '这是父组件的数据',
};
},
};
</script>
2、在子组件接收数据
在子组件中,通过props
选项声明接收父组件传递过来的属性
<template>
<p>{{message}}</p>
</template>
<script>
export default {
props: {
message: {
type: String, //类型
default:'默认值' //默认值
},
},
};
</script>
二、子传父(emit)
1.子组件触发事件并传递数据
在子组件中,通过emit方法触发一个自定义事件,并传递数据给父组件
<template>
<button @click='change'>子传父</button>
</template>
<script>
import { ref } from "vue";
export default {
setup(props, ctx) {
const num = ref("我是子组件");
const change=()=>{
ctx.emit("handelEvent",num.value)
}
return {
change
};
},
</script>
2.父组件监听事件并接收数据
在父组件的模板中,监听子组件触发的自定义事件,并在事件处理函数中接收数据。
<template>
<Childvue @handelEvent='handelEvent' />
</template>
<script>
import Childvue from './views/Childvue .vue';
import {ref,watch} from 'vue'
export default {
components: {
Childvue ,
},
setup(){
const handelEvent=(val)=>{
console.log(val,'子组件传过来的值1111111')
},
return{
handelEvent
}
}
};
</script>
三、provide / inject 父传子
-
父组件AboutView.vue
<template> <div class="about"> <HomeViewVue></HomeViewVue> </div> </template> <script> import {provide } from 'vue' import HomeViewVue from './HomeView.vue' export default{ components:{ HomeViewVue }, setup(){ provide("message","hello provide") } } </script>
-
子组件HomeView.vue
<template> <div class="home"> {{ getitem }} </div> </template> <script> import {inject,ref} from 'vue' export default { setup(){ const getitem = inject("message") return{ getitem } } } </script>
-
挂载到App.vue
<template> <div> <AboutViewVue /> </div> </template> import AboutViewVue from './views/AboutView.vue' components:{ AboutViewVue },
四、兄弟组件相互传值
1.mitt
Vue3 中没有了 EventBus 跨组件通信,但是现在有了一个替代的方案 mitt.js,原理还是 EventBus。
先安装 npm i mitt -S
封装一下
mitt.js
import mitt from 'mitt'
const mitt = mitt()
export default mitt
在main.js中引入,这个封装的文件
app.config.globalProperties.$bus=Bus
// 组件A
import {ref,getCurrentInstance} from 'vue'
export default {
setup(){
const {proxy} = getCurrentInstance()
const handelEvenbus=()=>{
proxy.$bus.emit("handelEvent",)
}
return{
handelEvenbus
}
}
}
// 组件B
import {onMounted,getCurrentInstance } from "vue";
export default {
setup() {
const {proxy} =getCurrentInstance()
onMounted(()=>{
proxy.$bus.on("handelEvent",()=>{
console.log("兄弟组件通讯")
})
})
},
};
2.provide/inject
创建一个提供共享数据的组件(如 providercomponent.vue),使用 provide 函数来提供数据:
<template>
<div>
<p>共享数据的组件: {{ sharedData }}</p>
<slot></slot>
</div>
</template>
<script>
import { ref, provide } from "vue";
export default {
setup() {
// provide 函数来提供数据
const sharedData = ref("测试数据");
provide("sharedData", sharedData);
return{
sharedData
}
},
};
</script>
在需要接收数据的兄弟组件(如 siblinga.vue 和 siblingb.vue)中,使用 inject 来接收提供的数据,并且可以进行修改:
<template>
<div>
<p>组件 a</p>
<p>获取到的共享数据:{{ sharedData }}</p>
<button @click="increaseData">点击触发</button>
<div>--------------------------------------</div>
</div>
</template>
<script>
import { inject } from "vue";
export default {
setup() {
// 使用 inject 来接收提供的数据,并且可以进行修改
const sharedData = inject("sharedData");
const increaseData = () => {
sharedData.value = "组件a更改后的数据";
};
return{
increaseData,
sharedData
}
},
};
</script>
<template>
<div>
<p>组件 b</p>
<p>获取到的共享数据: {{ sharedData }}</p>
<p>
<button @click="handelClick">组件b修改数据</button>
</p>
</div>
</template>
<script>
import { inject } from "vue";
export default {
setup() {
const sharedData = inject("sharedData");
const handelClick=()=>{
sharedData.value="组件b更改了数据"
}
return{
sharedData,
handelClick
}
},
};
</script>
在父组件(如 parentcomponent.vue)中使用 providercomponent 和两个兄弟组件:
<template>
<div>
<providercomponent>
<siblinga />
<siblingb />
</providercomponent>
</div>
</template>
<script setup>
import providercomponent from './providercomponent.vue';
import siblinga from './siblinga.vue';
import siblingb from './siblingb.vue';
</script>
将parentcomponent.vue父组件挂载到App.vue
<Providercomponent />
import Providercomponent from "./components/parentcomponent.vue";
components: {
Providercomponent,
},