
前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载useSorted 是 VueUse 在vueuse/core中提供的数组工具函数之一它把排序这一常见操作封装成响应式能力传入一个数组或 ref / getter即可获得一个始终保持有序的响应式数组且默认不会改动源数组。本文围绕 packages/core/useSorted/index.md 展开结合 packages/core/useSorted/index.ts 源码与 packages/core/useSorted/index.browser.test.ts 测试用例讲透它的基本用法、dirty 模式、完整配置项以及底层实现原理读完即可在 Vue 3 项目中直接落地使用。useSorted 是什么useSorted的核心定位一句话可以概括reactive sort array响应式排序数组。它接收一个MaybeRefOrGetterT[]类型的源数组普通数组、ref数组或返回数组的函数均可返回一个RefT[]这个返回值的.value永远保持排序后的状态。它被注册在 VueUse 的 packages/core/index.tsexport * from ./useSorted中随vueuse/core一起分发可通过以下方式引入import { useSorted } from vueuse/core该函数在 packages/export-size.md 中记录的体积约为 332 B属于轻量级工具。快速上手纯排序不改动源数组默认情况下非 dirty 模式useSorted是一个纯函数式排序它只返回排序后的新数组源数组保持不变。这是文档给出的最基本示例import { useSorted } from vueuse/core const source [10, 3, 5, 7, 2, 1, 8, 6, 9, 4] const sorted useSorted(source) console.log(sorted.value) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] console.log(source) // [10, 3, 5, 7, 2, 1, 8, 6, 9, 4] —— 源数组未被修改可以看到sorted.value是升序排列的结果而source仍保持原始顺序。这一点在测试 index.browser.test.ts 中也被明确验证纯模式下sorted的结果与预期排序数组一致且arr的快照仍为原始乱序。如果传入的是ref数组或 getter 函数当源数据变化时返回值也会自动重算保持响应式更新import { ref } from vue import { useSorted } from vueuse/core const source ref([10, 3, 5, 7, 2, 1, 8, 6, 9, 4]) const sorted useSorted(source) source.value.push(0) // sorted.value 会自动变为 [0, 1, 2, ..., 10]对象数组排序自定义 compareFn对数字数组默认比较函数(a, b) a - b已经够用对对象数组则需要传入自定义比较函数。文档给出的例子是按age升序排列用户列表const objArr [{ name: John, age: 40, }, { name: Jane, age: 20, }, { name: Joe, age: 30, }, { name: Jenny, age: 22, }] const objSorted useSorted(objArr, (a, b) a.age - b.age) // objSorted.value 顺序为Jane(20) → Jenny(22) → Joe(30) → John(40)从 index.ts 的类型定义可以看出比较函数类型为export type UseSortedCompareFnT any (a: T, b: T) number即与Array.prototype.sort的比较函数约定完全一致返回负数表示a排在b前返回正数表示a排在b后返回 0 表示相等。因此所有你熟悉的自定义排序逻辑按多字段、按字符串、按时间戳等都可以直接复用// 多条件排序先按 age再按 name const sorted useSorted(objArr, (a, b) a.age - b.age || a.name.localeCompare(b.name))排序结果同样有测试背书index.browser.test.ts 验证了传入 compareFn 的对象排序结果index.browser.test.ts 还验证了通过 options 传入compareFn的等价写法。dirty 模式直接修改源数组默认纯模式适合保留原始数据、只消费排序结果的场景当你希望源数组本身就被排序时可以开启dirty选项。文档中的示例import { ref } from vue import { useSorted } from vueuse/core const source ref([10, 3, 5, 7, 2, 1, 8, 6, 9, 4]) const sorted useSorted(source, (a, b) a - b, { dirty: true, }) console.log(source) // 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] —— 源数组已被修改在 dirty 模式下useSorted返回的就是源数组本身source并在内部通过watchEffect监听源数据变化后立即就地排序。测试 index.browser.test.ts 证实dirty 排序后dirtyArr与sorted的结果完全一致。注意dirty 模式会破坏源数组的原始顺序如果源数组后续还要按插入序或原始序展示请谨慎使用。完整配置项optionsuseSorted支持两种调用形式useSorted(source, compareFn)或useSorted(source, options)也支持useSorted(source, compareFn, options)三参形式。其选项定义见 index.ts选项类型默认值说明compareFn(a: T, b: T) number(a, b) a - b排序比较函数约定与Array.sort相同sortFn(arr: T[], compareFn) T[]source.sort(compareFn)自定义排序算法可替换为其他排序实现如稳定排序、归并排序dirtybooleanfalse为true时直接修改源数组并返回源数组false时返回全新的排序副本关于 sortFn 的进阶用法sortFn是useSorted中一个容易被忽略但很有用的扩展点它接收原始数组或副本和比较函数返回排序后的数组。默认实现就是原生Array.prototype.sortindex.tsconst defaultSortFn: UseSortedFn T(source: T[], compareFn: UseSortedCompareFnT): T[] source.sort(compareFn)你可以在不改变useSorted外部接口的前提下替换排序策略例如使用稳定排序原生sort在 V8 中虽已稳定但某些环境未必或自定义算法const sorted useSorted(source, { sortFn: (arr, compareFn) myStableSort(arr, compareFn), })参数解析的两种写法等价从 index.ts 的参数解析逻辑可以看到以下两种写法是等价的// 写法一直接传比较函数 useSorted(objArr, (a, b) a.age - b.age) // 写法二通过 options 传入 compareFn useSorted(objArr, { compareFn: (a, b) a.age - b.age, })当传入两个参数且第二个参数是对象时它会被视为options并从options.compareFn读取比较函数缺省时回退到默认比较否则第二个参数被当作比较函数。测试用例对这两种形式都做了覆盖见 index.browser.test.ts。源码解读纯模式与 dirty 模式的两条实现路径useSorted的完整实现只有约 37 行index.ts逻辑非常清晰两条路径对应两种模式纯模式默认dirty falseif (!dirty) return computed(() sortFn([...toValue(source)], compareFn))关键点有两个先通过[...toValue(source)]展开数组副本再交给sortFn从而保证源数组永远不会被修改外层用computed包裹使结果具备响应式——只要sourceref 或 getter发生变化排序结果自动重算。dirty 模式dirty truewatchEffect(() { const result sortFn(toValue(source), compareFn) if (isRef(source)) source.value result else source.splice(0, source.length, ...result) }) return source关键点用watchEffect监听源数据一旦变化立即重新排序并写回如果源是ref直接把排序结果赋给source.value如果源是普通数组通过source.splice(0, source.length, ...result)原地替换元素注意禁止使用splice以外的破坏性写法的约束并不影响该内置实现它属于框架内部逻辑因此外部对源数组的引用仍然有效返回值就是源数组本身。此外source的类型是MaybeRefOrGetterT[]意味着它可以同时接受普通数组、ref和 getter 函数配合toValue统一解包这体现了 VueUse 对输入形态的一贯兼容设计。实战场景与演示参考VueUse 仓库中 packages/core/useSorted/demo.vue 提供了一个完整的交互示例展示了两种典型用法可作为落地参考场景一输入即排序的搜索/过滤面板demo 中把用户输入的逗号分隔文本实时拆分成数组再交给useSorted得到有序输出const arrText shallowRef() const inputArr computed(() arrText.value.split(,)) const inputOut useSorted(inputArr)配合模板中的input双向绑定用户每输入一次输出列表就自动重排无需手动调用sort也无需额外维护排序后的副本状态。场景二对象属性排序展示demo 中对用户对象数组直接按age排序并渲染到页面const objArr [{ name: John, age: 40 }, /* ... */] const result2 useSorted(objArr, (a, b) a.age - b.age)这类需求常见于排行榜、表格列排序、数据看板等场景。结合你的业务还可以把compareFn换成时间戳、评分、价格等任意业务字段。使用注意事项纯模式不修改源数组但也不应依赖返回数组与源数组的同一性纯模式每次重算都会生成新副本适合展示层消费如果多个组件要共享同一份排序结果可把useSorted放在共享组合式函数或createSharedComposable中。默认比较函数仅适用于数字(a, b) a - b对字符串、对象不适用处理非数字数组务必显式传入compareFn。dirty 模式有副作用它会就地改变源数组顺序务必确认业务上可以接受对普通数组入参时splice原地替换不会改变数组引用外部持有引用的代码依然可用。排序稳定性原生Array.prototype.sort在 ES2019 之后要求稳定排序现代引擎均满足若你需要跨环境保证稳定行为可通过sortFn注入稳定排序实现。性能useSorted每次源数据变化都会执行一次完整排序O(n log n)适合数据量适中的场景超大列表且频繁变更时可考虑自行维护有序结构或使用sortFn定制增量策略。小结useSorted用极小的 API 表面一个函数、三个可选配置解决了响应式数组排序这一高频需求默认纯函数式返回副本、不污染源数据dirty模式满足就地排序compareFn支持任意自定义排序规则sortFn甚至允许替换底层排序算法。配合 源码、测试 和 演示 三份仓库证据无论是快速上手还是深入定制你都能找到准确依据。赞分享前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载相关推荐VueUse vueuse/math useMin响应式 Math.min 组合式函数完全指南VueUse vueuse/math useMin响应式 Math.min 组合式函数完全指南 useMin 是 VueUse vueuse/math 扩前端airi 项目中的 VueUse useSorted在 Vue 3 中实现响应式数组排序airi 项目中的 VueUse useSorted在 Vue 3 中实现响应式数组排序 在 airi 这个自托管 AI 伴生桌面应用中渲染层stageAI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染VueUse useArrayMap 组合式函数深度解析在 Airi 中实现响应式数组映射VueUse useArrayMap 组合式函数深度解析在 Airi 中实现响应式数组映射 在 Vue 3 应用中 Array.prototype.mapAI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染上一篇Blender3mfFormat3D打印工作流中的技术实现与优化下一篇终极Stackoverflow Clone指南从零搭建全栈开发者问答平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考