组件通信
一、父传子-defineProps函数
目标:能够实现组件通讯中的父传子组件通讯
步骤:
1.父组件提供数据
2.父组件将数据传递给子组件
3.子组件通过 defineProps 进行接收
4.子组件渲染父组件传递的数据
Father.vue
<template>
<div>
<h1>我是父组件</h1>
<div>金钱:{{ money }}</div>
<div>车辆:{{ cay }}</div>
<hr>
<Son :money="money" :car="car"></Son>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Son from './Son.vue'
const money = ref(100)
const car = ref('玛莎拉蒂')
</script>
Son.vue
<template>
<div>
<h3>我是子组件</h3>
<div>{{ money }} --- {{ car }}</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
// defineProps: 接受父组件传递的数据
const props = defineProps({
money: Number,
car: String
})
// 使用props
console.log(props.money);
</script>
App.vue
<template>
<Father></Father>
</template>
<script setup>
import Father from './components/Father.vue'
</script>
注意:
如果使用 defineProps 接收数据,这个数据只能在模板中渲染
如果想要在 script 中也操作 props 属性,应该接收返回值
二、子传父-defineEmits函数
目标:能够实现组件通讯中的子传父组件通讯
步骤:
1.子组件通过 defineEmits获取 emit 函数(因为没有this)
2.子组件通过 emit 触发事件,并且传递数据
3.父组件提供方法
4.父组件通过自定义事件的方式给子组件注册事件
Fahter.vue
<template>
<div>
<h1>我是父组件</h1>
<div>金钱:{{ money }}</div>
<div>车辆:{{ cay }}</div>
<hr>
<Son :money="money" :car="car" @changeMoney="changeMoney"></Son>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Son from './Son.vue'
const money = ref(100)
const car = ref('玛莎拉蒂')
const changeMoney = (num) =>{
money.value = money.value - num
}
</script>
Son.vue
<template>
<div>
<h3>我是子组件</h3>
<div>{{ money }} --- {{ car }}</div>
<button @click="change">change</button>
</div>
</template>
<script setup>
import { computed } from 'vue'
// defineProps: 接受父组件传递的数据
const props = defineProps({
money: Number,
car: String
})
// 得到emit函数,显性声明事件名称
const emit = defineEmits(['changeMoney'])
const change = () =>{
emit('changeMoney',10)
}
</script>
总结:
defineEmits 获取 emit 函数,且组件需要触发的事件需要显性声明出来
三、跨级组件通讯provide与inject函数
通过provide和inject函数可以简便的实现跨级组件通讯
祖先组件:App.vue
<template>
<div>
app组件{{ count }} updateCount
<Father></Father>
</div>
</template>
<script setup>
import { provide, ref } from 'vue'
import Father from './components/Father.vue'
// 1. app组件数据传递给child
const count = ref(0)
provide('count',count)
// 2. app组件函数传递给child,调用的时候可以回传数据
const updateCount = (num) =>{
count.value += num
}
provide('updateCount', updateCount)
</script>
父组件:Father.vue
<template>
<div>
Father组件
<hr>
<Son></Son>
</div>
</template>
<script setup>
import Son from './Son.vue'
</script>
子组件:Son.vue
<template>
<div>
Son
</div>组件 {{ count }}
<button @click="updateCount(100)">修改count</button>
</template>
<script setup>
import { inject } from 'vue';
const count = inject('count')
const updateCount = inject('updateCount')
</script>
总结:
provide和inject是解决跨级组件通讯的方案
provide 提供后代组件需要依赖的数据或函数
inject 注入(获取)provide提供的数据或函数
官方术语:依赖注入
App是后代组件依赖的数据和函数的提供者,Child是注入(获取)了App提供的依赖