npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

vue2-mind-map

v0.1.17

Published

`vue2-mind-map` 是一个功能丰富的思维导图可视化组件。该组件提供了完整的思维导图展示和交互功能,支持多种数据格式输入、灵活的布局配置、丰富的样式定制和流畅的用户交互体验。目前基于 Vue 2 构建。

Downloads

40

Readme

vue2-mind-map 组件使用文档

vue2-mind-map 是一个功能丰富的思维导图可视化组件。该组件提供了完整的思维导图展示和交互功能,支持多种数据格式输入、灵活的布局配置、丰富的样式定制和流畅的用户交互体验。目前基于 Vue 2 构建。

TODO

  • 支持 Vue 3
  • 触摸屏支持
  • 操作历史及回滚
  • 小地图

数据结构说明

TreeNode(树形数据结构)

用于描述具有层级关系的思维导图节点,通过 children 数组直接表示父子关系:

  • id string (可选) - 节点唯一标识符
  • position object (可选) - 节点位置坐标,格式:{ x: number, y: number }
  • size object (可选) - 节点尺寸,格式:{ x: number, y: number }
  • children array (可选) - 子节点数组,每个元素都是 TreeNode 结构
  • collapsed boolean (可选) - 节点是否折叠,默认为 false
  • content string|HTMLElement|array|function (可选) - 节点显示内容
  • [自定义属性] any - 可以添加任意自定义属性

示例

const treeData = {
  id: 'root',
  content: '根节点',
  children: [
    {
      id: 'child1',
      content: '子节点1',
      collapsed: false,
      children: [
        { id: 'grandchild1', content: '孙节点1' }
      ]
    },
    { id: 'child2', content: '子节点2' }
  ]
}

FlatNode(扁平数据结构)

用于描述扁平化的思维导图节点,通过 parentId 间接表示父子关系:

  • id string (可选) - 节点唯一标识符
  • parentId string (可选) - 父节点ID,根节点可以不设置
  • position object (可选) - 节点位置坐标,格式:{ x: number, y: number }
  • size object (可选) - 节点尺寸,格式:{ x: number, y: number }
  • collapsed boolean (可选) - 节点是否折叠,默认为 false
  • content string|HTMLElement|array|function (可选) - 节点显示内容
  • [自定义属性] any - 可以添加任意自定义属性

示例

const flatData = [
  { id: 'root', content: '根节点' },
  { id: 'child1', parentId: 'root', content: '子节点1' },
  { id: 'child2', parentId: 'root', content: '子节点2' },
  { id: 'grandchild1', parentId: 'child1', content: '孙节点1' }
]

配置选项说明

对齐配置 (MindMapAlign)

控制思维导图节点的对齐方式:

  • mode string - 对齐模式,可选值:
    • "cross-axis-start-edge" - 交叉轴起始边对齐(默认)
    • "cross-axis-center" - 交叉轴居中对齐
    • "node-center" - 以指定节点为中心对齐
  • targetNodeId string (可选) - 目标节点ID,仅在 mode"node-center" 时使用

拖拽配置 (MindMapDragOptions)

控制思维导图的拖拽行为:

  • enableNodeDrag boolean (可选) - 是否启用节点拖拽,默认 true
  • enableCanvasDrag boolean (可选) - 是否启用画布拖拽,默认 true
  • dragNodeButton number|array (可选) - 拖拽节点的鼠标按钮,默认左键(0)
  • dragCanvasButton number|array (可选) - 拖拽画布的鼠标按钮,默认右键(2)和中键(1)
  • useThrottle boolean (可选) - 是否使用节流减少事件触发频率,默认 true
  • throttleWait number (可选) - 节流函数的等待时间,默认 16 毫秒

鼠标按钮值:左键=0,中键=1,右键=2

缩放配置 (MindMapZoomOptions)

