Demo:点击备注图标会在侧边栏形式备注内容

This commit is contained in:
wanglin2
2025-03-30 15:55:52 +08:00
parent a0e54870b5
commit bd2cfda905
6 changed files with 126 additions and 6 deletions

View File

@@ -505,5 +505,8 @@ export default {
'】Can you help me continue writing one of the contents of the mind map【',
aiCreatePartMsgPostfix:
'】The subordinate content of the node needs to be returned in Markdown format and can only use two syntax: Markdown title and unordered list. It can support multi-level nesting. Just return the content.'
},
note: {
title: 'Note'
}
}

View File

@@ -487,5 +487,8 @@ export default {
aiCreatePartMsgCenter: '】的思维导图,帮我续写其中一个内容为【',
aiCreatePartMsgPostfix:
'】的节点的下级内容需要以Markdown格式返回并且只能使用Markdown的标题和无序列表两种语法可以支持多层嵌套。只需返回内容即可。'
},
note: {
title: '备注'
}
}

View File

@@ -487,5 +487,8 @@ export default {
aiCreatePartMsgCenter: '】的思維導圖,幫我續寫其中一個內容爲【',
aiCreatePartMsgPostfix:
'】的節點的下級內容需要以Markdown格式返回並且只能使用Markdown的標題和無序列表兩種語法可以支持多層嵌套。只需返回內容即可。'
},
note: {
title: '備註'
}
}

View File

@@ -51,6 +51,7 @@
v-if="mindMap"
:mindMap="mindMap"
></NodeImgPlacementToolbar>
<NodeNoteSidebar v-if="mindMap" :mindMap="mindMap"></NodeNoteSidebar>
<AiCreate v-if="mindMap && enableAi" :mindMap="mindMap"></AiCreate>
<AiChat v-if="enableAi"></AiChat>
<div
@@ -140,6 +141,7 @@ import NodeTagStyle from './NodeTagStyle.vue'
import Setting from './Setting.vue'
import AssociativeLineStyle from './AssociativeLineStyle.vue'
import NodeImgPlacementToolbar from './NodeImgPlacementToolbar.vue'
import NodeNoteSidebar from './NodeNoteSidebar.vue'
import AiCreate from './AiCreate.vue'
import AiChat from './AiChat.vue'
@@ -197,6 +199,7 @@ export default {
Setting,
AssociativeLineStyle,
NodeImgPlacementToolbar,
NodeNoteSidebar,
AiCreate,
AiChat
},

View File

@@ -11,7 +11,10 @@
@mousedown.stop
@mousemove.stop
@mouseup.stop
></div>
@wheel.stop
>
<div class="noteContentWrap customScrollbar" ref="noteContentWrap"></div>
</div>
</template>
<script>
@@ -41,7 +44,7 @@ export default {
this.$bus.$on('showNoteContent', this.onShowNoteContent)
this.$bus.$on('hideNoteContent', this.hideNoteContent)
document.body.addEventListener('click', this.hideNoteContent)
this.$bus.$on('node_active', this.hideNoteContent)
this.$bus.$on('node_active', this.onNodeActive)
this.$bus.$on('scale', this.onScale)
this.$bus.$on('translate', this.onScale)
this.$bus.$on('svg_mousedown', this.hideNoteContent)
@@ -55,13 +58,24 @@ export default {
this.$bus.$off('showNoteContent', this.onShowNoteContent)
this.$bus.$off('hideNoteContent', this.hideNoteContent)
document.body.removeEventListener('click', this.hideNoteContent)
this.$bus.$off('node_active', this.hideNoteContent)
this.$bus.$off('node_active', this.onNodeActive)
this.$bus.$off('scale', this.onScale)
this.$bus.$off('translate', this.onScale)
this.$bus.$off('svg_mousedown', this.hideNoteContent)
this.$bus.$off('expand_btn_click', this.hideNoteContent)
},
methods: {
onNodeActive(...args) {
const nodes = [...args[1]]
if (nodes.length > 0) {
if (nodes[0] !== this.node) {
this.hideNoteContent()
}
} else {
this.hideNoteContent()
}
},
// 显示备注浮层
onShowNoteContent(content, left, top, node) {
this.node = node
@@ -101,7 +115,7 @@ export default {
initEditor() {
if (!this.editor) {
this.editor = new Viewer({
el: this.$refs.noteContentViewer
el: this.$refs.noteContentWrap
})
}
}
@@ -115,9 +129,13 @@ export default {
background-color: #fff;
padding: 10px;
border-radius: 5px;
max-height: 300px;
overflow-y: auto;
box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.06);
border: 1px solid rgba(0, 0, 0, 0.06);
.noteContentWrap {
max-width: 250px;
max-height: 300px;
overflow-y: auto;
}
}
</style>

View File

@@ -0,0 +1,90 @@
<template>
<Sidebar ref="sidebar" :title="$t('note.title')">
<div class="noteContentWrap" ref="noteContentWrap"></div>
</Sidebar>
</template>
<script>
import Sidebar from './Sidebar.vue'
import { mapState, mapMutations } from 'vuex'
import Viewer from '@toast-ui/editor/dist/toastui-editor-viewer'
import '@toast-ui/editor/dist/toastui-editor-viewer.css'
export default {
components: {
Sidebar
},
props: {
mindMap: {
type: Object
}
},
data() {
return {
editor: null,
node: null
}
},
computed: {
...mapState({
isDark: state => state.localConfig.isDark,
activeSidebar: state => state.activeSidebar
})
},
watch: {
activeSidebar(val) {
if (val === 'noteSidebar') {
this.$refs.sidebar.show = true
} else {
this.$refs.sidebar.show = false
}
}
},
created() {
this.$bus.$on('node_active', this.onNodeActive)
this.mindMap.on('node_note_click', this.onNodeNoteClick)
},
mounted() {
this.initEditor()
},
beforeDestroy() {
this.$bus.$off('node_active', this.onNodeActive)
this.mindMap.off('node_note_click', this.onNodeNoteClick)
},
methods: {
...mapMutations(['setActiveSidebar']),
onNodeActive(...args) {
const nodes = [...args[1]]
if (nodes.length > 0) {
if (nodes[0] !== this.node) {
this.setActiveSidebar(null)
}
} else {
this.setActiveSidebar(null)
}
},
// 初始化编辑器
initEditor() {
if (!this.editor) {
this.editor = new Viewer({
el: this.$refs.noteContentWrap
})
}
},
onNodeNoteClick(node) {
this.node = node
this.setActiveSidebar('noteSidebar')
this.editor.setMarkdown(node.getData('note'))
}
}
}
</script>
<style lang="less" scoped>
.noteContentWrap {
padding: 12px 20px;
}
</style>