mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 14:04:47 +08:00
Demo:支持节点链接开发中
This commit is contained in:
@@ -205,7 +205,8 @@ export const nodeDataNoStylePropList = [
|
||||
'checkbox',
|
||||
'dir',
|
||||
'needUpdate', // 重新创建节点内容
|
||||
'imgMap'
|
||||
'imgMap',
|
||||
'nodeLink'
|
||||
]
|
||||
|
||||
// 错误类型
|
||||
|
||||
@@ -134,6 +134,9 @@
|
||||
<div class="item" @click="exec('REMOVE_NOTE')" v-if="hasNote">
|
||||
<span class="name">{{ $t('contextmenu.removeNote') }}</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('LINK_NODE')">
|
||||
<span class="name">链接到指定节点</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('REMOVE_CUSTOM_STYLES')">
|
||||
<span class="name">{{ $t('contextmenu.removeCustomStyles') }}</span>
|
||||
</div>
|
||||
@@ -478,6 +481,10 @@ export default {
|
||||
case 'REMOVE_NOTE':
|
||||
this.node.setNote('')
|
||||
break
|
||||
case 'LINK_NODE':
|
||||
this.$bus.$emit('show_link_node', this.node)
|
||||
this.hide()
|
||||
break
|
||||
case 'EXPORT_CUR_NODE_TO_PNG':
|
||||
this.mindMap.export(
|
||||
'png',
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
<NodeNoteSidebar v-if="mindMap" :mindMap="mindMap"></NodeNoteSidebar>
|
||||
<AiCreate v-if="mindMap && enableAi" :mindMap="mindMap"></AiCreate>
|
||||
<AiChat v-if="enableAi"></AiChat>
|
||||
<LinkNodeSelect
|
||||
v-if="mindMap && supportNodeLink"
|
||||
:mindMap="mindMap"
|
||||
></LinkNodeSelect>
|
||||
<div
|
||||
class="dragMask"
|
||||
v-if="showDragMask"
|
||||
@@ -92,7 +96,7 @@ import NodeBase64ImageStorage from 'simple-mind-map/src/plugins/NodeBase64ImageS
|
||||
import Themes from 'simple-mind-map-plugin-themes'
|
||||
// 协同编辑插件
|
||||
// import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js'
|
||||
// 以下插件为付费插件,详情请查看开发文档。依次为:手绘风格插件、标记插件、编号插件、Freemind软件格式导入导出插件、Excel软件格式导入导出插件、待办插件、节点连线流动效果插件、动量效果插件
|
||||
// 以下插件为付费插件,详情请查看开发文档。依次为:手绘风格插件、标记插件、编号插件、Freemind软件格式导入导出插件、Excel软件格式导入导出插件、待办插件、节点连线流动效果插件、动量效果插件、向右鱼骨图插件、节点链接插件、扩展节点形状插件、扩展主题列表插件
|
||||
import HandDrawnLikeStyle from 'simple-mind-map-plugin-handdrawnlikestyle'
|
||||
import Notation from 'simple-mind-map-plugin-notation'
|
||||
import Numbers from 'simple-mind-map-plugin-numbers'
|
||||
@@ -102,9 +106,12 @@ import Checkbox from 'simple-mind-map-plugin-checkbox'
|
||||
import LineFlow from 'simple-mind-map-plugin-lineflow'
|
||||
import Momentum from 'simple-mind-map-plugin-momentum'
|
||||
import RightFishbone from 'simple-mind-map-plugin-right-fishbone'
|
||||
import NodeLink from 'simple-mind-map-plugin-node-link'
|
||||
import MoreShapes from 'simple-mind-map-plugin-more-shapes'
|
||||
import MoreThemes from 'simple-mind-map-plugin-more-themes'
|
||||
// npm link simple-mind-map-plugin-excel simple-mind-map-plugin-freemind simple-mind-map-plugin-numbers simple-mind-map-plugin-notation simple-mind-map-plugin-handdrawnlikestyle simple-mind-map-plugin-checkbox simple-mind-map simple-mind-map-plugin-themes simple-mind-map-plugin-lineflow simple-mind-map-plugin-momentum simple-mind-map-plugin-right-fishbone simple-mind-map-plugin-more-themes simple-mind-map-plugin-more-shapes
|
||||
// npm link simple-mind-map simple-mind-map-plugin-excel simple-mind-map-plugin-freemind simple-mind-map-plugin-numbers simple-mind-map-plugin-notation simple-mind-map-plugin-handdrawnlikestyle simple-mind-map-plugin-checkbox simple-mind-map-plugin-lineflow simple-mind-map-plugin-momentum simple-mind-map-plugin-right-fishbone simple-mind-map-plugin-node-link
|
||||
// simple-mind-map-plugin-themes
|
||||
// simple-mind-map-plugin-more-themes simple-mind-map-plugin-more-shapes
|
||||
import OutlineSidebar from './OutlineSidebar.vue'
|
||||
import Style from './Style.vue'
|
||||
import BaseStyle from './BaseStyle.vue'
|
||||
@@ -147,6 +154,7 @@ import NodeImgPlacementToolbar from './NodeImgPlacementToolbar.vue'
|
||||
import NodeNoteSidebar from './NodeNoteSidebar.vue'
|
||||
import AiCreate from './AiCreate.vue'
|
||||
import AiChat from './AiChat.vue'
|
||||
import LinkNodeSelect from './LinkNodeSelect.vue'
|
||||
|
||||
// 注册插件
|
||||
MindMap.usePlugin(MiniMap)
|
||||
@@ -168,7 +176,6 @@ MindMap.usePlugin(MiniMap)
|
||||
.usePlugin(OuterFrame)
|
||||
.usePlugin(MindMapLayoutPro)
|
||||
.usePlugin(NodeBase64ImageStorage)
|
||||
.usePlugin(RightFishbone)
|
||||
// .usePlugin(Cooperate) // 协同插件
|
||||
|
||||
// 注册主题
|
||||
@@ -209,7 +216,8 @@ export default {
|
||||
NodeImgPlacementToolbar,
|
||||
NodeNoteSidebar,
|
||||
AiCreate,
|
||||
AiChat
|
||||
AiChat,
|
||||
LinkNodeSelect
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -235,7 +243,8 @@ export default {
|
||||
isUseMomentum: state => state.localConfig.isUseMomentum,
|
||||
extraTextOnExport: state => state.extraTextOnExport,
|
||||
isDragOutlineTreeNode: state => state.isDragOutlineTreeNode,
|
||||
enableAi: state => state.localConfig.enableAi
|
||||
enableAi: state => state.localConfig.enableAi,
|
||||
supportNodeLink: state => state.supportNodeLink
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
@@ -703,6 +712,14 @@ export default {
|
||||
this.mindMap.addPlugin(LineFlow)
|
||||
this.$store.commit('setSupportLineFlow', true)
|
||||
}
|
||||
if (typeof RightFishbone !== 'undefined') {
|
||||
this.mindMap.addPlugin(RightFishbone)
|
||||
this.$store.commit('setSupportRightFishbone', true)
|
||||
}
|
||||
if (typeof NodeLink !== 'undefined') {
|
||||
this.mindMap.addPlugin(NodeLink)
|
||||
this.$store.commit('setSupportNodeLink', true)
|
||||
}
|
||||
if (typeof MoreShapes !== 'undefined') {
|
||||
this.mindMap.addPlugin(MoreShapes)
|
||||
this.$store.commit('setSupportMoreShapes', true)
|
||||
|
||||
152
web/src/pages/Edit/components/LinkNodeSelect.vue
Normal file
152
web/src/pages/Edit/components/LinkNodeSelect.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeLinkSelectDialog"
|
||||
title="链接到指定节点"
|
||||
:visible.sync="dialogVisible"
|
||||
:show-close="false"
|
||||
append-to-body
|
||||
width="400px"
|
||||
>
|
||||
<div class="nodeTreeWrap">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
class="outlineTree"
|
||||
node-key="uid"
|
||||
default-expand-all
|
||||
:class="{ isDark: isDark }"
|
||||
:data="treeData"
|
||||
:props="defaultProps"
|
||||
:highlight-current="true"
|
||||
:expand-on-click-node="false"
|
||||
@current-change="onCurrentChange"
|
||||
>
|
||||
</el-tree>
|
||||
</div>
|
||||
<div slot="footer" class="footer">
|
||||
<el-checkbox v-model="isAddReturn" style="margin-right: auto;">是否添加反向链接</el-checkbox>
|
||||
<el-button @click="cancel">{{
|
||||
$t('dialog.cancel')
|
||||
}}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
nodeRichTextToTextWithWrap,
|
||||
htmlEscape
|
||||
} from 'simple-mind-map/src/utils'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
mindMap: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
treeData: [],
|
||||
defaultProps: {
|
||||
label: 'label'
|
||||
},
|
||||
currentNodeData: null,
|
||||
node: null,
|
||||
isAddReturn: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isDark: state => state.localConfig.isDark
|
||||
})
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('show_link_node', this.onShowDialog)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('show_link_node', this.onShowDialog)
|
||||
},
|
||||
methods: {
|
||||
onShowDialog(node) {
|
||||
this.node = node
|
||||
let data = this.mindMap.getData()
|
||||
let walk = root => {
|
||||
let text = root.data.richText
|
||||
? nodeRichTextToTextWithWrap(root.data.text)
|
||||
: root.data.text
|
||||
text = htmlEscape(text)
|
||||
text = text.replace(/\n/g, '<br>')
|
||||
root.label = text
|
||||
root.uid = root.data.uid
|
||||
if (root.children && root.children.length > 0) {
|
||||
root.children.forEach(item => {
|
||||
walk(item)
|
||||
})
|
||||
}
|
||||
}
|
||||
walk(data)
|
||||
this.treeData = [data]
|
||||
this.dialogVisible = true
|
||||
},
|
||||
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
this.node = null
|
||||
this.treeData = []
|
||||
this.currentNodeData = null
|
||||
this.isAddReturn = false
|
||||
},
|
||||
|
||||
// 当前选中的树节点变化事件
|
||||
onCurrentChange(data) {
|
||||
this.currentNodeData = data
|
||||
},
|
||||
|
||||
cancel() {
|
||||
this.close()
|
||||
},
|
||||
|
||||
confirm() {
|
||||
if (!this.currentNodeData) {
|
||||
this.$message.warning('请选择要链接到的节点')
|
||||
return
|
||||
}
|
||||
if (this.currentNodeData.uid === this.node.getData('uid')) {
|
||||
this.$message.warning('不能链接自己')
|
||||
return
|
||||
}
|
||||
this.$bus.$emit(
|
||||
'execCommand',
|
||||
'SET_NODE_LINK',
|
||||
this.node,
|
||||
this.currentNodeData.uid,
|
||||
this.isAddReturn
|
||||
)
|
||||
this.$message.success('链接成功')
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.nodeLinkSelectDialog {
|
||||
/deep/ .el-dialog__body {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
.nodeTreeWrap {
|
||||
height: 400px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -350,7 +350,8 @@ export default {
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<style lang="less">
|
||||
.outlineTree {
|
||||
&.isDark {
|
||||
background-color: #262a2e;
|
||||
|
||||
@@ -362,67 +362,4 @@ export default {
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.outlineTree {
|
||||
&.isDark {
|
||||
background-color: #262a2e;
|
||||
|
||||
.customNode {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.el-tree--highlight-current {
|
||||
/deep/ .el-tree-node.is-current > .el-tree-node__content {
|
||||
background-color: hsla(0, 0%, 100%, 0.05) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node__content:hover,
|
||||
.el-upload-list__item:hover {
|
||||
background-color: hsla(0, 0%, 100%, 0.02) !important;
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node__content {
|
||||
.el-tree-node__expand-icon {
|
||||
color: #fff;
|
||||
|
||||
&.is-leaf {
|
||||
&::after {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node > .el-tree-node__children {
|
||||
overflow: inherit;
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node__content {
|
||||
height: auto;
|
||||
margin: 5px 0;
|
||||
|
||||
.el-tree-node__expand-icon {
|
||||
color: #262a2e;
|
||||
|
||||
&.is-leaf {
|
||||
color: transparent;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
background-color: #262a2e;
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -38,7 +38,9 @@ const store = new Vuex.Store({
|
||||
supportCheckbox: false, // 是否支持Checkbox插件
|
||||
supportLineFlow: false, // 是否支持LineFlow插件
|
||||
supportMomentum: false, // 是否支持Momentum插件
|
||||
supportMoreShapes: false,// 是否支持MoreShapes插件
|
||||
supportRightFishbone: false, // 是否支持RightFishbone插件
|
||||
supportNodeLink: false, // 是否支持NodeLink插件
|
||||
supportMoreShapes: false, // 是否支持MoreShapes插件
|
||||
isDragOutlineTreeNode: false, // 当前是否正在拖拽大纲树的节点
|
||||
aiConfig: {
|
||||
api: 'http://ark.cn-beijing.volces.com/api/v3/chat/completions',
|
||||
@@ -139,6 +141,16 @@ const store = new Vuex.Store({
|
||||
state.supportMomentum = data
|
||||
},
|
||||
|
||||
// 设置是否支持RightFishbone插件
|
||||
setSupportRightFishbone(state, data) {
|
||||
state.supportRightFishbone = data
|
||||
},
|
||||
|
||||
// 设置是否支持NodeLink插件
|
||||
setSupportNodeLink(state, data) {
|
||||
state.supportNodeLink = data
|
||||
},
|
||||
|
||||
// 设置是否支持MoreShapes插件
|
||||
setSupportMoreShapes(state, data) {
|
||||
state.supportMoreShapes = data
|
||||
|
||||
Reference in New Issue
Block a user