🔗 @lionad/leader-line:在网页元素之间绘制引导线
在需要表达元素之间关系的界面里,引导线(Leader Line)是一种便宜又直观的可视化手段。流程图、表单联动、节点编辑器、看板依赖……只要两个 DOM 元素需要被“连起来”,就会用到它。
最近把 anseki/leader-line fork 成了一个现代维护版 @lionad/leader-line,顺手补上了类型、ESM/CJS/IIFE 三产物,以及一个可以批量合并重排的渲染调度器。这篇文章简单介绍它解决了什么问题、怎么用、以及在 Vue / Nuxt 中的集成方式。
基础用法
安装:
pnpm add @lionad/leader-line
ESM 或 CommonJS 都能直接导入,也支持 <script> 标签直载:
import LeaderLine from '@lionad/leader-line'
const line = new LeaderLine(
document.getElementById('start'),
document.getElementById('end'),
{ color: 'coral', endPlug: 'arrow2' }
)
API 与上游基本兼容,所以旧项目迁移时通常只改包名即可。
Vue / Nuxt 集成
命令式 API 直接塞进 Vue 的响应式系统会比较啰嗦,所以另外提供了两个平行子包:
@lionad/leader-line-vue:composable + 组件@lionad/leader-line-nuxt:Nuxt 4 模块(包含 vue 包)
单线响应式
<script setup>
import { ref, useTemplateRef } from 'vue'
import { useLeaderLine } from '@lionad/leader-line-vue'
const a = useTemplateRef('a')
const b = useTemplateRef('b')
const color = ref('coral')
const { line, position, show, hide, remove } = useLeaderLine(a, b, {
color,
endPlug: 'arrow2'
})
</script>
color 是 ref 时,修改 color.value 会自动调用 setOptions,不会重建整条线。组件卸载时也会自动 remove,不用手动清理。
批量连线
import { useLeaderLines } from '@lionad/leader-line-vue'
const edges = ref([
{ key: 'a→b', start: elA, end: elB, color: 'coral', data: { fieldId: 'x' } }
])
const { lines, getLine, findWhere, removeWhere } = useLeaderLines(edges, {
preventSame: true
})
edges 的 push / splice / 同 key 属性修改 / 重排都会按最小代价更新,避免频繁重建 SVG。
Nuxt 零配置模块
export default defineNuxtConfig({
modules: ['@lionad/leader-line-nuxt'],
leaderLine: {
defaults: { color: '#4a9eff', size: 2 }
}
})
之后所有 composable 和 <LeaderLine> 组件都免 import 直接使用,且 SSR 安全(client-only)。
渲染调度
上游的 position() 是同步的。如果一帧内更新 N 条线,每条线都先读布局再写 DOM,会触发 N 次强制同步 reflow。在拖拽或窗口 resize 这种高频场景里,代价很明显。
这个版本把一帧内的 position() 更新合并为“全部读 → 全部写”,reflow 次数降到至多 1 次。用法有两种:
// 方式 A:逐调用调度(拖拽等高频场景推荐)
lines.forEach(line => line.requestPosition())
// 方式 B:全局开关,position() 自动走调度
LeaderLine.deferPositionUpdate = true
lines.forEach(line => line.position())
position() 默认保持同步语义以兼容旧代码,LeaderLine.positionByWindowResize 内部已经走调度。
相比上游的新增与修复
功能
- ESM 默认导出
options.svgContainer:指定 SVG 挂载容器,默认document.body- 完整 TypeScript 类型定义
- 三产物:
dist/leader-line.mjs、dist/leader-line.cjs、dist/leader-line.min.js
修复
aplStats.position_plugOverheadSE is not defined@micro-zoe/micro-app中的getFrame error
迁移
从旧 leader-line 包迁移:
- "leader-line": "^1.1.0"
+ "@lionad/leader-line": "^1.0.0"
- 不再支持 IE11 与旧 Edge
- 产物路径变为
dist/下三格式 - Bower 已移除
- API 完全兼容,
requestPosition()/deferPositionUpdate为纯新增
结语
@lionad/leader-line 没有重新发明引导线,只是把上游库搬到了一个更现代的维护轨道上:类型完整、构建产物齐全、渲染有调度、Vue / Nuxt 有封装。如果你的项目里正好需要画几根线,可以试试看。