news 2026/9/10 2:24:18

airi 项目中的 VueUse `useArrayFind`:让 `Array.find` 具备响应式的实践指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
airi 项目中的 VueUse `useArrayFind`:让 `Array.find` 具备响应式的实践指南

airi 项目中的 VueUseuseArrayFind:让Array.find具备响应式的实践指南

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

useArrayFind是 VueUse 提供的响应式Array.find,它把原生数组查找逻辑包装成 Vue 计算属性:当数组或查找条件发生变化时,返回值会自动更新。本文以 airi 仓库内置的 useArrayFind 参考文档 为骨架,结合仓库中 Vue 3 应用(stage-web、stage-tamagotchi 等)对 VueUse 的实际使用方式,讲解它的用法、类型签名、响应式原理,以及它与useArrayFindIndexuseArrayFindLast等数组家族函数的搭配场景,帮助你写出更简洁、可维护的 Vue 业务代码。

useArrayFind 是什么

在 Vue 组件中,我们经常需要根据状态从列表中"找出第一个符合条件的元素",例如根据用户选择找到对应的配置项、根据 ID 找到当前播放的音频等。传统的做法是在computed里手写:

import { computed } from 'vue' const list = ref([1, -1, 2]) const positive = computed(() => list.value.find(val => val > 0))

useArrayFind将这个模式固化成一个官方 composable,语义即 "ReactiveArray.find",调用方式与原生find几乎一致,却自动获得了响应式追踪能力。在 airi 仓库中,@vueuse/core通过 pnpm catalog 统一管理版本(见 pnpm-workspace.yaml,当前为^14.4.0),SKILL.md 中的 Array 分类表将其Invocation标记为AUTO,意味着在 Vue/Nuxt 开发中遇到"从数组中查找元素"的需求时,应当优先选用它而不是手写computed

基本用法

对 ref 数组执行查找

useArrayFind接受两个参数:第一个是源数组,第二个是测试函数(predicate),返回值是一个ComputedRef,读取时需要访问.value

import { useArrayFind } from '@vueuse/core' import { ref } from 'vue' const list = [ref(1), ref(-1), ref(2)] const positive = useArrayFind(list, val => val > 0) // positive.value: 1

注意上面示例中list的每个元素本身也是 ref,useArrayFind的类型签名明确支持这种MaybeRefOrGetter<T>[]的嵌套形式——数组的元素可以是原始值、ref 或 getter,函数内部会统一解包后再执行测试。

与 reactive 数组联动

useArrayFind的真正价值在于与响应式数据结构联动:当数组内容发生变化(如pushsplice)时,计算结果会自动重算,无需手动触发:

import { useArrayFind } from '@vueuse/core' import { reactive } from 'vue' const list = reactive([-1, -2]) const positive = useArrayFind(list, val => val > 0) // positive.value: undefined(当前没有正数) list.push(1) // positive.value: 1(数组变化后自动更新)

这段代码展示了一个关键特性:当找不到任何满足条件的元素时,返回值是undefined(与原生Array.find一致);一旦数组被push进符合条件的元素,positive.value立即更新为1

类型签名与参数语义

原文档给出了完整的 TypeScript 声明,理解它能避免误用:

export type UseArrayFindReturn<T = any> = ComputedRef<T | undefined> export declare function useArrayFind<T>( list: MaybeRefOrGetter<MaybeRefOrGetter<T>[]>, fn: (element: T, index: number, array: MaybeRefOrGetter<T>[]) => boolean, ): UseArrayFindReturn<T>

逐项解读:

  • list: MaybeRefOrGetter<MaybeRefOrGetter<T>[]>:第一参数可以是一个 ref、getter 或普通数组;数组元素同样可以是 ref 或 getter。这解释了为何[ref(1), ref(-1), ref(2)]这种"ref 元素数组"可以直接传入。
  • fn: (element, index, array) => boolean:测试函数签名与原生Array.find一致,接收当前元素、下标和整个数组(此处元素已被解包为T),返回布尔值决定是否命中。
  • 返回值ComputedRef<T | undefined>:结果是一个计算属性,读取用.value;未命中时为undefined,文档注释明确:"the first element in the array that satisfies the provided testing function. Otherwise, undefined is returned."
  • @__NO_SIDE_EFFECTS__:标注该函数无副作用,便于打包器做 tree-shaking 与死代码消除。

