## 1.父传子:与vue2一样
```
//传递数据给子组件
data : [{id : 1,name:"Zhangsan"},{id : 2 , name : "Lisi"}]
<Menu v-bind:data="data" title="标题"></Menu>
```
### 子组件接收,通过defineProps 来接受 **defineProps是无须引入的直接使用即可**
```
//正常接收
defineProps({
title:{
default:"",
type:string
},
data:Array
})
//ts接收方式
<script setup lang="ts">
defineProps<{
title:string,
data:number[]
}>()
</script>
```
TS 特有的默认值方式
withDefaults是个函数也是无须引入开箱即用接受一个props函数第二个参数是一个对象设置默认值
```
type Props = {
title?: string,
data?: number[]
}
withDefaults(defineProps<Props>(), {
title: "张三",
data: () => [1, 2, 3]
})
```
## 2.子传父
```
<template>
<div class="menu">
<button @click="submit">子传父</button>
</div>
</template>
//写法一:script + setup
<script setup lang="ts">
const emit = defineEmits(['submit']);
//如果用了ts可以这样两种方式
// const emit = defineEmits<{
// (e: "submit", name: string): void
// }>()
const clickTap = () => {
emit('submit', “测试”)
}
</script>
写法二:export + 组合式api
export default {
emits: ["btn1"],//触发的方法,需要定义,否则会出现警告
props : ["msg"],//接收参数
setup(props, ctx) {
const appPro = inject("appPro");
const appPro1 = inject("appPro1");
console.log(props, "2222");
const btn1 = () => {
ctx.emit("btn1", "子组件");
};
//方法和变量需要retrun出去
return {
btn1,
appPro,
appPro1
};
},
};
```
## 3.依赖注入
```
父组件
<script setup>
import home from "./components/home.vue";
import { provide, reactive, ref } from "vue";
provide("appPro",ref("app"))
provide("appPro1",ref("app1"))
</script>
子组件
<script setup>
import { defineProps, defineEmits, inject } from "vue";
const appPro = inject("appPro")//获取依赖参数
const appPro1 = inject("appPro1")
const emits = defineEmits("btn");
const props = defineProps({
msg: "string",
});
</script>
```
## 4.插槽
```
//子组件
<template>
<div>
//默认插槽
<slot></slot>
</div>
//具名插槽
<slot name="son"></slot>
</template>
//父组件
<home msg="hello" @btn1="btn">
<template #son>我是插槽内容</template>
<template #default>我是默认插槽内容</template>
</home>
```