尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

VueUse useTextSelection:基于 Vue 3 的响应式文本选区追踪组合式函数

VueUse useTextSelection:基于 Vue 3 的响应式文本选区追踪组合式函数 前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载导读useTextSelection是 VueUsevueuse/core中归属于Sensors传感器分类的一个组合式函数它基于浏览器原生的Window.getSelectionAPI将用户选中了哪些文本、选区覆盖哪些范围、选区对应的矩形区域这类信息封装为 Vue 响应式状态。读完本文你将掌握useTextSelection的完整 API、源码级实现原理以及如何用它快速构建选中文本高亮、复制引导、标注批注等交互功能。快速上手最小可用示例在 Vue 3 的script setup中直接调用即可无需任何初始化配置script setup langts import { useTextSelection } from vueuse/core const state useTextSelection() /script template p{{ state.text }}/p /template当用户在页面上框选任意文本时state.text会立刻变为被选中的字符串清除选区后state.text会自动恢复为空字符串。整个过程不需要手动监听事件也不需要手动调用清理逻辑。useTextSelection已从 packages/core/index.ts 统一导出因此既可以通过import { useTextSelection } from vueuse/core引入也可以直接从vueuse/core/useTextSelection子路径引入。vueuse/core要求vue为^3.5.0的 peer 依赖请确保项目基于 Vue 3 使用参见 packages/core/package.json。返回值四个响应式字段useTextSelection的返回类型定义在 packages/core/useTextSelection/index.ts 中共四个字段字段类型含义textComputedRefstring当前选中的纯文本内容无选区时为rectsComputedRefDOMRect[]选区中每个 Range 对应的视口矩形getBoundingClientRect()数组rangesComputedRefRange[]选区包含的 Range 对象数组selectionShallowRefSelection \| null底层的Selection单例对象本身text是最常用的字段直接对应selection.toString()ranges允许你进一步操作选区结构例如遍历Range做自定义标记rects基于ranges派生每个Range经range.getBoundingClientRect()得到其矩形位置可用于给被选中文字绘制高亮浮层或定位工具条selection是底层Selection单例的浅引用shallow ref适合需要直接调用SelectionAPI如anchorNode、focusNode、collapse()的场景。真实示例实时展示选中文本与选区矩形仓库自带的 packages/core/useTextSelection/demo.vue 演示了text与rects的组合用法script setup langts import { useTextSelection } from vueuse/core import { computed } from vue const { rects, text } useTextSelection() const selectedStyle computed(() text.value ? text-primary : text-gray-400) /script template div p classfont-600 text-blue-600 You can select any text on the page. /p p strongSelected Text:/strong em :classselectedStyle classwhitespace-pre h-44 overflow-y-auto block {{ text || No selected }}/em /p p strongSelected rects:/strong pre classh-72 langjson{{ rects }}/pre /p /div /template从 demo 中可以提炼两个实战要点无选区状态的 UI 兜底text || No selected在空字符串时展示占位文案避免界面出现空白rects直接可序列化DOMRect对象包含x、y、width、height、top、right、bottom、left等属性用pre langjson打印即可直观查看选区在页面中的精确位置这也是实现选中即弹出高亮/标注工具的数据基础。源码级原理事件驱动 派生计算整个实现非常精简核心逻辑全部位于 packages/core/useTextSelection/index.tsexport function useTextSelection(options: UseTextSelectionOptions {}): UseTextSelectionReturn { const { window defaultWindow, } options const selection shallowRefSelection | null(window?.getSelection() ?? null) const text computed(() selection.value?.toString() ?? ) const ranges computedRange[](() selection.value ? getRangesFromSelection(selection.value) : []) const rects computed(() ranges.value.map(range range.getBoundingClientRect())) function onSelectionChange() { selection.value null // trigger computed update if (window) selection.value window.getSelection() } if (window) useEventListener(window.document, selectionchange, onSelectionChange, { passive: true }) return { text, rects, ranges, selection, } }1. 初始化直接读取当前选区调用时通过window?.getSelection()获取浏览器当前存在的Selection单例存入shallowRef。因此即使组件挂载时用户已经选中了文本text也能立即拿到既有选区内容——这一点在测试should initialize with an existing range中得到了验证见 packages/core/useTextSelection/index.browser.test.ts。2. 事件驱动监听selectionchange浏览器没有为选区变化提供可订阅的流式 API因此组件通过useEventListener在window.document上注册selectionchange事件监听使用{ passive: true }以优化滚动场景下的性能。useEventListener负责在组件卸载时自动移除监听无需手动清理其注册/清理逻辑参见 packages/core/useEventListener/index.ts。监听回调onSelectionChange中有一段精妙的实现function onSelectionChange() { selection.value null // trigger computed update if (window) selection.value window.getSelection() }先置null再赋新值是因为Selection在浏览器中是单例对象——选区变化时对象引用本身不变只是内部状态变了。若直接重新赋值shallowRef会认为引用未变化而跳过触发导致text/rects不更新。显式先赋null再赋新值即可强制刷新派生 computed。测试selection should always return the singleton Selection object no matter how the selection changes正是对这一行为的约束无论选区如何变化selection.value始终指向同一个Selection单例见 index.browser.test.ts。3. 派生计算text / ranges / rectstextselection.value?.toString() ?? 直接取选区文本ranges通过getRangesFromSelection按selection.rangeCount逐项调用selection.getRangeAt(i)收集所有 Range见 index.tsrects对ranges逐一映射range.getBoundingClientRect()得到以视口为坐标系的矩形数组。三者均为computed仅当selection引用变化即选区事件发生时才重新求值派生成本极低。配置选项ConfigurableWindowuseTextSelection接受一个可选的options对象其类型UseTextSelectionOptions继承了 VueUse 通用的ConfigurableWindow接口export interface ConfigurableWindow { /** * Specify a custom window instance, e.g. working with iframes or in testing environments. */ window?: Window }该接口定义于 packages/core/_configurable.ts核心作用是在iframe 环境或测试环境中注入自定义window实例使选区追踪作用于目标文档而非全局窗口。未传入时默认值取自export const defaultWindow isClient ? window : undefined见 packages/core/_configurable.ts——在 SSR/非浏览器环境下为undefined此时useTextSelection内部会跳过getSelection()调用与事件注册返回的text为、ranges/rects为空数组保证服务端渲染不会报错。典型用法iframe 场景const { text, rects } useTextSelection({ window: iframe.contentWindow, })测试验证与行为契约packages/core/useTextSelection/index.browser.test.ts 通过 Vitest happy-dom 定义了该函数的四个核心行为契约可作为你理解与使用时的权威参考选区对象单例性无论选区怎么变化selection.value始终指向同一个Selection对象初始空选区页面无选区时text为rects、ranges均为空数组anchorNode/focusNode为null初始化时读取既有选区调用前已存在选区则text直接反映该选区内容ranges/rects长度均为 1selectionchange驱动的实时更新模拟选中Hello World节点并派发selectionchange事件后text变为Hello WorldremoveAllRanges()后再派发事件所有派生值恢复为空。测试中手动派发new Event(selectionchange)的方式也印证了该函数的更新完全依赖selectionchange事件这一事实——这也是在测试代码中触发其更新的标准手段。典型应用场景选中文本高亮标注用rects计算选中区域的精确位置叠加高亮浮层或批注工具条复制引导 / 词典释义实时监听text在用户选中词句时弹出复制翻译查词按钮选区统计与分享在阅读类应用中统计用户选中文本或生成可分享的引用片段富文本选区操作配合ranges对选区 Range 做包裹标签、插入标记等 DOM 操作。小结useTextSelection以约 20 行核心代码将浏览器底层的Selection单例模型与 Vue 响应式系统优雅地衔接起来shallowRef承载Selectionselectionchange事件驱动刷新computed派生text、ranges、rects三路只读状态。它无需任何配置即可开箱即用同时通过ConfigurableWindow保留了 iframe 与 SSR 场景的扩展能力是 Vue 3 中处理用户文本选择这一交互需求的轻量而完备的解决方案。赞分享前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载相关推荐airi 项目实战用 VueUse useTextSelection 在 Vue 3 中响应式追踪用户文本选区airi 项目实战用 VueUse useTextSelection 在 Vue 3 中响应式追踪用户文本选区 导读 useTextSelection 是 VAI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染AIRI 项目中的 usePreferredColorScheme响应式追踪 prefers-color-scheme 的 VueUse 组合式函数实战指南AIRI 项目中的 usePreferredColorScheme响应式追踪 prefers color scheme 的 VueUse 组合式函数实战指南AI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染VueUse vueuse/math useMin响应式 Math.min 组合式函数完全指南VueUse vueuse/math useMin响应式 Math.min 组合式函数完全指南 useMin 是 VueUse vueuse/math 扩前端上一篇comprehensive-rust 课程精讲用所有权与借用检查器实现 Single-Use Values一次性值下一篇Web-Dev-For-Beginners 实战作业解析用 JavaScript 条件逻辑实现学生成绩判定创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表