控制思维导图的缩放行为:

  • enableWheelZoom boolean (可选) - 是否启用滚轮缩放,默认 true
  • zoomStep number (可选) - 每次缩放步长,默认 0.1 (10%)
  • invertWheelDirection boolean (可选) - 是否反转滚轮方向,默认 false
  • minZoom number (可选) - 最小缩放比例,默认 0.1 (10%)
  • maxZoom number (可选) - 最大缩放比例,默认 5.0 (500%)
  • useThrottle boolean (可选) - 是否使用节流减少事件触发频率,默认 true
  • throttleWait number (可选) - 节流函数的等待时间,默认 16 毫秒

全屏配置 (FullscreenOptions)

控制思维导图的全屏行为:

  • fullscreenBgColor string (可选) - 全屏模式下的背景颜色,默认 #FFFFFF
  • fullscreenMode string (可选) - 全屏模式,可选值:
    • "native" - 使用浏览器原生全屏 API(默认)
    • "pseudo" - 使用 CSS 模拟全屏效果

Props

基础配置

data (必填)

  • 类型: TreeNode 对象 或 FlatNode 数组
  • 描述: 思维导图的数据源

direction

  • 类型: "horizontal" | "vertical"
  • 默认值: "horizontal"
  • 描述: 思维导图的布局方向

样式配置

line-style

  • 类型: "straight" | "curved" | "zigzag"
  • 默认值: "curved"
  • 描述: 连接线的样式

line-color

  • 类型: String
  • 默认值: "#000000"
  • 描述: 连接线的颜色

line-width

  • 类型: Number
  • 默认值: 1
  • 描述: 连接线的宽度,单位像素

node-border-width

  • 类型: Number
  • 默认值: 1
  • 描述: 节点边框的宽度,单位像素

node-bg-color

  • 类型: String
  • 默认值: "#FFFFFF"
  • 描述: 节点背景颜色

node-border-color

  • 类型: String
  • 默认值: "#000000"
  • 描述: 节点边框颜色

布局配置

align

  • 类型: MindMapAlign 配置对象
  • 默认值: { mode: "cross-axis-start-edge" }
  • 描述: 思维导图对齐方式配置

sibling-separation

  • 类型: Number
  • 默认值: 25
  • 描述: 同级节点之间的间距,单位像素

level-separation

  • 类型: Number
  • 默认值: 50
  • 描述: 层级之间的间距,单位像素

initial-offset

  • 类型: Object
  • 默认值: undefined
  • 描述: 思维导图的初始偏移量,格式:{ x: number, y: number }

交互配置

drag-options

  • 类型: MindMapDragOptions 配置对象
  • 默认值: { enableNodeDrag: true, enableCanvasDrag: true, dragNodeButton: 0, dragCanvasButton: [2, 1], useThrottle: true, throttleWait: 16 }
  • 描述: 拖拽相关配置。dragNodeButtondragCanvasButton 的值可以是单个鼠标按钮或按钮数组 (左键=0, 中键=1, 右键=2)。

zoom-options

  • 类型: MindMapZoomOptions 配置对象
  • 默认值: { enableWheelZoom: true, zoomStep: 0.1, invertWheelDirection: false, minZoom: 0.1, maxZoom: 5.0, useThrottle: true, throttleWait: 16 }
  • 描述: 缩放相关配置。

full-screen-options

  • 类型: FullscreenOptions 配置对象
  • 默认值: { fullscreenBgColor: '#FFFFFF', fullscreenMode: 'native' }
  • 描述: 全屏相关配置。

方法 (Methods)

你可以通过获取 MindMap.vue 组件的引用 (ref) 来调用其公开方法。

示例:

<template>
  <mind-map ref="mindMapRef" :data="mindMapData" />
</template>

<script>
export default {
  mounted() {
    // 调用 rebuild 方法
    this.$refs.mindMapRef.rebuild();
  }
};
</script>

布局和渲染控制

rebuild()

  • 描述: 重置思维导图布局并重新渲染
  • 返回: void

clear()

  • 描述: 清空思维导图实例的所有内容和状态
  • 返回: void

setHorizontal(isHorizontal)

  • 参数: isHorizontal: boolean - 布局方向,true 为水平,false 为垂直
  • 描述: 设置思维导图布局方向
  • 返回: void

