父子组件通信 defineProps
在 Vue 3 中,父组件向子组件传递数据通常通过props实现。使用defineProps 选项来声明子组件接收的props
父组件:
<template>
<Child :message="message"/>
</template>
<script setup>
import Child from './child.vue'
import { ref } from 'vue'
const message=ref('父类的数据')
</script>
子组件:
<template>
<div>
<p>{{message}}</p>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props=defineProps({
message: {
type: String,
required: true
}
})
</script>
当子组件修改父组件的数据时,有两种方法:
1.传递修改函数
父组件:
<template>
<Child :message="message" :updateMessage="updateMessage"/> //传递修改方法
</template>
<script setup>
import Child from './child.vue'
import { ref } from 'vue'
const message=ref('父类的数据')
function updateMessage() {
message.value = '修改后父类的数据';
}
</script>
子组件:
<template>
<div>
<p>{{message}}</p>
<button @click="updateMessage">Change</button>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props=defineProps({
message: {
type: String,
required: true
},
updateMessage:{
type: Function,
required: true
}
})
</script>
2.自定义事件
子组件能够修改父组件的数据时,可以通过定义一个自定义事件并在父组件中监听该事件
父组件:
<template>
<Child :message="message" @update="changeMsg"/> //监听(订阅)事件
</template>
<script setup>
import Child from './child.vue'
import { ref } from 'vue'
const message=ref('父类的数据')
function changeMsg(value) {
message.value = value;
}
</script>
子组件:
<template>
<div>
<p>{{message}}</p>
<button @click="updateMessage">Change</button>
</div>
</template>
<script setup>
import { defineProps , defineEmits } from 'vue';
const props=defineProps({
message: {
type: String,
required: true
},
})
// 定义一个自定义事件 update,并在父组件中通过 v-on:update 接收并处理
const emits = defineEmits(['update']); //定义事件
const updateMessage = () => {
emits('update', '修改后父类的数据'); //发布事件
}
</script>
子父通信 defineEmits
当我们希望子组件能够将数据传递给父组件时,通常的做法是通过子组件触发事件使用defineEmits来通知父组件。
子组件:
<template>
<div>
<h2>子组件</h2>
<p>消息:{{ message }}</p>
<button @click="updateMessage">change</button>
</div>
</template>
<script setup>
import { ref,defineExpose } from 'vue'
const message=ref('子类的数据')
function updateMessage() {
message.value = '子组件的消息已更改';
}
defineExpose({ message, updateMessage });
</script>
父组件:
<template>
<Child ref="childRef" />
<div>
<h2>父组件</h2>
<p>消息:{{parentMessage }}</p>
<button @click="updateFromChild">childeMsg</button>
</div>
</template>
<script setup>
import Child from './child.vue'
import { ref } from 'vue'
const parentMessage = ref('父组件的初始消息');
const childRef = ref(null);
function updateFromChild() {
parentMessage.value = childRef.value.message;
}
</script>
跨级通信 provide && inject
provide和inject是一种在组件树中进行跨层级通信的方式。它们允许你将数据从祖先组件传递给其后代组件,而无需通过中间组件逐层传递 props。这种方式特别适合于那些需要被多个组件访问的数据或方法,而且这些组件之间没有直接的父子关系。
祖先组件:
<template>
<div>
<h1>Top Component</h1>
<middle-component />
</div>
</template>
<script setup>
import MiddleComponent from './Middle.vue';
const topData = 'Data from the top component';
provide('topData', topData);
</script>
中间组件:
<template>
<div>
<h2>Middle Component</h2>
<leaf-component />
</div>
</template>
<script setup>
import LeafComponent from './Leaf.vue';
</script>
子孙组件:
<template>
<div>
<h3>Leaf Component</h3>
<p>Data from top: {{ topData }}</p>
</div>
</template>
<script setup>
import { inject } from 'vue';
const topData = inject('topData');
</script>