由于返回ComputedRef,你可以在模板中直接使用,也可以在另一个computed中依赖它形成链式推导,例如"先找到当前选中的配置,再读取它的某个字段"。

与原生 find 的对比及适用边界

对比维度原生Array.finduseArrayFind
数据源普通数组,一次性查询ref / reactive / getter 数组,自动响应式
结果形态普通值ComputedRef.value访问)
结果更新需手动重新调用数据或条件变化时自动重算
未命中结果undefinedundefined
典型场景一次性处理静态数据列表来自状态、随用户操作增删改的动态数据

需要说明的边界:useArrayFind依赖 Vue 的响应式追踪,因此源数组必须是响应式的(ref、reactive 包裹,或数组元素为 ref/getter),或者依赖查找条件的变化来触发重算;对完全静态的数据,直接用原生find即可,不必引入额外开销。

在 airi 仓库中的应用场景

airi 仓库的多个 Vue 应用均通过 catalog 依赖@vueuse/core,包括 stage-web、stage-tamagotchi、stage-pocket、ui-server-auth 等。在这些应用的源码中存在大量"从响应式列表里按条件取首元素"的写法,它们都是useArrayFind的典型应用场景。例如:

  • CharacterItem.vue 中多次出现props.character.i18n.find(...)props.character.capabilities.find(c => c.type === 'llm')这类查找;
  • mcp.vue 中通过servers.value.find(...)servers.value.findIndex(...)按名称或 rowId 定位 MCP 服务器配置项。

按照 SKILL.md 的指导原则——"先检查 VueUse 函数能否满足需求,优先使用 composable 而非手写代码"——当这些查找的数据源本身就是响应式状态时,改用useArrayFind可以直接把"手写 computed + find"缩减为一行声明式调用,让依赖关系由框架自动维护。

数组家族:从 find 到整个响应式数组工具链

useArrayFind属于 VueUse 的 Array 分类,SKILL.md 中列出了一整套"响应式数组方法",彼此可以自由组合:

  • useArrayFindIndex:响应式Array.findIndex,返回第一个命中的下标而非元素;
  • useArrayFindLast:响应式Array.findLast,从数组末尾向前查找;
  • useArrayFilter:响应式Array.filter,返回所有命中的元素数组;
  • useArrayEveryuseArraySome:响应式every/some,用于断言;
  • useArrayIncludesuseArrayUniqueuseSorted等:覆盖成员判断、去重、排序等常见需求。

这些函数共用同一套入参约定(MaybeRefOrGetter<MaybeRefOrGetter<T>[]>)与ComputedRef返回约定,因此学会useArrayFind后可以零成本迁移到其他数组操作。选择建议:只需第一个命中元素用useArrayFind;需要下标用useArrayFindIndex;需要全部命中用useArrayFilter;需要从尾部找用useArrayFindLast

小结

useArrayFind以极小的心智成本把原生find变成响应式声明:list支持 ref/reactive/getter 三种形态,测试函数签名与原生一致,返回值统一为ComputedRef<T | undefined>。在 airi 这类大量依赖 Vue 3 响应式状态的项目中,它适合用来替代"手写 computed + find"的样板代码,让"根据状态查找首个元素"的逻辑由框架自动保持同步。想深入了解完整类型与用法,可随时查阅仓库内置的 useArrayFind.md,并对照 SKILL.md 中的 Array 分类表选择合适的数组 composable。

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 2:24:13

电商智能分仓与需求预测实战:从数据集到闭环落地

简介&#xff1a;本资源是一份面向物流算法工程师、运筹优化与机器学习从业者及高校相关专业研究生的实战型数据集与建模方案包&#xff0c;聚焦电商场景下“单未下、货先行”的前置分仓策略&#xff0c;解决区域需求精准预测、RDC/FDC库存调拨协同与全局成本优化等核心问题。资…

作者头像 李华
网站建设 2026/9/10 2:22:20

Python面试三大件:迭代器、生成器与装饰器原理与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 2:21:57

移动储能灾后动态调度的MATLAB建模与闭环验证

简介&#xff1a;本资源面向电力系统自动化、智能配电网及能源优化方向的研究生、科研人员与工程技术人员&#xff0c;聚焦灾害场景下配电网韧性提升这一关键问题&#xff0c;提供灾后动态调度的完整建模与实现方案。资源包含9个文件&#xff0c;以5个核心MATLAB脚本&#xff0…

作者头像 李华