提供/注入

    我们也可以在 Composition API 中使用 。两者都只能在当前活动实例的 期间调用。

    假设我们要重写以下代码,其中包含一个 MyMap 组件,该组件使用 Composition API 为 MyMarker 组件提供用户的位置。

    1. <!-- src/components/MyMarker.vue -->
    2. <script>
    3. export default {
    4. inject: ['location', 'geolocation']
    5. }
    6. </script>

    setup() 中使用 provide 时,我们首先从 vue 显式导入 provide 方法。这使我们能够调用 provide 时来定义每个 property。

    provide 函数允许你通过两个参数定义 property:

    1. property 的 name (<String> 类型)
    2. property 的 value
    1. <!-- src/components/MyMap.vue -->
    2. <template>
    3. <MyMarker />
    4. </template>
    5. <script>
    6. import { provide } from 'vue'
    7. import MyMarker from './MyMarker.vue
    8. export default {
    9. components: {
    10. MyMarker
    11. },
    12. setup() {
    13. provide('location', 'North Pole')
    14. provide('geolocation', {
    15. longitude: 90,
    16. latitude: 135
    17. })
    18. }
    19. }
    20. </script>

    setup() 中使用 inject 时,还需要从 vue 显式导入它。一旦我们这样做了,我们就可以调用它来定义如何将它暴露给我们的组件。

    inject 函数有两个参数:

    1. 要注入的 property 的名称
    2. 一个默认的值 (可选)

    使用 MyMarker 组件,可以使用以下代码对其进行重构:

    为了增加提供值和注入值之间的响应性,我们可以在提供值时使用 或 reactive

    1. <!-- src/components/MyMap.vue -->
    2. <template>
    3. <MyMarker />
    4. </template>
    5. <script>
    6. import { provide, reactive, ref } from 'vue'
    7. components: {
    8. MyMarker
    9. },
    10. setup() {
    11. const location = ref('North Pole')
    12. const geolocation = reactive({
    13. longitude: 90,
    14. latitude: 135
    15. })
    16. provide('location', location)
    17. provide('geolocation', geolocation)
    18. }
    19. }
    20. </script>

    现在,如果这两个 property 中有任何更改,MyMarker 组件也将自动更新!

    修改响应式 property

    当使用响应式提供/注入值时,建议尽可能,在提供者内保持响应式 property 的任何更改

    例如,在需要更改用户位置的情况下,我们最好在 MyMap 组件中执行此操作。

    1. <!-- src/components/MyMap.vue -->
    2. <template>
    3. <MyMarker />
    4. </template>
    5. <script>
    6. import { provide, reactive, ref } from 'vue'
    7. import MyMarker from './MyMarker.vue
    8. export default {
    9. components: {
    10. MyMarker
    11. },
    12. setup() {
    13. const location = ref('North Pole')
    14. const geolocation = reactive({
    15. longitude: 90,
    16. latitude: 135
    17. })
    18. provide('location', location)
    19. provide('geolocation', geolocation)
    20. return {
    21. location
    22. }
    23. },
    24. methods: {
    25. updateLocation() {
    26. this.location = 'South Pole'
    27. }
    28. }
    29. </script>

    然而,有时我们需要在注入数据的组件内部更新注入的数据。在这种情况下,我们建议提供一个方法来负责改变响应式 property。

    1. <!-- src/components/MyMarker.vue -->
    2. <script>
    3. import { inject } from 'vue'
    4. export default {
    5. setup() {
    6. const userLocation = inject('location', 'The Universe')
    7. const userGeolocation = inject('geolocation')
    8. const updateUserLocation = inject('updateLocation')
    9. return {
    10. userLocation,
    11. userGeolocation,
    12. updateUserLocation
    13. }
    14. }
    15. }
    16. </script>
    1. <!-- src/components/MyMap.vue -->
    2. <template>
    3. <MyMarker />
    4. </template>
    5. <script>
    6. import { provide, reactive, readonly, ref } from 'vue'
    7. import MyMarker from './MyMarker.vue
    8. export default {
    9. components: {
    10. MyMarker
    11. },
    12. setup() {
    13. const location = ref('North Pole')
    14. const geolocation = reactive({
    15. longitude: 90,
    16. latitude: 135
    17. })
    18. const updateLocation = () => {
    19. location.value = 'South Pole'
    20. }
    21. provide('location', readonly(location))
    22. provide('geolocation', readonly(geolocation))
    23. provide('updateLocation', updateLocation)
    24. }
    25. </script>