1.总结
defineProps
:子组件接收父组件中传递来的值defineEmits
:子组件调用父组件传递过来的方法defineExpose
:子组件暴露方法和属性给父组件使用provide
:上级组件暴露属性和方法给下级组件,下级组件通过inject
接受属性和方法
2.示例
- defineProps
// 父组件:
<Son msg="父组件的值"></Son>
// 子组件 script
import { defineProps } from 'vue'
const props = defineProps({ msg: { type: String } });
2.defineEmits
// 父组件:
<Son @faterFn="handleFn"></Son>
// script
const handleFn = () => { console.log('父组件的方法') }
// 子组件 script
import { defineEmits } from 'vue'
const emit = defineEmits(["faterFn"]);
emit('faterFn')
// emit('faterFn', '这里可以向父级传递参数')
3.defineExpose
// 子组件 script
import { ref, defineExpose } from "vue";
const toFatherValue = ref<string>("我是要暴露给父组件的值")
const toFatherMethod = () => { console.log("我是要暴露给父组件的方法")}
defineExpose({ toFatherMethod, toFatherValue })
// 父组件:
<Son ref="sonRef"></Son>
// script
// 接收子组件defineExpose暴露出来的属性和方法
const sonRef = ref()
onMounted(() => {
sonRef.value.toFatherMethod()
console.log(sonRef.value.toFatherValue)
})
4.provide和inject
// 父组件:
import { provide } from "vue";
provide('toChildValue', 'provide暴露属性给下级组件')
const provieFn = () => { console.log('provide暴露方法给下级组件') }
provide('toChildFn', provieFn)
// 子组件
// 接收上级组件provide暴露的属性 inject(接收名,默认值)
const getFatherValue = inject("toChildValue", '子');
console.log('getFatherValue', getFatherValue);
// 接收上级组件provide暴露的方法
const getFatherFn = inject('toChildFn') as Function
getFatherFn()
5.完整代码
父组件:
// Father.vue
<template>
<div class="parent">
<div style="margin: 10px">我是父组件</div>
<Son msg="父组件的值" @faterFn="handleFn" ref="sonRef"></Son>
</div>
</template>
<script setup lang="ts">
import Son from "./Son.vue";
import { ref, onMounted, provide } from "vue";
// 传递给子组件方法
const handleFn = (res: string) => { console.log('父组件的方法', '接收子参数:', res) }
// 接收子组件defineExpose暴露出来的属性和方法
const sonRef = ref()
onMounted(() => {
sonRef.value.toFatherMethod()
console.log(sonRef.value.toFatherValue)
})
// provide暴露属性给下级组件
provide('toChildValue', 'provide暴露属性给下级组件')
const provieFn = () => { console.log('provide暴露方法给下级组件') }
provide('toChildFn', provieFn)
</script>
<style scoped>
.parent {
border: 3px solid cornflowerblue;
width: 400px;
text-align: center;
margin: 8px 0;
}
</style>
子组件:
// Son.vue
<template>
<div style="margin: 10px; border: 2px solid red">
我是子组件
<div style="margin: 5px; border: 2px solid gold">
父组件传值接收区:{{ msg }}
</div>
<div @click="invokefaFn">调用父方法</div>
</div>
</template>
<script setup lang="ts">
import { defineProps, defineEmits, defineExpose, ref, inject } from 'vue'
// 接收父值
const props = defineProps({ msg: { type: String } });
console.log('props', props.msg);
// 接收父方法并调用且传参
const emit = defineEmits(["faterFn"]);
const invokefaFn = () => { emit('faterFn', '向父传参') }
// 暴露给父组件的值
const toFatherValue = ref<string>("我是要暴露给父组件的值")
// 暴露给父组件的方法
const toFatherMethod = () => { console.log("我是要暴露给父组件的方法") }
// 暴露方法和属性给父组件
defineExpose({ toFatherMethod, toFatherValue })
// 接收上级组件provide暴露的属性和方法
const getFatherValue = inject("toChildValue", '子');
console.log('getFatherValue', getFatherValue);
const getFatherFn = inject('toChildFn') as Function
getFatherFn()
</script>