ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

vue-devui Anchor 锚点组件实战指南:指令式页面内跳转与滚动激活

vue-devui Anchor 锚点组件实战指南:指令式页面内跳转与滚动激活 前端UI组件设计系统【免费下载链接】vue-devui基于全新 DevUI Design 设计体系的 Vue3 组件库面向研发工具的开源前端解决方案。项目地址https://gitcode.com/DevCloudFE/vue-devui点击查看免费下载在长文档、帮助中心或研发工具等需要「页内快速导航」的场景中Anchor 锚点组件通过在页面上建立链接与目标区块的映射关系实现点击链接平滑滚动到指定位置并在滚动过程中自动高亮当前所在章节。本文基于 vue-devui 组件库的 Anchor 组件文档见 packages/devui-vue/docs/components/anchor/index.md完整讲解其三条指令v-d-anchor-box、v-d-anchor-link、v-d-anchor的用法、参数与激活事件并结合仓库源码剖析其滚动、高亮与 URL Hash 同步的实现原理帮助读者在项目里快速落地「目录导航 章节定位」功能。组件概览与何时使用Anchor 是「跳转到页面指定位置的组件」属于 vue-devui 导航类category: 导航组件。当页面内容较长、需要在各个部分之间实现快速跳转时即可使用典型场景包括文档页 / 帮助中心左侧的章节目录长表单分块填写时的步骤导航研发工具中的配置项快速定位与常规「一个组件 一个配置对象」的封装方式不同vue-devui 的 Anchor 以**指令directive**为主要交互载体由三个指令协作完成全部能力由 packages/devui-vue/devui/anchor/index.ts 统一注册install(app: App): void { app.directive(dAnchor.name, dAnchor); app.directive(dAnchorLink.name, dAnchorLink); app.directive(dAnchorBox.name, dAnchorBox); app.component(Anchor.name, Anchor); }即全局注册DAnchorBox、DAnchorLink、DAnchor三条指令同时导出同名Anchor组件当前Anchor组件本体为占位容器功能主要由指令承担组件实现见 anchor.tsx。三个指令各司其职指令职责v-d-anchor-box定义扫描锚点的滚动容器放在dAnchor与dAnchorLink的公共父节点上负责锚点和链接之间的通信v-d-anchor-link定义一个锚点链接点击后平滑滑动到对应锚点v-d-anchor定义一个锚点章节区块并参与滚动激活状态的判定基本用法在页面中使用时只需要一个容器节点内部用无序列表承载链接、用普通块级元素承载锚点区块。参考文档示例与 demo.tsx!-- classscrollTarget 加上这个类名是局部滚动,不加是全局滚动 -- div v-d-anchor-box classNamescrollTarget ul li v-d-anchor-linkanchorlink-oneanchorlink-one/li li v-d-anchor-linkanchorlink-twoanchorlink-two/li li v-d-anchor-linkanchorlink-threeanchorlink-three/li li v-d-anchor-linkanchorlink-fouranchorlink-four/li /ul div div v-d-anchoranchorlink-one anchorlink-one1 /div div v-d-anchoranchorlink-two anchorlink-two /div div v-d-anchoranchorlink-three anchorlink-three /div div v-d-anchoranchorlink-four anchorlink-four /div /div /div全局滚动与局部滚动示例代码中有一处关键注释容器上添加scrollTarget类名即为局部滚动不加则为全局滚动。全局滚动滚动事件绑定在window上锚点位置按document.documentElement.scrollTop || document.body.scrollTop计算适用于整页内容较长、目录固定于一侧的场景局部滚动滚动事件绑定在容器元素上按scrollTarget容器的scrollTop计算适用于页面内嵌一个独立滚动区域如面板内长列表的场景。从 d-anchor-box.ts 的源码可以看到容器对这两种模式的判定逻辑window.onscroll function () { windoScrollTop document.documentElement.scrollTop || document.body.scrollTop; if (!document.getElementsByClassName(scrollTarget).length) { // 全局滚动根据滚动位置切换 sidebar 的定位absolute/fixed } else { cssChange(mysidebar, absolute, div.scrollTop, 0); } }; // 容器自身的滚动事件 addEvent?.(div, scroll, function () { if (document.getElementsByClassName(scrollTarget).length) { cssChange(mysidebar, fixed, div.getBoundingClientRect().top, div.getBoundingClientRect().left); } });此外d-anchor-box挂载时会给容器生成一个随机 id复用shared/utils中的randomId工具见 random-id.ts并追加mycontainer、mymain类名作为后续侧边导航定位、滚动监听的作用域标识。Anchor定义一个锚点v-d-anchor用于在页面中定义一个锚点章节区块是滚动激活判定的目标单元。Anchor 参数参数类型默认说明dAnchorstring--必选设置一个锚点的名字anchorActivestring--可选锚点处于激活状态时模块生效对应的 CSS 类名源码中的挂载行为在 d-anchor.ts 中指令挂载mounted时会完成以下动作若父节点没有类名则补上mycontent右侧内容区样式在元素内部插入一个隐藏的a classbox-anchor href#锚点名作为锚点映射关系中的 Hash 载体供链接查询与匹配给元素设置section-block类名并写入name锚点名属性——点击链接时正是通过document.getElementsByName(binding.value)找到目标区块的绑定onclick点击锚点区块时通过hightLightFn高亮对应的链接。mounted(el: HTMLElement, binding: Bind): void { const parent: Element el.parentNode as Element; if (!parent.className) { parent.className mycontent; } el.innerHTML a classbox-anchor styledisplay:none href# binding.value ?/a el.innerHTML; el.className section-block; el.setAttribute(name, binding.value); el.onclick () { hightLightFn(binding.value); }; }对应的默认样式在 anchor.scss 中定义.section-block有min-height: 200px与底部虚线分隔保证每个章节区块有足够的可点击/可判定区域。Anchor 锚点激活事件锚点被激活时组件会自动在锚点元素上添加对应的 CSS 类用来区分「激活是由什么动作触发的」便于开发者针对不同触发来源定制样式CSS 类名代表意义anchor-active-by-anchor-link点击锚点链接激活anchor-active-by-scroll容器滚动到锚点位置激活anchor-active-by-click-inside点击锚点内部内容激活anchor-active-by-initial初始化滚动条位置激活这些类名配合section-block.active前缀使用。例如 anchor.scss 中内置的「点击链接后区块闪烁高亮」动画即利用了第一类激活.section-block.active.anchor-active-by-anchor-link { -webkit-animation: hightlight-and-disapear 3s linear 1; animation: hightlight-and-disapear 3s linear 1; }动画hightlight-and-disapear在 10%50% 时间点给区块绘制var(--devui-brand, #5e7ce0)的描边并逐渐淡出实现「定位到目标后短暂高亮提醒」的视觉反馈主题色通过 DevUI Design 变量接入主题系统。AnchorLink定义一个锚点链接v-d-anchor-link用于定义目录中的链接项点击后会平滑滑动到对应的锚点区块当滚动使锚点位于页面顶部附近时对应链接也会被激活并高亮。AnchorLink 参数参数类型默认说明dAnchorLinkstring--必选点击滑动的目标锚点的名字anchorActivestring--可选锚点处于激活状态时链接生效对应的 CSS 类名源码中的挂载与点击行为在 d-anchor-link.ts 中链接项挂载时会若父节点通常是ul没有类名则补上mysidebar step-nav使其具备侧边导航的样式与结构约定为链接项设置bar-link-item类名并追加隐藏的a classd-d-anchor href#锚点名用锚点名作为元素id便于滚动激活时通过document.getElementById定位高亮绑定onclick先根据页面是否存在scrollTarget决定滚动容器局部滚动取容器元素、全局滚动取window再调用scrollToControl执行平滑滚动。el.onclick () { let scrollContainer: IScrollContainer; const scollToDomY document.getElementsByName(binding.value)[0]; document.getElementsByClassName(scrollTarget).length ? scrollContainer (document.getElementsByClassName(scrollTarget)[0] as IScrollContainer) : scrollContainer window as IScrollContainer; scrollToControl(scollToDomY, scrollContainer); };scrollToControl与平滑滚动实现位于 utils.ts它计算目标区块相对容器的距离按固定步长timeoutIntervalSpeed 10通过多次setTimeout逐帧scrollBy形成平滑滚动效果滚动结束后再通过history.replaceState将当前锚点 Hash 同步到地址栏并触发对应链接高亮function scrollSmoothly(scrollPos: number, repeatTimes: number, container: HTMLElement): void { if (repeatCount repeatTimes) { scrollPos 0 ? container.scrollBy(0, timeoutIntervalSpeed) : container.scrollBy(0, -timeoutIntervalSpeed); } else { repeatCount 0; clearTimeout(cTimeout); history.replaceState(null, , document.location.pathname # hashName); hightLightFn(hashName); ... } repeatCount; cTimeout setTimeout(() { scrollSmoothly(scrollPos, repeatTimes, container); }, 10); }滚动过程中的链接自动高亮d-anchor-box挂载时会调用setActiveLink(timeId)建立「链接 ↔ 锚点」的映射关系见 d-anchor-box.ts通过.step-nav li.bar-link-item a收集当前容器作用域内的全部链接通过.box-anchor收集页面内全部锚点并按hash值把链接与锚点一一配对在滚动事件onScroll300ms 节流防抖触发时依据当前scrollTop与各锚点位置判断当前应处于哪个章节命中后history.replaceState更新地址栏 Hash、activateLink高亮对应链接并向上为父级目录项同步active类。const onScroll throttleAndDebounce(setActiveLink, 300);高亮切换统一由hightLightFn完成先清空侧边栏中所有带active的项再为当前命中的链接 id 添加active类见 utils.ts。默认激活态样式同样定义在 anchor.scss 中——li.active/li:hover时文字变为品牌色var(--devui-brand-active, #526ecc)并通过::before圆形节点和竖线连接线构建出「步骤式」目录的视觉层级。AnchorBox锚点通信容器v-d-anchor-box是锚点功能的前提——必须有一个容器否则功能无法使用。它必须放置在dAnchor与dAnchorLink的公共父节点上负责生成容器唯一 id并追加mycontainer/mymain类名作为内部作用域标识监听window滚动全局滚动或容器自身滚动局部滚动驱动链接高亮与 Hash 更新根据滚动位置切换侧边导航.mysidebar的定位方式页面滚动至容器范围内时使用fixed跟随超出范围后回退为absolute实现「目录吸顶/随动」效果对应源码 d-anchor-box.ts 中的cssChange与window.onscroll逻辑监听window.resize在窗口尺寸变化时重置侧边导航为absolute定位。同时侧边导航的默认宽度为240px见 anchor.scss 中.mysidebar与.step-nav的定义内容区.mycontent通过margin-left: 240px与目录形成左右分栏布局。实践要点与注意事项三个指令必须配套使用v-d-anchor-box是链路入口缺少它则滚动监听与链接匹配无法工作v-d-anchor-link负责触发v-d-anchor负责承载与命中判定指令值锚点名必须在链接与锚点间一一对应链接通过getElementsByName查找目标锚点锚点通过name属性与隐藏a的hash参与匹配名字不一致将导致滚动定位失败局部滚动记得添加scrollTarget类名该类名同时控制滚动容器选取、scrollTop计算方式与侧边导航定位策略不添加则默认走整页window滚动逻辑URL Hash 会被同步更新滚动命中锚点或点击链接后组件通过history.replaceState写入#锚点名不会产生历史记录便于在刷新/分享后仍能感知当前位置激活态类名是样式定制的扩展点可依据anchor-active-by-anchor-link、anchor-active-by-scroll等类名见上文表格为不同触发来源编写差异化样式当前实现说明从 d-anchor.ts 与 d-anchor-link.ts 的binding接口看目前源码仅消费value锚点名文档中列出的可选参数anchorActive尚未在指令挂载逻辑中体现使用前建议先在目标环境中验证或自行扩展且该组件在 index.ts 中标注状态为50%样式依赖主题变量anchor.scss大量使用--devui-brand、--devui-brand-active、--devui-text-weak、--devui-line等 DevUI Design 变量引入自devui/theme/styles-var/devui-var.scss使用前需确保项目已接入 devui-theme 主题体系以保证配色与整体设计语言一致。综上vue-devui 的 Anchor 组件以「容器 链接 锚点」三段式指令模型覆盖了从点击平滑滚动、滚动激活高亮到 URL Hash 同步的完整页内导航链路其源码结构清晰、样式挂件独立既可直接用于文档站与工具类页面的章节导航也为二次定制激活类名、侧边栏定位策略、滚动节流等保留了充足的扩展空间。赞分享前端UI组件设计系统【免费下载链接】vue-devui基于全新 DevUI Design 设计体系的 Vue3 组件库面向研发工具的开源前端解决方案。项目地址https://gitcode.com/DevCloudFE/vue-devui点击查看免费下载相关推荐Ant Design锚点组件Anchor与页面导航实现Ant Design锚点组件Anchor与页面导航实现 在现代Web应用开发中长页面内容的导航体验直接影响用户体验。当用户面对大量信息时如何快速定位到目标UI组件前端设计系统Ant Design Vue Anchor 组件完全指南单页滚动锚点导航的 API 详解与源码剖析Ant Design Vue Anchor 组件完全指南单页滚动锚点导航的 API 详解与源码剖析 Anchor 是 Ant Design Vue 中用于在单前端UI组件设计系统Ant Design Anchor 锚点组件完全指南API 配置、滚动高亮原理与实战示例Ant Design Anchor 锚点组件完全指南API 配置、滚动高亮原理与实战示例 Ant Design 的 Anchor锚点组件用于在单页内展示可前端UI组件设计系统上一篇gh_mirrors/as/assert在微服务架构中的应用确保服务间数据交换安全下一篇yuzu模拟器终极指南在电脑上畅玩Switch游戏的完整解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表