1.props
// 父组件
<template>
<div>
<!-- 使用子组件 -->
<son :son="son" :sendFun="sendFun" />
</div>
</template>
<script lang="ts" setup>
import {ref} from "vue"
import son from "./son.vue" // 引入子组件
const son = ref('传送过去的数据') // 传送给子组件的数据
const review = ref('子给父回传的数据') // 通过给子组件传一个函数,子组件触发函数传参
// 发送给子组件方法
const sendFun = (value:string)=>{
// 通过给子组件传一个函数,子组件触发函数传参
review.value = value
}
</script>
//子组件
<template>
<div>
<!-- 使用父组件传送过来的数据 -->
{{son}}
<!-- 使用父组件传送过来的方法 -->
<div @click = "sendFun('返回的数据')"></div>
</div>
</template>
<script lang="ts" setup>
// 第一种声明接收方式
defineProps(['son','sendFun'])
// 第二种声明接收方式(对象型)
defineProps({
son:{
type:String, // 声明类型
default:'zzz', // 默认值
required:true, // 该数据是否为必传
}
})
// 还有泛型写法等等就不一一列举了(这里只列举了几种常用的方式)
</script>
2. 自定义事件
// 父组件
<template>
<div>
<!-- 使用子组件,绑定自定义事件 -->
<son @sonFun = "sonFun" />
</div>
</template>
<script lang="ts" setup>
import {ref} from "vue"
import son from "./son.vue" // 引入子组件
// 自定义函数
const sonFun = (e)=>{
}
</script>
//子组件
<template>
<div>
<!-- 点击事件触发,然后在事件中调用自定义方法 -->
<div @click = "sendFun"></div>
</div>
</template>
<script lang="ts" setup>
// 在子组件中声明事件
const emit = defineEmits(['sonFun'])
// 点击事件触发,然后在事件中调用自定义方法
const sendFun = ()=>{
emit('sonFun','传递的参数')
}
</script>
3. v-model
// 父组件
<template>
<div>
<!-- 使用子组件,绑定自定义事件 -->
<son v-model="sonData" />
<!-- 而且可以自定义名字用来传递多个v-model -->
<son v-model:name="sonData" />
</div>
// v-model 相当于干了两件事 1. v-bind绑定 2. @input事件
</template>
<script lang="ts" setup>
import {ref} from "vue"
import son from "./son.vue" // 引入子组件
const sonData = ref('发送给组件的数据')
</script>
//子组件
<template>
<div>
<!-- 父给子传递的数据 -->
<div @click = "sendFun">{{modelValue}}</div>
</div>
</template>
<script lang="ts" setup>
// 在子组件中声明,如果不自定义名字的话则默认为modelValue
defineProps(['modelValue','name'])
// 声明自定义接收方式,相当于v-model同时进行了props传参和自定义事件双向绑定
const emit = defineEmits(['update:modelValue','update:name'])
// 点击事件触发,然后在事件中调用自定义方法
const sendFun = ()=>{
// 传递过去后,父组件的sonData 会改为下面传递的数据
emit('update:modelValue','传递的参数')
}
</script>
4. $attrs
用于当前组件的父组件给当前组件的子组件通信,祖孙通信
// 父组件
<template>
<son :data="data" :upData="upData"/>
</template>
<script lang = "ts" setup>
// 引入子组件
import son from './son'
const data = ref('数据')
// 可以通过传递函数实现孙给父通信
const upData = (value)=>{
}
</script>
// 子组件
<template>
<div>
<!-- 将数据直接传给孙组件 -->
<grandChild v-bind="$attrs"/>
</div>
</template>
<script lang = "ts" setup>
// 引入孙组件
import grandChild from './grandChild'
// 不需要对父组件传的props进行接收,因为在$attrs里存着直接给孙组件
</script>
// 孙组件
<template>
</template>
<script lang = "ts" setup>
// 孙组件对数据进行接收
defindProps(['data',"upData"])
</script>
5. parent、refs
parent子传父
// 父组件
<template>
<div>
<div @click="changeSon"></div>
<son ref="child"/>
<!-- $refs 可以拿到所有的子组件 -->
<div @click="changeSonTwo($refs)"></div>
</div>
</template>
<script lang = "ts" setup>
// 引入子组件
import son from './son'
const child = ref()
const data = ref('暴露给子组件的数据')
// 父组件暴露数据给子组件
defineExpose({data})
// 拿到dom后可以拿到子组件对外暴露的数据
function changeSon (){
console.log( child.value.data1,child.value.data2)
}
// 可以拿到所以子组件,前提是需要给子组件绑定ref值
function changeSonTwo(refs:object){
console.log(refs.child)
}
</script>
// 子组件
<template>
<div>
<grandChild v-bind="$attrs"/>
<!-- 修改父组件 -->
<div @click="changeFa($parent)"></div>
</div>
</template>
<script lang = "ts" setup>
cosnt data1 = ref('对外暴露的数据1')
const data2 = ref('对外暴露的数据2')
// 对外进行暴露
defineExpose({data1,datat2})
// 修改父组件,这个parent就是父组件
const changeFa = (parent)=>{
}
</script>
6. provide-inject
祖孙通信
// 父组件
<template>
<div>
<div @click="changeSon"></div>
<son ref="child"/>
</div>
</template>
<script lang = "ts" setup>
const money = ref(100)
// 引入子组件
import son from './son'
// 需要引入provide
import {provide} from "vue"
// 需要传入两个参数,1.数据名字,2. 数据值
provide('money',{money,update}) //money为ref数据,但是传的时候不需要.value
// 传给孙组件一个函数,用来实现孙给父组件传值
function update(value){
}
</script>
// 子组件
<template>
<div>
<child />
</div>
</template>
<script lang = "ts" setup>
// 引入孙组件
import child from './child'
</script>
// 孙组件
<template>
<div>
<!-- 调用函数给父组件传值 -->
<div @click="update('传值')"></div>
</div>
</template>
<script lang = "ts" setup>
// 需要引入inject进行接收
import {inject} from "vue"
// 参数 1. 数据对应名字 2. 默认值
let {money,update} = inject('money',{money:200,update:(x:number)=>{}})
</script>
7. mitt
任意组件通信 需要安装mitt
pnpm install mitt
// mitt.ts
import mitt from 'mitt' // 引入mitt
const emitter = mitt() // 调用mitt,emitter能绑定事件,触发事件
export default emitter // 暴露mitt
import emitter from './mitt'
// 绑定事件
emitter.on('fun1',(v)=>{
console.log('fun1被调用',v)
})
// 触发事件
emitter.emit('fun1','传递的参数')
// 解绑事件
emitter.off('fun1')
// 一次性解绑所有事件
emitter.all.clear()