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

Vue3+TS组合式函数返回数组调用filter报错,求助排查

问题原因及解决方法

1. 初始化错误:favorites 被初始化为对象而非数组

在组合式函数中,你将 favorites 初始化为 ref({})(空对象),但它的实际用途是存储艺术家数组。尽管后续 loadFavorites 会将其赋值为数组,但在初始化阶段或数据加载完成前,尝试对对象调用 filter 方法必然会报错。

修复: 将初始值改为空数组:

const favorites = ref([]);

2. 错误访问 Ref 内部值

在组件中,你通过 favorites._rawValue 访问数组,这是直接操作 Vue 的内部属性,不符合规范。正确的做法是通过 .value 访问 Ref 的值(在 <script setup> 中,模板会自动解包,但在脚本中必须手动使用 .value)。

修复: 修改 isFavorite 函数:

function isFavorite(artist) {
  return favorites.value.filter((favorite) => {
    return favorite.id === artist.id;
  }).length > 0;
}

3. 监听逻辑错误

你当前的监听目标是 favorites.value,这意味着你监听的是初始的空对象。当后续将数组赋值给 favorites.value 时,监听绑定的是旧对象的引用,不会触发缓存逻辑。此外,如果通过 push 修改数组(如 addFavorite 中的操作),由于数组引用未变,浅监听也无法触发。

修复: 直接监听 Ref 实例,并开启深度监听:

watch(favorites, cacheFavorites, { deep: true });

完整修正代码

组合式函数(composable)

import { onMounted, ref, watch } from 'vue';
import { Preferences } from "@capacitor/preferences";
import { useStore } from "@/store";

export const userFavorites = () => {
  const FAVORITE_ARTISTS = 'favorites';
  // 修正:初始化为空数组
  const favorites = ref([]);
  const store = useStore();

  function addFavorite(artist, saved) {
    let payload = {
      artists: [artist],
      isFavorite: saved
    };

    store.dispatch({
      type: 'updateUserFavorites',
      payload
    });

    favorites.value.push(artist);
  }

  const loadFavorites = async () => {
    const favoriteList = await Preferences.get({ key: FAVORITE_ARTISTS });
    const favoriteResults = favoriteList.value ? JSON.parse(favoriteList.value) : [];
    favorites.value = favoriteResults;
  };

  const cacheFavorites = () => {
    Preferences.set({
      key: FAVORITE_ARTISTS,
      value: JSON.stringify(favorites.value),
    });
  };

  onMounted(loadFavorites);
  // 修正:监听 Ref 并开启深度监听
  watch(favorites, cacheFavorites, { deep: true });

  return {
    favorites,
    addFavorite
  };
};

Vue 组件(myfile.vue)

<script lang="ts" setup>
import { computed, ref } from "vue";
import RegisterToolbar from "@/components/RegisterToolbar.vue";
import { useRoute, useRouter } from "vue-router";
import { useStore } from "@/store";
import { bookmarkOutline, bookmark } from 'ionicons/icons';
import { userFavorites } from '@/composables/userFavorites';
const { addFavorite, favorites } = userFavorites();

import {
  IonButton,
  IonBackButton,
  IonButtons,
  IonPage,
  IonIcon,
  IonContent,
  IonLabel,
  IonAvatar,
  IonCard,
  IonGrid,
  IonRow,
  IonCol,
  IonList,
  IonItem,
  IonCardHeader,
  IonChip,
  IonCardContent,
  IonSearchbar,
} from "@ionic/vue";

const store = useStore();
const router = useRouter();

const artists = computed(() => store.getters.getArtists);
const user = computed(() => store.getters.getUser);    
const route = useRoute();

// 修正:通过 .value 访问 Ref 值
function isFavorite(artist) {
  return favorites.value.filter((favorite) => {
    return favorite.id === artist.id;
  }).length > 0;
}

const navigate = (url: string) => {
  router.push(url);
}
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:04:56