mind-elixir官方地址
官方地址
修改的点:
1、该插件默认是右键拖动画布,改为左键右键都可以拖动
2、默认画布内容是有点居右的,现在改为居中
1、新建MindMap.vue
<template>
<div ref="mindContainer" class="mind-container"></div>
</template>
<script>
import MindElixir from "mind-elixir/dist/MindElixir.js";
import "mind-elixir/dist/MindElixir.css";
export default {
name: "MindMap",
props: {
// 思维导图数据,从父组件传入
mindData: {
type: Object,
required: true,
},
// 思维导图配置项
options: {
type: Object,
default: () => ({
direction: MindElixir.RIGHT,
draggable: true,
toolBar: true,
editable: true,
keypress: true,
locale: "zh_CN",
}),
},
},
data() {
return {
mind: null,
};
},
mounted() {
this.initMind();
},
watch: {
// 监听数据变化,更新思维导图
mindData: {
deep: true,
handler(newData) {
if (this.mind) {
// 销毁现有实例
this.mind.destroy();
// 重新初始化
this.initMind();
}
},
},
// 监听配置项变化
options: {
deep: true,
handler() {
if (this.mind) {
this.mind.destroy();
this.initMind();
}
},
},
},
beforeDestroy() {
if (this.mind) {
this.mind.destroy();
}
// 移除DOM事件监听器
if (this.domClickHandler && this.$refs.mindContainer) {
this.$refs.mindContainer.removeEventListener("click", this.domClickHandler);
console.log("已移除DOM事件监听器");
}
},
methods: {
// 初始化思维导图
initMind() {
// 初始化 MindElixir
const mind = new MindElixir({
el: this.$refs.mindContainer,
...this.options,
});
// 使用父组件传入的数据初始化
mind.init(this.mindData);
this.mind = mind;
this.$nextTick(() => {
this.safeCenter();
}, 300);
this.setAddListener();
this.enableLeftDrag();
},
// 强制居中函数
safeCenter() {
const container = this.$refs.mindContainer;
const canvas = container.querySelector(".map-canvas");
if (!canvas) return;
// 计算容器和脑图宽高
const rect = container.getBoundingClientRect();
const mindRect = canvas.getBoundingClientRect();
// 把根节点移到容器中心
const offsetX = (rect.width - mindRect.width) / 2;
const offsetY = (rect.height - mindRect.height) / 2;
canvas.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
},
setAddListener() {
this.mind.bus.addListener("operation", (operation) => {
console.log(operation);
});
this.mind.bus.addListener("selectNodes", (node) => {
this.$emit("select-node", node);
});
this.mind.bus.addListener("expandNode", (node) => {
console.log("expandNode: ", node);
});
},
// 对外暴露获取当前数据的方法
getData() {
if (this.mind) {
return this.mind.getData();
}
return null;
},
enableLeftDrag() {
const container = this.$refs.mindContainer.querySelector(".map-canvas");
let isDragging = false;
let lastX = 0,
lastY = 0;
let transformX = 0,
transformY = 0;
const getTransform = () => {
const transform = container.style.transform || "translate(0px, 0px)";
const match = transform.match(/translate\(([-\d.]+)px,\s*([-\d.]+)px\)/);
if (match) {
transformX = parseFloat(match[1]);
transformY = parseFloat(match[2]);
} else {
transformX = 0;
transformY = 0;
}
};
container.addEventListener("mousedown", (e) => {
if (e.button === 0 && !e.target.closest(".node")) {
isDragging = true;
lastX = e.clientX;
lastY = e.clientY;
getTransform();
e.preventDefault();
}
});
window.addEventListener("mousemove", (e) => {
if (!isDragging) return;
const dx = e.clientX - lastX;
const dy = e.clientY - lastY;
container.style.transform = `translate(${transformX + dx}px, ${transformY + dy}px)`;
});
window.addEventListener("mouseup", () => {
isDragging = false;
});
},
},
};
</script>
<style scoped>
.mind-container {
width: 100%;
height: 600px;
border: 1px solid #ccc;
}
</style>
2、在页面index.vue里面使用
<template>
<div class="mind-map-container">
<div class="mind-container wbgc-card">
<MindMap ref="mindMap" :mind-data="mindData" :options="mindOptions" @select-node="handleSelectNode" />
</div>
</div>
</template>
<script>
import MindMap from "./components/MindMap.vue";
import MindElixir from "mind-elixir/dist/MindElixir.js";
import "mind-elixir/dist/MindElixir.css";
export default {
name: "CaseMindEdit",
inject: ["closeTab"],
components: {
MindMap,
},
data() {
return {
// 思维导图数据,将传递给子组件
mindData: {},
// 思维导图配置项
mindOptions: {
direction: MindElixir.RIGHT,
draggable: true,
toolBar: true,
editable: true,
locale: "zh_CN",
},
};
},
mounted() {
// 初始化思维导图数据
this.initMindData();
},
methods: {
// 初始化思维导图数据
initMindData() {
// 创建初始数据结构
const data = MindElixir.new("自定义右键菜单示例");
data.nodeData = {
id: "root",
topic: "root:",
children: [
{
id: "1",
topic: "1",
children: [
{
id: "1-1",
topic: "1-1",
children: [
{ id: "1-1-1", topic: "1-1-1:", children: [{ id: "1-1-1-1", topic: "New Node" }] },
{
id: "1-1-2",
topic: "1-1-2:",
children: [
{ id: "1-1-1-1", topic: "New Node" },
{ id: "1-1-1-2", topic: "New Node" },
],
},
{
id: "1-1-3",
topic: "1-1-3:",
children: [
{ id: "1-1-1-1", topic: "New Node" },
{ id: "1-1-1-2", topic: "New Node" },
{ id: "1-1-1-3", topic: "New Node" },
],
},
{
id: "1-1-4",
topic: "1-1-4:",
children: [
{ id: "1-1-1-1", topic: "New Node" },
{ id: "1-1-1-2", topic: "New Node" },
{ id: "1-1-1-3", topic: "New Node" },
{ id: "1-1-1-4", topic: "New Node" },
],
},
],
},
],
},
],
};
this.mindData = data;
},
// 处理思维导图数据变化事件
handleChangeData(data) {
console.log("思维导图数据变化:", data);
// 这里可以处理数据变化后的逻辑
},
},
};
</script>
<style scoped lang="less">
.mind-map-container {
height: 100%;
display: flex;
flex-direction: column;
padding: 0 12px 12px;
.row-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 24px;
margin-bottom: 12px;
.header-left {
color: #6281a3;
font-size: 16px;
padding-left: 13px;
line-height: 36px;
position: relative;
display: flex;
&::before {
content: "";
position: absolute;
width: 5px;
height: 14px;
left: 0;
top: 11px;
background-color: #87ce40;
}
}
.wpg-btn {
margin-left: 10px;
}
}
.mind-container {
flex: 1;
height: 100%;
}
}
</style>
效果

image.png