首页 > 解决方案 > 提供 Inject 在 vue 3 组合 API 中无法正常工作

问题描述

我正在使用 Vue 3 组合 api 并通过检索天气数据async/await fetch,我得到 200 响应和 Chrome 开发工具中请求中的数据。

在接收数据并进行调用的组件中,我有一个provide方法,然后我inject将数据输入到另一个输出组件中。问题出在inject组件中。ed 变量的值inject始终为 null,并且不会在 Vue 开发工具中更新,因此我的数据永远不会输出到屏幕上。我浏览了文档,代码几乎相同,但我无法让它工作。任何人都可以看到一个明显的问题吗?

接收组件

setup () {
    async function getCurrentWeather () {
      const response = await fetch(`${baseWeatherApiUrl}q=${userInput.value}`);

      userInput.value = null;

      return weatherData.value = await response.json();
    }

    const returnedWeatherData = reactive(weatherData);

    provide('returnedWeatherData', returnedWeatherData);

    return {
      getCurrentWeather,
      userInput,
      weatherData
    }
  }

输出组件

setup () {
    //Provide default of empty object in case no results exist
    const weatherData = inject('returnedWeatherData');

    console.log(weatherData) //No output even when making a new request to the weather api
    
    return {
      weatherData
    }
  }

作为一个单独的测试,我尝试对provide/inject文档中的值进行硬编码,但geolocation在注入时仍然为空。

provide('geolocation', {
      longitude: 90,
      latitude: 135
    })
const userGeolocation = inject('geolocation')


    console.log(userGeolocation) // Nothing logged

    return {
      weatherData,
      userGeolocation
    }

标签: vue.jsvuejs3vue-composition-api

解决方案


provide-ed 参数应该是它本身ref(不包含在 a 中reactive()):

// Parent.vue
export default {
  setup () {
    const weatherData = ref()

    // ❌
    // const returnedWeatherData = reactive(weatherData);
    // provide('returnedWeatherData', returnedWeatherData);

    // ✅
    provide('returnedWeatherData', weatherData);
  }
}

并且子组件的console.log()insetup()不会自动再次被调用。您应该将该调用包装起来,watchEffect()以便在更改为时调用它ref

// Child.vue
import { inject, watchEffect } from 'vue'

export default {
  setup () {
    const weatherData = inject('returnedWeatherData')

    // ❌
    //console.log('new weatherData', weatherData.value)

    // ✅
    watchEffect(() => {
      console.log('new weatherData', weatherData.value)
    })
  }
}

演示


推荐阅读