缩放控制

zoomIn(cx?, cy?)

  • 参数:
    • cx?: number - 缩放中心点的 X 坐标(可选)
    • cy?: number - 缩放中心点的 Y 坐标(可选)
  • 描述: 放大思维导图
  • 返回: void

zoomOut(cx?, cy?)

  • 参数:
    • cx?: number - 缩放中心点的 X 坐标(可选)
    • cy?: number - 缩放中心点的 Y 坐标(可选)
  • 描述: 缩小思维导图
  • 返回: void

resetZoom(cx?, cy?)

  • 参数:
    • cx?: number - 缩放中心点的 X 坐标(可选)
    • cy?: number - 缩放中心点的 Y 坐标(可选)
  • 描述: 重置思维导图缩放比例到 1.0
  • 返回: void

节点操作

setNodeSize(nodeId, size)

  • 参数:
    • nodeId: string - 要设置尺寸的节点 ID
    • size: { width?: number; height?: number } - 新的节点尺寸
  • 描述: 设置指定节点的尺寸
  • 返回: boolean | undefined - 如果节点找到并成功设置尺寸,则返回 true;否则返回 false

focusOnNode(nodeId)

  • 参数: nodeId: string - 节点ID
  • 描述: 将指定节点聚焦到视口中心
  • 返回: boolean | undefined - 如果节点找到并成功聚焦,则返回 true;否则返回 false

toggleNodeCollapse(nodeId)

  • 参数: nodeId: string - 节点ID
  • 描述: 切换节点的折叠状态
  • 返回: boolean | undefined - 如果节点找到并成功切换状态,则返回 true;否则返回 false

setNodeCollapsed(nodeId, collapsed)

  • 参数:
    • nodeId: string - 节点ID
    • collapsed: boolean - 要设置的折叠状态
  • 描述: 设置节点的折叠状态
  • 返回: boolean | undefined - 如果节点找到并成功设置状态,则返回 true;否则返回 false

getNodeCollapsed(nodeId)

  • 参数: nodeId: string - 节点ID
  • 描述: 获取节点的折叠状态
  • 返回: boolean | undefined - 节点的折叠状态,如果节点不存在则返回 undefined

expandAllNodes()

  • 描述: 展开所有节点
  • 返回: number - 成功展开的节点数量

collapseAllNodes()

  • 描述: 折叠所有非根节点
  • 返回: number - 成功折叠的节点数量

updateNodeContents(nodeIds?)

  • 参数: nodeIds?: string[] - 要更新内容的节点 ID 数组,不传参时默认更新所有节点
  • 描述: 更新指定节点的内容,此方法会根据节点的 content 属性或外部传入的 contentCallback 来重新解析和设置节点内部的内容
  • 返回: Promise<number> - 成功更新的节点个数

全屏控制

enterFullscreen(mode?)

  • 参数:
    • mode?: "native" | "pseudo" (可选) - 全屏模式 ('native' 或 'pseudo')。如果未提供,则使用组件 prop 中配置的默认模式。
  • 描述: 进入全屏模式。
  • 返回: Promise<boolean | undefined> - 成功时 resolve true,失败时 reject error。

exitFullscreen()

  • 描述: 退出全屏模式。会自动检测并退出当前激活的全屏模式 (原生或模拟)。
  • 返回: Promise<boolean | undefined> - 成功时 resolve true,失败时 reject error。

toggleFullscreen(mode?)

  • 参数:
    • mode?: "native" | "pseudo" (可选) - 全屏模式 ('native' 或 'pseudo')。如果未提供,则使用组件 prop 中配置的默认模式。
  • 描述: 切换全屏状态。
  • 返回: Promise<boolean | undefined> - 成功时 resolve 新的全屏状态 (true 为进入,false 为退出)。

插槽 (Slots)

默认插槽

  • 名称: default(默认插槽)
  • 作用域: { node: TreeNode | FlatNode }
  • 描述: 自定义节点内容的显示。你可以通过这个作用域插槽来为每个节点提供自定义的 HTML 结构。
  • node: 当前正在渲染的节点对象,包含节点的 ID、位置、子节点等信息。也就是你通过 prop data 传入的节点。

