You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pinia保存对象?城市天气数据无法追加至数组问题

Pinia城市天气状态数组存储问题解决

问题描述

需要将城市天气数据存入Pinia状态,期望city字段以数组形式存储多条数据(如city: [{}, {}, ...]),但实际状态中city是单个对象,且每次添加新城市时会完全覆盖原有数据,无法实现追加效果。

原代码

type WeatherStore = {
  weather: OneWeather[];
  city: CityWeather[];
  loading: boolean;
};

export const useWeatherStore = defineStore({
  id: "weather",
  state: () =>
    <WeatherStore>{
      weather: [],
      city: [],
      loading: false,
    },
  actions: {
    async fetchCurrentWeather() {
      this.loading = true;
      try {
        const { coords } = await Geolocation.getCurrentPosition();
        const response = await fetch(
          `${weatherUrl}&lat=${coords.latitude}&lon=${coords.longitude}&units=metric`
        );
        const cityRes = await fetch(
          `${cityUrl}&lat=${coords.latitude}&lon=${coords.longitude}&units=metric`
        );
        this.city = await cityRes.json();
        this.weather = await response.json();
      } catch (error) {
        console.log(error);
      } finally {
        this.loading = false;
      }
    },

    async fetchCityWeather(name: string) {
      this.loading = true;
      try {
        const response = await fetch(`${cityUrl}&q=${name}&units=metric`);
        const res = await response.json();
        this.city = res;
        // this.updateCity(res);
      } catch (error) {
        console.log(error);
      } finally {
        this.loading = false;
      }
    },
  },
});

Vue Devtool显示的状态

State
weather:Object
city:Object
loading:false

解决方案

问题核心是直接用this.city = res将数组类型的状态覆盖为了对象,需要改为追加数据到数组,同时兼容接口返回的单个对象或数组格式,可选添加去重逻辑。

修改后的代码:

type WeatherStore = {
  weather: OneWeather[];
  city: CityWeather[];
  loading: boolean;
};

export const useWeatherStore = defineStore({
  id: "weather",
  state: () =>
    <WeatherStore>{
      weather: [],
      city: [],
      loading: false,
    },
  actions: {
    async fetchCurrentWeather() {
      this.loading = true;
      try {
        const { coords } = await Geolocation.getCurrentPosition();
        const response = await fetch(
          `${weatherUrl}&lat=${coords.latitude}&lon=${coords.longitude}&units=metric`
        );
        const cityRes = await fetch(
          `${cityUrl}&lat=${coords.latitude}&lon=${coords.longitude}&units=metric`
        );
        const currentCityData = await cityRes.json();
        
        // 根据接口返回格式追加数据
        if (Array.isArray(currentCityData)) {
          this.city.push(...currentCityData);
        } else {
          this.city.push(currentCityData);
        }
        
        this.weather = await response.json();
      } catch (error) {
        console.log(error);
      } finally {
        this.loading = false;
      }
    },

    async fetchCityWeather(name: string) {
      this.loading = true;
      try {
        const response = await fetch(`${cityUrl}&q=${name}&units=metric`);
        const cityData = await response.json();
        
        // 可选:判断城市是否已存在,避免重复添加(假设CityWeather有name字段)
        const isCityExist = this.city.some(item => item.name === cityData.name);
        if (!isCityExist) {
          if (Array.isArray(cityData)) {
            this.city.push(...cityData);
          } else {
            this.city.push(cityData);
          }
        }
      } catch (error) {
        console.log(error);
      } finally {
        this.loading = false;
      }
    },
  },
});

修改要点

  1. 替换赋值为追加:用push方法将新数据添加到city数组中,而非直接覆盖整个数组
  2. 兼容接口返回格式:判断返回数据是数组还是单个对象,分别处理
  3. 可选去重:通过some方法检查数组中是否已有相同城市,避免重复存储

内容的提问来源于stack exchange,提问作者anpu God

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 13:24:27