父传子
父组件可以通过 props(属性)实现向子组件传递数据。
子组件可以通过 defineProps 接收父组件传输的数据。
向子组件传递“字符串型”属性数据
父组件
<script setup>import Nav from "./components/Nav.vue";</script><template><div><!-- 设置子组件的“字符串型”属性,propName与propAge可自定义 --><Nav propName="龙龙" propAge="21" /></div>
</template><style scoped></style>
以上父组件中定义了传给子组件的 “字符串型” 数据
子组件
<template><div><p>从父组件获取的数据有:</p><ins>{{ props.propAge }}</ins><br><ins>{{ props.propName }}</ins></div>
</template><script setup>const props = defineProps(["propName", "propAge"])console.log(props);</script><style lang="scss" scoped></style>
子组件中用 defineProps 接收父组件的数据,并定义其属性 props
向子组件传递“对象型”属性数据
父组件
<script setup>import Nav from "./components/Nav.vue";
//设置传送到子组件的“对象型”属性
const propTest = {name: "龙龙",age: 19, }</script><template><div>//用v-bind 绑定“对象型”属性,用于传送给子组件<Nav v-bind="propTest" /></div>
</template><style lang="scss" scoped></style>
子组件
<template><div><p>从父组件获取的对象型数据有:</p><ins>{{ props.name }}</ins><br><ins>{{ props.age }}</ins></div>
</template><script setup>
// 定义子组件接收父组件数据的"对象类型"的属性
const props = defineProps({name:{type:String // 类型为字符串},age:{type:Number, // 类型为数字// 是否必需传值(若必须传值却没有传,则控制台会给出警告)required:true, default:18 // 默认值}, })console.log(props);</script><style lang="scss" scoped></style>
向子组件传递“响应型”属性数据
父组件
<script setup>
import { reactive } from "vue";
import Nav from "./components/Nav.vue";const propTest = reactive({name: "龙龙",age: 19, })const AddpropTest=()=>{propTest.age++;propTest.name+="好可爱";console.log("单击成功!");}
</script><template><div><Nav v-bind="propTest" /><button @click="AddpropTest">单击我有惊喜</button></div>
</template><style lang="scss" scoped></style>
以上父组件中定义了响应式数据 “propTest” 和 方法“AddpropTest” ,用v-bind 绑定响应式数据用于传送到子组件,使用方法来改变响应式数据的值。
子组件
<template><div><p>从父组件获取的响应型数据属性有:</p><ins>{{ props.name }}</ins><br><ins>{{ props.age }}</ins></div>
</template><script setup>const props = defineProps({name:{type:String // 类型为字符串},age:{type:Number, // 类型为数字required:true, // 是否必需传值(若必须传值却没有传,则控制台会给出警告)default:28 // 默认值}, })console.log(props);</script><style lang="scss" scoped></style>
子组件中使用 defineProps 接收父组件的数据,并定义其属性。当父组件调用方法使数据发生更改时,子组件接收的数据随父组件变化而变化。
单击前
单击后
子传父
defineEmits 是Vue3的编译时宏函数,用于子组件向父组件发送自定义事件
向父组件传递普通数据
子组件
<script setup>const emitTest=defineEmits(["TestPerson"]);
emitTest( "TestPerson" , { name:"龙龙 ", age:19 })</script><template><div></div>
</template><style lang="scss" scoped></style>
以上子组件用宏函数 defineEmits 定义一个名为 emitTest 的对象(名字可以随便取), 用于存储自定义事件 "TestPerson" ;并向父组件发射名为“TestPerson”的自定义事件,并同时传递数据
父组件
<script setup>import Nav from "./components/Nav.vue";const emitprintTest=(Data)=>{console.log(`接收到子组件传来的数据有 ${Data.age} , ${Data.name}`);}</script><template><div><Nav v-on:TestPerson="emitprintTest"/></div>
</template><style lang="scss" scoped></style>
在父组件中用 v-on 绑定一个自定义事件 “emitprintTest” ,用来接收子组件传来的值
向父组件传递响应式数据
子组件
<script setup>const emitTest=defineEmits(["TestPerson"]);
const TestPerson=()=>{emitTest ( "TestPerson" , 2)
}</script><template><div><button @click="TestPerson">点击有惊喜!</button></div>
</template><style lang="scss" scoped></style>
父组件
<script setup>
import { ref } from "vue";
import Nav from "./components/Nav.vue";const person1= ref(0);const emitprintTest=(Data)=>{person1.value+=Data;console.log("点击成功!");}
</script><template><div><p>子组件传递的响应式数据:{{ person1 }}</p>
<Nav v-on:TestPerson="emitprintTest"/></div>
</template><style lang="scss" scoped></style>
单击前
单击后
跨组件通信
当组件需要在 无关系 的组件中传送数据时,我们就可以用到 provide inject 。
provide 用于某个上层组件将数据广播给所有下层组件,inject用于接收数据。
若使用了provide和inject来进行数据传递,则一般不需要再使用defineProps
某上层组件向所有下层组件广播普通数据
上层组件
<template><div><Footer/></div>
</template><script setup>import { provide } from "vue";
import Footer from "./components/Footer.vue";const person = {name:"龙龙", age:28}provide("provideperson", person)</script><style lang="scss" scoped></style>
下层组件
<template><div>
<p>跨组件接收的数据:{{ person.name}} , {{ person.age}}</p></div>
</template><script setup>import {inject} from 'vue'
const person =inject("provideperson")
console.log("provideperson",person);</script><style lang="scss" scoped></style>
上层组件向所有下层组件广播响应式数据
上层组件
<template><div><Footer/></div>
</template><script setup>import { provide,ref } from "vue";
import Footer from "./components/Footer.vue";const num = ref(0)provide("provideNum",num)</script><style lang="scss" scoped></style>
下层组件
<template><div>
<p>跨组件接收的数据:{{ num }} </p></div>
</template><script setup>import {inject,ref} from 'vue'
const num =inject("provideNum")console.log("provideNum:", num.value)</script><style lang="scss" scoped></style>
上层组件向所有下层组件广播函数
上层组件
<template><div><Footer></Footer></div>
</template><script setup>import { provide,ref } from "vue";
import Footer from "./components/Footer.vue";const num = ref(0)provide("provideNum",num)const addNum = () => {num.value++;console.log("单击成功!");} provide("provideFuncAddNum",addNum)</script><style lang="scss" scoped></style>
下层组件
<template><div><p>跨组件接收的数据:{{ num }} </p>
<button @click="funcNumAdd ">添加数字</button></div>
</template><script setup>import {inject} from 'vue'const num =inject("provideNum")console.log("provideNum:", num.value)const funcNumAdd = inject("provideFuncAddNum")console.log("provideFuncAddNum:", funcNumAdd)</script><style lang="scss" scoped></style>
单击前
单击后
同级组件通信
上层兄弟组件
<template><div>
<Nav></Nav></div>
</template><script setup>import {provide} from 'vue'
import Nav from "./Nav.vue";const Test={name:"龙龙",age:22}provide("provideTest",Test)</script><style lang="scss" scoped></style>
下层兄弟组件
<template><div><p>接收到上组件的数据有:{{ Test.name }} , {{ Test.age }}</p></div>
</template><script setup>
import {inject} from 'vue'const Test=inject("provideTest")
console.log("provideTest",Test);</script><style lang="scss" scoped></style>