通常,当我们需要从父组件向子组件传递数据时,我们使用 props。想象一下这样的结构:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 prop 沿着组件链逐级传递下去,可能会很麻烦
我们使用provide 、 inject可以在祖先组件中指定提供给后代的数据或方法
例如:创建三个组件 A.vue B.vue C.vue
A B C 互相引用
A.vue组件
- <template>
- <div class="a-div">
- <h1>我是AAA组件</h1>
- <h5 style="color: #fff;">{{ tname }}</h5>
- <B />
- </div>
- </template>
-
- <script setup lang="ts">
- import { provide } from "vue";
- import B from "./B.vue";
-
- let tname = '我是你爸爸'
- let name = provide('name', tname)
- </script>
-
- <style scoped>
- .a-div {
- width: 600px;
- height: 600px;
- background-color: red;
- }
- </style>
B.vue组件
- <template>
- <div class="b-div">
- <h1>我是BBBBB组件</h1>
- <h5 style="color: #fff;">{{ name }}</h5>
- <C />
- </div>
- </template>
-
- <script setup lang="ts">
- import { inject } from "vue";
- import C from "./C.vue";
- let name = inject('name')
- </script>
-
- <style scoped>
- .b-div {
- width: 500px;
- height: 500px;
- background-color: green;
- }
- </style>
C.vue组件
- <template>
- <div class="c-div">
- <h1>我是CCC组件</h1>
- <h5 style="color: #fff;">{{ name }}</h5>
- </div>
- </template>
-
- <script setup lang="ts">
- import C from "./C.vue";
- import { inject } from "vue";
- let name = inject('name')
- </script>
-
- <style scoped>
- .c-div {
- width: 400px;
- height: 400px;
- background-color: blue;
- }
- </style>
效果:
我们可以看到在A组件注入的数据 在其子代组件中都可以使用
如上因为是传递普通的值 是不具有响应式的,如何需要响应的需要通过ref reactive 添加响应式
A.vue
- <template>
- <div class="a-div">
- <h1>我是AAA组件</h1>
- <h5 style="color: #fff;">{{ tname }}</h5>
- <B />
- </div>
- </template>
-
- <script setup lang="ts">
- import { provide, ref } from "vue";
- import B from "./B.vue";
-
- let tname = ref('我是你爸爸')
- let name = provide('name', tname)
- </script>
-
- <style scoped>
- .a-div {
- width: 600px;
- height: 600px;
- background-color: red;
- }
- </style>
B.vue
- <template>
- <div class="b-div">
- <h1>我是BBBBB组件</h1>
- <h5 style="color: #fff;">{{ name }}</h5>
- <button @click="changeName">改变</button>
- <C />
- </div>
- </template>
-
- <script setup lang="ts">
- import { inject, Ref, ref } from "vue";
- import C from "./C.vue";
- let name = inject<Ref<string>>('name', ref('我是C默认值'))
-
- let changeName = () => {
- name.value = "改变name---BBBB"
- }
- </script>
-
- <style scoped>
- .b-div {
- width: 500px;
- height: 500px;
- background-color: green;
- }
- </style>
C.vue
- <template>
- <div class="c-div">
- <h1>我是CCC组件</h1>
- <h5 style="color: #fff;">{{ name }}</h5>
- <button @click="changeName">change name</button>
- </div>
- </template>
-
- <script setup lang="ts">
- import C from "./C.vue";
- import { inject, Ref, ref } from "vue";
-
- let name = inject<Ref<string>>('name', ref('我是C默认值'))
-
- let changeName = () => {
- name.value = "改变name---C"
- }
- </script>
-
- <style scoped>
- .c-div {
- width: 400px;
- height: 400px;
- background-color: blue;
- }
- </style>
默认效果:
点击修改
Provide (供给):父组件(祖先)供给,为组件后代供给数据
- <script setup lang="ts">
- import { provide, ref } from "vue";
-
- let tname = ref('参数')
- let name = provide('name', tname)
- </script>
Inject (注入):注入祖先组件供给的数据
- <script setup lang="ts">
- import { inject, Ref, ref } from "vue";
- let name = inject<Ref<string>>('name', ref('我是C默认值'))
- let changeName = () => {
- name.value = "改变name---BBBB"
- }
- </script>