基础示例:

<template>
  <mind-map :data="mindMapData">
    <template v-slot="{ node }">
      <div class="custom-node">
        <strong>{{ node.id }}</strong>
        <p v-if="node.data && node.data.description">{{ node.data.description }}</p>
      </div>
    </template>
  </mind-map>
</template>

条件渲染示例:

<template>
  <mind-map :data="mindMapData">
    <template v-slot="{ node }">
      <!-- 方式1: 使用 v-show 控制显示 -->
      <div v-show="slotIndex === 1" class="node-style-1">
        样式1 - {{ node.id }}
      </div>
      <div v-show="slotIndex === 2" class="node-style-2">
        样式2 - {{ node.id }}
      </div>
      
      <!-- 方式2: 使用 v-if 条件渲染 -->
      <div v-if="node.type === 'important'" class="important-node">
        重要节点: {{ node.id }}
      </div>
      <div v-else class="normal-node">
        普通节点: {{ node.id }}
      </div>
    </template>
  </mind-map>
</template>

注意事项:

  • 插槽内容会被缓存以提高性能,每个节点对应一个 Vue 实例
  • 插槽渲染失败时会显示错误信息,并回退到默认渲染

事件 (Events)

你可以通过监听 MindMap.vue 组件的事件来响应思维导图的状态变化。

画布拖拽事件

canvas-drag-start

  • 触发时机: 当画布开始被拖拽时触发
  • 事件数据: MindMapCanvasEvent 对象
    • originalEvent: MouseEvent - 原始鼠标事件
    • button: MouseButton | null - 按下的鼠标按钮
    • mouseX: number - 拖拽开始时鼠标在容器内的 X 坐标
    • mouseY: number - 拖拽开始时鼠标在容器内的 Y 坐标
  • 描述: 此事件在画布拖拽开始时触发,可以用于记录拖拽开始状态或执行相关初始化操作

canvas-drag

  • 触发时机: 当画布正在被拖拽时触发
  • 事件数据: MindMapCanvasEvent 对象
    • originalEvent: MouseEvent - 原始鼠标事件
    • button: MouseButton | null - 按下的鼠标按钮
    • mouseX: number - 当前鼠标在容器内的 X 坐标
    • mouseY: number - 当前鼠标在容器内的 Y 坐标
    • deltaX: number - X 轴拖拽距离
    • deltaY: number - Y 轴拖拽距离
  • 描述: 此事件在画布拖拽过程中持续触发,可以用于同步画布位置状态或执行跟随操作

canvas-drag-end

  • 触发时机: 当画布拖拽结束时触发
  • 事件数据: MindMapCanvasEvent 对象
    • originalEvent: MouseEvent - 原始鼠标事件
    • button: MouseButton | null - 按下的鼠标按钮
    • mouseX: number - 拖拽结束时鼠标在容器内的 X 坐标
    • mouseY: number - 拖拽结束时鼠标在容器内的 Y 坐标
  • 描述: 此事件在画布拖拽结束时触发,可以用于保存最终状态或执行清理操作

使用示例:

<template>
  <mind-map 
    :data="mindMapData" 
    @canvas-drag-start="handleCanvasDragStart"
    @canvas-drag="handleCanvasDrag"
    @canvas-drag-end="handleCanvasDragEnd"
  />
</template>

<script>
export default {
  methods: {
    handleCanvasDragStart(event) {
      console.log('画布开始拖拽:', event.mouseX, event.mouseY);
    },
    
    handleCanvasDrag(event) {
      console.log('画布拖拽中:', `移动了 ${event.deltaX}, ${event.deltaY}`);
    },
    
    handleCanvasDragEnd(event) {
      console.log('画布拖拽结束');
    }
  }
};
</script>

缩放事件

