提供 Inject 在 vue 3 组合中无法正常工作 API

Provide Inject not working properly in vue 3 composition API

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

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

接收组件

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
    }

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

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

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

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

并且 setup() 中的子组件 console.log() 不会自动再次调用。您应该用 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)
    })
  }
}

demo