依赖注入

来源: 2024-05-26 11:35:18 播报

Provide (提供)

要为组件后代提供数据。

在 script setup 使用,使用到 provide() 函数。

示例:

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

provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
</script>

在 setup() 方法使用,provide() 是在 setup() 同步调用。

示例:

import { provide } from 'vue'

export default {
  setup() {
    provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
  }
}

provide() 函数的参数。

1、第一个参数被称为注入名,可以是一个字符串或是一个 Symbol。后代组件会用注入名来查找期望注入的值。一个组件可以多次调用 provide(),使用不同的注入名,注入不同的依赖值。

第二个参数是提供的值,值可以是任意类型,包括响应式的状态,比如一个 ref。

示例:

import { ref, provide } from 'vue'

const count = ref(0)
provide('key', count)

应用层 Provide

示例:

import { createApp } from 'vue'

const app = createApp({})

app.provide(/* 注入名 */ 'message', /* 值 */ 'hello!')

Inject (注入)

子孙组件要注入上层组件提供的数据。

1、在 script setup 使用 inject() 函数。

示例:

<script setup>
import { inject } from 'vue'

const message = inject('message')
</script>

2、在 setup() 方法使用,inject() 是在 setup() 同步调用。

示例:

import { inject } from 'vue'

export default {
  setup() {
    const message = inject('message')
    return { message }
  }
}

注入默认值

注入一个值时不要求必须有提供者,我们应该声明一个默认值。

示例:

// 如果没有祖先组件提供 "message"
// `value` 会是 "这是默认值"
const value = inject('message', '这是默认值')

和响应式数据配合使用

需要在注入方组件中更改数据,那么我们要在供给方组件内声明并提供一个更改数据的方法函数。

示例:

<!-- 在供给方组件内 -->
<script setup>
import { provide, ref } from 'vue'

const location = ref('North Pole')

function updateLocation() {
  location.value = 'South Pole'
}

provide('location', {
  location,
  updateLocation
})
</script>
<!-- 在注入方组件 -->
<script setup>
import { inject } from 'vue'

const { location, updateLocation } = inject('location')
</script>

<template>
  <button @click="updateLocation">{{ location }}</button>
</template>

如果我们想提供的数据不能被注入方的组件更改,我们可以使用 readonly() 来包装提供的值。

示例:

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

const count = ref(0)
provide('read-only-count', readonly(count))
</script>

使用 Symbol 作注入名

在构建大型的应用,包含非常多的依赖提供,为避免潜在的冲突,建议使用Symbol 来作为注入名。

通常推荐在一个单独的文件中导出这些注入名 Symbol。

示例:

// keys.js
export const myInjectionKey = Symbol()
// 在供给方组件中
import { provide } from 'vue'
import { myInjectionKey } from './keys.js'

provide(myInjectionKey, { /*
  要提供的数据
*/ });
// 注入方组件
import { inject } from 'vue'
import { myInjectionKey } from './keys.js'

const injected = inject(myInjectionKey)