在 Vue 中,provide
和 inject
主要用于父子组件之间的数据传递。provide
让父组件提供数据,inject
让子组件从父组件注入数据。
provide(key,value)
接收两个参数:第一个参数是要注入的 key,可以是一个字符串或者一个 symbol,第二个参数是要注入的值。
inject(key,defaultValue) 接收两个参数:第一个参数是注入的 key,第二个参数是可选的,即在没有匹配到 key 时使用的默认值。
下面演示如何使用:
父组件
<template>
<div class="provide-container" :style="{ height: height + 'px' }">
<h1>父组件</h1>
<n-button @click="handleClick">点击</n-button>
<h2>{{ data }}</h2>
<div>
<A></A>
<B></B>
</div>
</div>
</template>
<script lang="ts" setup>
import A from '@/components/provide/A.vue'
import B from '@/components/provide/B.vue'
import { provide, ref } from 'vue'
let height = ref()
height.value = window.innerHeight
let count = ref(0)
let data = ref(0)
const handleClick = () => {
count.value++
}
const handleChange = (val) => {
data.value += val
}
provide('ParentComponent', {
msg: '父组件',
count,
handleChange,
})
</script>
<style lang="scss" scoped>
.provide-container {
height: 100%;
background: #e6e6e6;
text-align: center;
}
</style>
A组件
<template>
<div class="A-container">
<h2 class="name">A组件</h2>
<h3>父组件传递的数据:{{ ParentComponent.count }}</h3>
<div>
<DeepA></DeepA>
</div>
</div>
</template>
<script lang="ts" setup>
import DeepA from '@/components/provide/deepA.vue'
import { provide, inject, ref } from 'vue'
const ParentComponent = inject('ParentComponent')
</script>
<style scoped lang="scss">
.A-container {
background: #54a29e;
height: 400px;
width: 400px;
}
</style>
B组件
<template>
<div class="B-container">
<h2 class="name">B组件</h2>
<div>
<h3>父组件传递的数据:{{ ParentComponent.count }}</h3>
</div>
</div>
</template>
<script lang="ts" setup>
import { provide, inject, ref } from 'vue'
const ParentComponent = inject('ParentComponent')
</script>
<style scoped lang="scss">
.B-container {
background: palegreen;
height: 400px;
width: 400px;
}
</style>
子孙组件
<template>
<div class="deepA-container">
<h3 class="name">deepA组件</h3>
<h4>父组件传递的数据:{{ ParentComponent.count }}</h4>
<n-button @click="handleClick()">点击父组件方法</n-button>
</div>
</template>
<script lang="ts" setup>
import { inject } from 'vue'
const ParentComponent = inject('ParentComponent')
const handleClick = () => {
ParentComponent.handleChange(4)
}
</script>
<style scoped lang="scss">
.deepA-container {
height: 200px;
width: 200px;
background-color: #f00;
}
</style>
效果
点击父组件的按钮 子组件和子孙组件的数据都发生了变化
点击子孙组件的按钮 父组件的按钮发生了变化
provide/indecj可以从父组件向子孙组件传递数据,也可以从子孙组件向父组件传递数据;但是无法直接实现兄弟组件之间的传参,要是向实现兄弟组件的传参需要父组件做中间组件来实现通讯,要是有兄弟组件之间传参的需求可以eventBus 可以参看我的上一篇文章——— 兄弟组件以及跨组件传参——eventBus-优快云博客