zoom-change

  • 触发时机: 当思维导图的缩放比例发生变化时触发
  • 事件数据: MindMapZoomEvent 对象
    • originalEvent?: WheelEvent - 原始滚轮事件(如果是滚轮触发的缩放)
    • scale: Vector - 当前的缩放比例向量 {x, y}
    • mouseX: number - 缩放中心在容器内的 X 坐标
    • mouseY: number - 缩放中心在容器内的 Y 坐标
  • 描述: 此事件在缩放操作(放大、缩小、重置)完成后触发,可以用于同步缩放状态或执行相关联的操作

使用示例:

<template>
  <mind-map 
    :data="mindMapData" 
    @zoom-change="handleZoomChange"
  />
</template>

<script>
export default {
  methods: {
    handleZoomChange(event) {
      console.log('缩放比例变化:', `${event.scale.x * 100}%`);
      console.log('缩放中心:', event.mouseX, event.mouseY);
      
      // 同步外部缩放状态
      this.currentZoomLevel = event.scale.x;
    }
  }
};
</script>

容器尺寸变化事件

container-resize

  • 触发时机: 当思维导图容器尺寸发生变化时触发
  • 事件数据: MindMapContainerResizeEvent 对象
    • width: number - 新的容器宽度
    • height: number - 新的容器高度
  • 描述: 此事件在容器尺寸变化时触发,可以用于响应式布局调整或执行相关的重新计算操作

使用示例:

<template>
  <mind-map 
    :data="mindMapData" 
    @container-resize="handleContainerResize"
  />
</template>

<script>
export default {
  methods: {
    handleContainerResize(event) {
      console.log('容器尺寸变化:', `${event.width} x ${event.height}`);
      
      // 根据新尺寸调整相关组件
      this.adjustUIForNewSize(event.width, event.height);
    },
    
    adjustUIForNewSize(width, height) {
      // 执行尺寸相关的调整逻辑
    }
  }
};
</script>

布局更新事件

layout-updated

  • 触发时机: 当思维导图的布局发生变化并更新完成后触发(例如,从水平切换到垂直布局,或重新计算布局后)
  • 事件数据: MindMapLayoutEvent 对象
    • direction: 'horizontal' | 'vertical' - 当前的布局方向
  • 描述: 此事件在思维导图完成布局计算和渲染后触发,可以用于同步外部状态或执行需要在布局稳定后进行的操作

使用示例:

<template>
  <mind-map 
    :data="mindMapData" 
    @layout-updated="handleLayoutUpdated"
  />
</template>

<script>
export default {
  methods: {
    handleLayoutUpdated(event) {
      console.log('布局已更新,当前方向:', event.direction);
      // 执行布局更新后的逻辑
    }
  }
};
</script>

节点折叠状态变化事件

node-collapse-changed

  • 触发时机: 当任何节点的折叠/展开状态发生变化时触发
  • 事件数据: MindMapNodeCollapseEvent 对象
    • nodeId: string - 折叠状态发生变化的节点 ID
    • collapsed: boolean - 当前的折叠状态,true 表示已折叠,false 表示已展开
    • node: TreeNode | FlatNode - 被折叠/展开的节点对应的原始数据
  • 描述: 此事件在调用折叠相关方法(如 toggleNodeCollapsesetNodeCollapsedexpandAllNodescollapseAllNodes)时触发,可以用于同步外部状态或记录操作历史

使用示例:

<template>
  <mind-map 
    :data="mindMapData" 
    @node-collapse-changed="handleNodeCollapseChanged"
  />
</template>

<script>
export default {
  methods: {
    handleNodeCollapseChanged(event) {
      console.log(`节点 ${event.nodeId} ${event.collapsed ? '折叠' : '展开'}了`);
      console.log('节点数据:', event.node);
      
      // 同步外部状态
      this.updateNodeState(event.nodeId, event.collapsed);
    },
    
    updateNodeState(nodeId, collapsed) {
      // 更新外部数据或状态管理
    }
  }
};
</script>

批量操作事件: 当调用 expandAllNodes()collapseAllNodes() 方法时,每个状态发生变化的节点都会单独触发一次 node-collapse-changed 事件。