Vue 组件通信全解析:Props、Emit 与 defineExpose
Vue 组件通信全解析:Props、Emit 与 defineExpose
在 Vue 开发中,组件通信是构建复杂应用的关键部分。Vue 提供了多种方式来实现组件之间的数据传递和交互,本文将详细介绍三种常见的组件通信方式:父组件向子组件传递数据(props)、子组件向父组件传递数据(emit)以及子组件向父组件暴露数据(defineExpose),并结合具体代码示例进行讲解。
1. 父组件向子组件传递数据:props
原理
props 是 Vue 中用于实现父组件向子组件传递数据的机制。父组件可以通过在子组件标签上绑定属性的方式,将数据传递给子组件。子组件则使用 defineProps 来声明和接收这些数据。
代码示例
在 defineProps.vue 文件中,父组件定义了一个 msg 的响应式变量:
<script setup>
import {ref} from 'vue'
import ChildComponent from '@/components/ChildComponent.vue'
const msg = ref(0)
</script>
<template>
<ChildComponent :msg="msg" />
</template>
在 ChildComponent.vue 文件中,子组件使用 defineProps 来接收 msg:
<script setup>
import { onMounted,ref } from 'vue';
const props = defineProps({
msg: {
type: Number,
required: true
}
})
</script>
<template>
<p>我是父组件传过来的值(msg):{{ msg }}</p>
</template>
在上述代码中,父组件通过 :msg="msg" 将 msg 变量传递给子组件,子组件使用 defineProps 声明并接收 msg,然后在模板中显示该值。
2. 子组件向父组件传递数据:emit
原理
emit 是 Vue 中用于实现子组件向父组件传递数据的机制。子组件可以通过触发自定义事件,并携带数据,将数据传递给父组件。父组件则监听这些自定义事件,并在事件触发时执行相应的处理函数。
代码示例
在 ChildComponent.vue 文件中,子组件定义了一个 msg2 的响应式变量,并通过 defineEmits 声明了一个自定义事件 pass-msg-to-father:
<script setup>
import { onMounted,ref } from 'vue';
const props = defineProps({
msg: {
type: Number,
required: true
}
})
const emit = defineEmits(['pass-msg-to-father'])
const msg2 = ref(666)
onMounted(()=>{
emit('pass-msg-to-father', msg2)
})
const handleClick = () => {
msg2.value++
emit('pass-msg-to-father', msg2)
}
</script>
<template>
<button @click="handleClick">msg2++</button>
</template>
在 defineProps.vue 文件中,父组件监听 pass-msg-to-father 事件,并在事件触发时执行 getMagFromSon 函数:
<script setup>
import {ref} from 'vue'
import ChildComponent from '@/components/ChildComponent.vue'
const msg2 = ref('')
const getMagFromSon = (data) => {
msg2.value = data.value
}
</script>
<template>
<ChildComponent :msg="msg" @pass-msg-to-father="getMagFromSon"/>
<p>这是子组件传给父组件的值(msg2):{{ msg2 }}</p>
</template>
在上述代码中,子组件在挂载时和点击按钮时分别触发 pass-msg-to-father 事件,并携带 msg2 数据。父组件监听该事件,并在事件触发时更新 msg2 的值。
3. 子组件向父组件暴露数据:defineExpose
原理
defineExpose 是 Vue 3 中新增的一个 API,用于在 <script setup> 中向父组件暴露数据和方法。默认情况下,在 <script setup> 中定义的所有变量和方法都是私有的,父组件无法直接访问。使用 defineExpose 可以将这些变量和方法暴露给父组件。
代码示例
在 ChildComponent2.vue 文件中,子组件定义了一个 sonMsg 的响应式变量和一个 changeSonMsg 方法,并使用 defineExpose 将它们暴露给父组件:
<script setup>
import {ref} from 'vue'
const sonMsg = ref(999);
const changeSonMsg = () => {
sonMsg.value++
}
defineExpose({
sonMsg,
changeSonMsg
})
</script>
<template>
<p>这是子组件自己的值(sonMsg):{{ sonMsg }}</p>
</template>
在 defineProps.vue 文件中,父组件通过 ref 引用子组件,并调用子组件暴露的方法和访问暴露的数据:
<script setup>
import {ref} from 'vue'
import ChildCommonent2 from '@/components/ChildComponent2.vue'
const son2 = ref(null)
const son2Msg = ref(-1)
const getMsgFromSon2 = () => {
console.log(son2.value.sonMsg)
son2.value.changeSonMsg()
son2Msg.value = son2.value.sonMsg
console.log(son2.value.sonMsg)
}
</script>
<template>
<ChildCommonent2 ref="son2"/>
<p>这是子组件通过defineExpose暴露给父组件的值(son2Msg):{{ son2Msg}}</p>
<button @click="getMsgFromSon2">修改子组件2的值</button>
</template>
在上述代码中,子组件使用 defineExpose 暴露了 sonMsg 和 changeSonMsg,父组件通过 ref 引用子组件,并调用 changeSonMsg 方法更新子组件的值,同时访问 sonMsg 数据。
总结
通过 props、emit 和 defineExpose,我们可以实现 Vue 组件之间的灵活通信。props 用于父组件向子组件传递数据,emit 用于子组件向父组件传递数据,defineExpose 用于子组件向父组件暴露数据和方法。这些机制为我们构建复杂的 Vue 应用提供了强大的支持。
更多推荐

所有评论(0)