VueUse useArrayFindIndex:为 Vue 3 提供响应式的 Array.findIndex

📅 发布时间:2026/10/4 20:48:05
VueUse useArrayFindIndex:为 Vue 3 提供响应式的 Array.findIndex
前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载useArrayFindIndex是 VueUse当前仓库gh_mirrors/vu/vueuse在packages/shared包中提供的数组工具函数它把 JavaScript 原生的Array.prototype.findIndex变成了一个响应式计算属性当传入的数组元素可以是普通值、ref或 getter发生变化时返回的下标会自动重算。阅读本文后你将掌握它的两种典型用法、参数与返回值语义、底层源码实现原理以及与useArrayFind、useArrayFindLast的取舍从而在需要“找到第一个满足条件的元素下标”并跟随数据实时更新的场景中直接落地使用。定位响应式版本的Array.findIndex原生Array.findIndex(callback)返回数组中第一个满足测试函数的元素下标找不到时返回-1。问题在于它是一次性的数据变化后你必须手动重新调用。useArrayFindIndex则返回一个ComputedRefnumber底层由 Vue 的computed驱动任何依赖变化都会自动触发重算组件模板中可直接使用而无需手动同步。核心实现位于 index.ts完整类型签名如下export type UseArrayFindIndexReturn ComputedRefnumber export function useArrayFindIndexT( list: MaybeRefOrGetterMaybeRefOrGetterT[], fn: (element: T, index: number, array: MaybeRefOrGetterT[]) unknown, ): UseArrayFindIndexReturn两个要点list既可以是「元素本身是 ref/getter 的数组」也可以是「一个 ref 或 getter 返回数组」即响应式数组两种形态在下文分别演示返回值恒为ComputedRefnumber命中返回首个满足条件元素的下标未命中返回-1与原生的findIndex语义一致。用法一数组由多个 ref 组成文档 index.md 给出的第一种场景是数组元素本身就是独立的refimport { useArrayFindIndex } from vueuse/core const item1 ref(0) const item2 ref(2) const item3 ref(4) const item4 ref(6) const item5 ref(8) const list [item1, item2, item3, item4, item5] const result useArrayFindIndex(list, i i % 2 0) // result.value: 0 item1.value 1 // result.value: 1执行过程拆解初始list中 5 个元素全为偶数第一个偶数下标为 0所以result.value 0把item1.value改为 1 后数组变成[1, 2, 4, 6, 8]第一个偶数变成下标 1result.value自动更新为 1若所有元素都不满足条件则返回-1见测试佐证一节。需要注意这里的list是普通数组但内部元素是ref。useArrayFindIndex在每次重算时通过toValue逐个解包元素因此元素 ref 的变化依然能触发重新计算。用法二整个数组本身是响应式第二种场景是「整个数组用一个ref包裹」并对数组执行结构性修改import { useArrayFindIndex } from vueuse/core const list ref([0, 2, 4, 6, 8]) const result useArrayFindIndex(list, i i % 2 0) // result.value: 0 list.value.unshift(-1) // result.value: 1在ref([0, 2, 4, 6, 8])中list是一个深度响应式数组。useArrayFindIndex先toValue(list)取出数组本身再执行findIndex。由于数组是响应式的无论是元素被修改、还是unshift/push/splice等结构性操作都会触发依赖收集并自动重算初始数组中第一个偶数下标为 0unshift(-1)在头部插入 -1 后数组变为[-1, 0, 2, 4, 6, 8]第一个偶数移到下标 1结果随之更新。这使它在“轮播图当前索引定位”“表单步骤定位”“第一个满足校验条件的字段下标”等动态场景中非常顺手。源码原理computed toValue 的惰性响应完整实现只有一行核心逻辑位于 index.tsexport function useArrayFindIndexT( list: MaybeRefOrGetterMaybeRefOrGetterT[], fn: (element: T, index: number, array: MaybeRefOrGetterT[]) unknown, ): UseArrayFindIndexReturn { return computed(() toValue(list).findIndex((element, index, array) fn(toValue(element), index, array))) }几个值得展开的底层细节computed保证惰性与缓存函数返回的是ComputedRefnumber只在依赖变化时才重算模板或 watch 中读取result.value即可获得当前下标无需任何手动订阅。toValue双层的解包外层toValue(list)用于解包「整个数组」的 ref/getter内层toValue(element)用于解包「数组元素」的 ref/getter这与参数类型MaybeRefOrGetterMaybeRefOrGetterT[]一一对应。toValue是 Vue 3.3 提供的统一取值工具同时兼容 ref 与 getter。回调三参数原样透传fn收到(element, index, array)三个参数与原生findIndex一致。其中array是尚未解包元素的原始数组类型为MaybeRefOrGetterT[]element已被解包为真实值T方便直接编写判断逻辑如i i % 2 0。__NO_SIDE_EFFECTS__注解源码顶部为该函数标注了无副作用标记便于打包器做 tree-shaking 优化vueuse/shared包声明了sideEffects: false见 package.json进一步保障了按需引入时的体积。测试佐证行为与边界情况仓库为每个函数配备了 Vitest 单测index.test.ts 覆盖了两种用法并验证了边界行为数组元素逐个变为不满足条件依次把item1~item5改为奇数result.value从 0 依次前进到 4最后全部不满足时返回-1—— 印证“找不到返回 -1”的原生语义响应式数组的结构变化deepRef([0, 2, 4, 6, 8])配合unshift(-1)后下标从 0 变为 1 —— 印证数组结构性修改同样驱动重算。该测试覆盖了文档中两个示例的行为可作为你接入业务前理解预期结果的直接参考。与兄弟函数对比useArrayFind / useArrayFindLastuseArrayFindIndex属于 VueUse 的数组系列在 packages/shared/index.ts 中统一导出与以下两个函数形成互补函数返回值语义源码位置useArrayFindComputedRefT \| undefined返回第一个满足条件的元素本身找不到返回undefineduseArrayFind/index.tsuseArrayFindIndexComputedRefnumber返回第一个满足条件的下标找不到返回-1useArrayFindIndex/index.tsuseArrayFindLastComputedRefT \| undefined返回最后一个满足条件的元素自后向前查找useArrayFindLast/index.ts选择建议需要“元素值”用useArrayFind需要“下标”用useArrayFindIndex需要从尾部找用useArrayFindLast。值得一提的实现细节是useArrayFindLast内部为 Node 18 环境提供了手写的findLastpolyfill见 useArrayFindLast/index.ts而useArrayFindIndex依赖的原生findIndex在主流运行环境均已普及因此实现上无需额外兼容代码。获取与使用方式useArrayFindIndex归属vueuse/shared包但按 VueUse 的约定通过聚合包导入最方便import { useArrayFindIndex } from vueuse/core当前仓库中vueuse/shared版本为15.0.0peerDependencies要求vue: ^3.5.0见 package.json因此请确保项目基于 Vue 3.5 及以上版本。由于__NO_SIDE_EFFECTS__与sideEffects: false的双重保证按需导入时多余代码会被安全摇树。实战小结把原生findIndex升级为响应式的三步心法确定数据形态元素是独立 ref 就传普通数组整个数组响应式就直接传ref([...])函数两者皆可只写判断条件回调fn(element, index, array)只需关心真实元素值解包与依赖追踪由computed toValue完成消费返回值直接读取result.value或在模板中使用找不到时得到-1注意与useArrayFind的undefined区分。在需要“跟随数据自动更新的第一个匹配下标”的场景中useArrayFindIndex能省去大量手动watch同步代码是数组系列工具里简洁且可靠的一员。赞分享前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载相关推荐VueUse 中的 useInfiniteScroll为 Vue 3 打造响应式无限滚动加载VueUse 中的 useInfiniteScroll为 Vue 3 打造响应式无限滚动加载 本指南以 VueUse 仓库中 packages/core/us前端VueUse vueuse/math 之 logicNot为 ref 提供响应式 NOT 逻辑判断的完整实战指南VueUse vueuse/math 之 logicNot为 ref 提供响应式 NOT 逻辑判断的完整实战指南 logicNot 是 VueUse 数学扩前端VueUse useArrayFilter 指南在 Vue 3 中实现响应式的 Array.filterVueUse useArrayFilter 指南在 Vue 3 中实现响应式的 Array.filter useArrayFilter 是 VueUse 在前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考