Skip to content

依赖注入

通常情况下我们向子组件传递数据时使用props,如果多层级嵌套的组件数,深层次的子组件需要一个较远的祖先组件组件,使用props逐级传递下去会非常麻烦。

依赖注入就是可以在组件树的任一一个组件中提供一些需要传递的属性,在这个节点的任一子节点中都可以将这些属性注入使用。

Provider和Injector是依赖注入的核心。

Provider

Provider为后代提供数据,这些数据可以在组件树的任一子节点中注入使用。

vue
<script setup>
import { provide } from 'vue';

provide(/* 注入名 */ 'key', /* 注入值 */ 'value');
</script>

如果使用 setup() ,确保在 setup() 函数中调用 provide() 函数。

vue
<script>
import { provide } from 'vue';

export default {
  setup() {
    provide(/* 注入名 */ 'key', /* 注入值 */ 'value');
  },
};
</script>

Injector

Injector从Provider提供的数据中获取需要的数据。

vue
<script setup>
import { inject } from 'vue';
const value = inject(/* 注入名 */ 'key');
</script>

如果使用 setup() ,确保在 setup() 函数中调用 inject() 函数。

vue
<script>
import { inject } from 'vue';
export default {
  setup() {
    const value = inject(/* 注入名 */ 'key');
    return { value };
  },
};
</script>

和响应式数据配合使用

可以配合响应式数据使用,当响应式数据变化时,Provider提供的数据也会随之变化。

vue
<script setup>
import { provide, ref } from 'vue';

const count = ref(0);
provide('key', count);
</script>
vue
<script setup>
import { inject, ref } from 'vue';

const count = inject('key');
const double = ref(0);

watchEffect(() => {
  double.value = count.value * 2;
});
</script>

提供 / 注入响应式数据时,子组件中如果需要更改注入数据,建议在提供数据的组件中进行更改。这样可以确保数据的一致性,更容易维护。

供给方可以提供更改数据的方法,以允许子组件更新数据。

vue
<script setup>
import { provide, ref } from 'vue';

const count = ref(0);
const increment = () => {
  count.value++;
};
provide('count', { count, increment });
</script>
vue
<script setup>
import { inject } from 'vue';

const { count, increment } = inject('count');
</script>
<template>
  <button @click="increment">{{ count }}</button>
</template>

如果想确保提供的数据不能被注入放更改,可以使用 readonly() 来包装提供的值。

vue
<script setup>
import { provide, readonly, ref } from 'vue';

const count = ref(0);
provide('key', readonly(count));
</script>

Released Under The MIT License.