mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 22:08:25 +08:00
Demo:组件卸载时解除绑定的事件
This commit is contained in:
@@ -72,8 +72,7 @@ import OutlineEdit from './OutlineEdit.vue'
|
||||
import { showLoading, hideLoading } from '@/utils/loading'
|
||||
|
||||
// 注册插件
|
||||
MindMap
|
||||
.usePlugin(MiniMap)
|
||||
MindMap.usePlugin(MiniMap)
|
||||
.usePlugin(Watermark)
|
||||
.usePlugin(Drag)
|
||||
.usePlugin(KeyboardNavigation)
|
||||
@@ -88,7 +87,7 @@ MindMap
|
||||
.usePlugin(Painter)
|
||||
|
||||
// 注册自定义主题
|
||||
customThemeList.forEach((item) => {
|
||||
customThemeList.forEach(item => {
|
||||
MindMap.defineTheme(item.value, item.theme)
|
||||
})
|
||||
|
||||
@@ -132,7 +131,8 @@ export default {
|
||||
...mapState({
|
||||
isZenMode: state => state.localConfig.isZenMode,
|
||||
openNodeRichText: state => state.localConfig.openNodeRichText,
|
||||
useLeftKeySelectionRightKeyDrag: state => state.localConfig.useLeftKeySelectionRightKeyDrag,
|
||||
useLeftKeySelectionRightKeyDrag: state =>
|
||||
state.localConfig.useLeftKeySelectionRightKeyDrag
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
@@ -153,25 +153,48 @@ export default {
|
||||
this.$bus.$on('paddingChange', this.onPaddingChange)
|
||||
this.$bus.$on('export', this.export)
|
||||
this.$bus.$on('setData', this.setData)
|
||||
this.$bus.$on('startTextEdit', () => {
|
||||
this.mindMap.renderer.startTextEdit()
|
||||
})
|
||||
this.$bus.$on('endTextEdit', () => {
|
||||
this.mindMap.renderer.endTextEdit()
|
||||
})
|
||||
this.$bus.$on('createAssociativeLine', () => {
|
||||
this.mindMap.associativeLine.createLineFromActiveNode()
|
||||
})
|
||||
this.$bus.$on('startPainter', () => {
|
||||
this.mindMap.painter.startPainter()
|
||||
})
|
||||
this.$bus.$on('startTextEdit', this.handleStartTextEdit)
|
||||
this.$bus.$on('endTextEdit', this.handleEndTextEdit)
|
||||
this.$bus.$on('createAssociativeLine', this.handleCreateLineFromActiveNode)
|
||||
this.$bus.$on('startPainter', this.handleStartPainter)
|
||||
this.$bus.$on('node_tree_render_end', this.handleHideLoading)
|
||||
this.$bus.$on('showLoading', this.handleShowLoading)
|
||||
window.addEventListener('resize', () => {
|
||||
this.mindMap.resize()
|
||||
})
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('execCommand', this.execCommand)
|
||||
this.$bus.$off('paddingChange', this.onPaddingChange)
|
||||
this.$bus.$off('export', this.export)
|
||||
this.$bus.$off('setData', this.setData)
|
||||
this.$bus.$off('startTextEdit', this.handleStartTextEdit)
|
||||
this.$bus.$off('endTextEdit', this.handleEndTextEdit)
|
||||
this.$bus.$off('createAssociativeLine', this.handleCreateLineFromActiveNode)
|
||||
this.$bus.$off('startPainter', this.handleStartPainter)
|
||||
this.$bus.$off('node_tree_render_end', this.handleHideLoading)
|
||||
this.$bus.$off('showLoading', this.handleShowLoading)
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
},
|
||||
methods: {
|
||||
handleStartTextEdit() {
|
||||
this.mindMap.renderer.startTextEdit()
|
||||
},
|
||||
|
||||
handleEndTextEdit() {
|
||||
this.mindMap.renderer.endTextEdit()
|
||||
},
|
||||
|
||||
handleCreateLineFromActiveNode() {
|
||||
this.mindMap.associativeLine.createLineFromActiveNode()
|
||||
},
|
||||
|
||||
handleStartPainter() {
|
||||
this.mindMap.painter.startPainter()
|
||||
},
|
||||
|
||||
handleResize() {
|
||||
this.mindMap.resize()
|
||||
},
|
||||
|
||||
// 显示loading
|
||||
handleShowLoading() {
|
||||
this.enableShowLoading = true
|
||||
@@ -252,7 +275,7 @@ export default {
|
||||
...(config || {}),
|
||||
iconList: icon,
|
||||
useLeftKeySelectionRightKeyDrag: this.useLeftKeySelectionRightKeyDrag,
|
||||
customInnerElsAppendTo: null,
|
||||
customInnerElsAppendTo: null
|
||||
// isUseCustomNodeContent: true,
|
||||
// 示例1:组件里用到了router、store、i18n等实例化vue组件时需要用到的东西
|
||||
// customCreateNodeContent: (node) => {
|
||||
@@ -309,18 +332,18 @@ export default {
|
||||
})
|
||||
this.bindSaveEvent()
|
||||
// setTimeout(() => {
|
||||
// 动态给指定节点添加子节点
|
||||
// this.mindMap.execCommand('INSERT_CHILD_NODE', false, this.mindMap.renderer.root, {
|
||||
// text: '自定义内容'
|
||||
// })
|
||||
// 动态给指定节点添加子节点
|
||||
// this.mindMap.execCommand('INSERT_CHILD_NODE', false, this.mindMap.renderer.root, {
|
||||
// text: '自定义内容'
|
||||
// })
|
||||
|
||||
// 动态给指定节点添加同级节点
|
||||
// this.mindMap.execCommand('INSERT_NODE', false, this.mindMap.renderer.root, {
|
||||
// text: '自定义内容'
|
||||
// })
|
||||
// 动态给指定节点添加同级节点
|
||||
// this.mindMap.execCommand('INSERT_NODE', false, this.mindMap.renderer.root, {
|
||||
// text: '自定义内容'
|
||||
// })
|
||||
|
||||
// 动态删除指定节点
|
||||
// this.mindMap.execCommand('REMOVE_NODE', this.mindMap.renderer.root.children[0])
|
||||
// 动态删除指定节点
|
||||
// this.mindMap.execCommand('REMOVE_NODE', this.mindMap.renderer.root.children[0])
|
||||
// }, 5000);
|
||||
// 如果应用被接管,那么抛出事件传递思维导图实例
|
||||
if (window.takeOverApp) {
|
||||
@@ -386,7 +409,7 @@ export default {
|
||||
if (!showed) {
|
||||
this.$notify.info({
|
||||
title: this.$t('edit.newFeatureNoticeTitle'),
|
||||
message: this.$t('edit.newFeatureNoticeMessage'),
|
||||
message: this.$t('edit.newFeatureNoticeMessage'),
|
||||
duration: 0,
|
||||
onClose: () => {
|
||||
localStorage.setItem('SIMPLE_MIND_MAP_NEW_FEATURE_TIP_1', true)
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
>{{ $t('export.include') }}</el-checkbox
|
||||
>
|
||||
</div>
|
||||
<div class="paddingInputBox" v-show="['svg', 'png', 'pdf'].includes(exportType)">
|
||||
<div
|
||||
class="paddingInputBox"
|
||||
v-show="['svg', 'png', 'pdf'].includes(exportType)"
|
||||
>
|
||||
<span class="name">{{ $t('export.paddingX') }}</span>
|
||||
<el-input
|
||||
style="width: 100px"
|
||||
@@ -32,7 +35,9 @@
|
||||
size="mini"
|
||||
@change="onPaddingChange"
|
||||
></el-input>
|
||||
<span class="name" style="margin-left: 10px;">{{ $t('export.paddingY') }}</span>
|
||||
<span class="name" style="margin-left: 10px;">{{
|
||||
$t('export.paddingY')
|
||||
}}</span>
|
||||
<el-input
|
||||
style="width: 100px"
|
||||
v-model="paddingY"
|
||||
@@ -47,11 +52,11 @@
|
||||
>
|
||||
</div>
|
||||
<div class="downloadTypeList">
|
||||
<div
|
||||
class="downloadTypeItem"
|
||||
v-for="item in downTypeList"
|
||||
:key="item.type"
|
||||
:class="{active: exportType === item.type}"
|
||||
<div
|
||||
class="downloadTypeItem"
|
||||
v-for="item in downTypeList"
|
||||
:key="item.type"
|
||||
:class="{ active: exportType === item.type }"
|
||||
@click="exportType = item.type"
|
||||
>
|
||||
<div class="icon iconfont" :class="[item.icon, item.type]"></div>
|
||||
@@ -104,14 +109,19 @@ export default {
|
||||
|
||||
downTypeList() {
|
||||
return downTypeList[this.$i18n.locale] || downTypeList.zh
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('showExport', () => {
|
||||
this.dialogVisible = true
|
||||
})
|
||||
this.$bus.$on('showExport', this.handleShowExport)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('showExport', this.handleShowExport)
|
||||
},
|
||||
methods: {
|
||||
handleShowExport() {
|
||||
this.dialogVisible = true
|
||||
},
|
||||
|
||||
onPaddingChange() {
|
||||
this.$bus.$emit('paddingChange', {
|
||||
exportPaddingX: Number(this.paddingX),
|
||||
@@ -163,12 +173,7 @@ export default {
|
||||
this.isTransparent
|
||||
)
|
||||
} else {
|
||||
this.$bus.$emit(
|
||||
'export',
|
||||
this.exportType,
|
||||
true,
|
||||
this.fileName
|
||||
)
|
||||
this.$bus.$emit('export', this.exportType, true, this.fileName)
|
||||
}
|
||||
this.$notify.info({
|
||||
title: this.$t('export.notifyTitle'),
|
||||
@@ -189,7 +194,7 @@ export default {
|
||||
|
||||
.info {
|
||||
.name {
|
||||
color: hsla(0,0%,100%,.9);
|
||||
color: hsla(0, 0%, 100%, 0.9);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,7 +227,7 @@ export default {
|
||||
margin-top: 10px;
|
||||
|
||||
&.warning {
|
||||
color: #F56C6C;
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +241,7 @@ export default {
|
||||
overflow: hidden;
|
||||
margin: 10px;
|
||||
border-radius: 11px;
|
||||
box-shadow: 0 0 20px 0 rgba(0,0,0,.02);
|
||||
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.02);
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -58,11 +58,16 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('showImport', () => {
|
||||
this.dialogVisible = true
|
||||
})
|
||||
this.$bus.$on('showImport', this.handleShowImport)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('showImport', this.handleShowImport)
|
||||
},
|
||||
methods: {
|
||||
handleShowImport() {
|
||||
this.dialogVisible = true
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-08-03 22:48:42
|
||||
|
||||
@@ -44,7 +44,15 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
this.$bus.$on('node_active', this.handleNodeActive)
|
||||
this.$bus.$on('showNodeLink', this.handleShowNodeLink)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_active', this.handleNodeActive)
|
||||
this.$bus.$off('showNodeLink', this.handleShowNodeLink)
|
||||
},
|
||||
methods: {
|
||||
handleNodeActive(...args) {
|
||||
this.activeNodes = args[1]
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
@@ -54,14 +62,14 @@ export default {
|
||||
this.link = ''
|
||||
this.linkTitle = ''
|
||||
}
|
||||
})
|
||||
this.$bus.$on('showNodeLink', () => {
|
||||
},
|
||||
|
||||
handleShowNodeLink() {
|
||||
this.activeNodes[0].mindMap.keyCommand.pause()
|
||||
this.$bus.$emit('startTextEdit')
|
||||
this.dialogVisible = true
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-22 22:08:11
|
||||
|
||||
@@ -43,7 +43,15 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
this.$bus.$on('node_active', this.handleNodeActive)
|
||||
this.$bus.$on('showNodeIcon', this.handleShowNodeIcon)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_active', this.handleNodeActive)
|
||||
this.$bus.$off('showNodeIcon', this.handleShowNodeIcon)
|
||||
},
|
||||
methods: {
|
||||
handleNodeActive(...args) {
|
||||
this.activeNodes = args[1]
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
@@ -51,15 +59,15 @@ export default {
|
||||
} else {
|
||||
this.iconList = []
|
||||
}
|
||||
})
|
||||
this.$bus.$on('showNodeIcon', () => {
|
||||
},
|
||||
|
||||
handleShowNodeIcon() {
|
||||
this.dialogVisible = true
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
getHtml(icon) {
|
||||
return /^<svg/.test(icon) ? icon : `<img src="${icon}" />`
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
|
||||
@@ -1,40 +1,53 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" title="图标/贴纸">
|
||||
<div class="box" :class="{ isDark: isDark }">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="图标" name="icon"></el-tab-pane>
|
||||
<el-tab-pane label="贴纸" name="image"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="boxContent">
|
||||
<!-- 图标 -->
|
||||
<div class="iconBox" v-if="activeName === 'icon'">
|
||||
<div class="item" v-for="item in nodeIconList" :key="item.name">
|
||||
<div class="title">{{ item.name }}</div>
|
||||
<div class="list">
|
||||
<div class="icon" v-for="icon in item.list" :key="icon.name" v-html="getHtml(icon.icon)" :class="{
|
||||
selected: iconList.includes(item.type + '_' + icon.name)
|
||||
}" @click="setIcon(item.type, icon.name)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 贴纸 -->
|
||||
<div class="imageBox" v-if="activeName === 'image'">
|
||||
<div class="item" v-for="item in nodeImageList" :key="item.name">
|
||||
<div class="title">{{ item.name }}</div>
|
||||
<div class="list">
|
||||
<div class="icon" v-for="image in item.list" :key="image.url" :class="{
|
||||
selected: nodeImage === image.url
|
||||
}" @click="setImage(image)">
|
||||
<img :src="image.url" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Sidebar ref="sidebar" title="图标/贴纸">
|
||||
<div class="box" :class="{ isDark: isDark }">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="图标" name="icon"></el-tab-pane>
|
||||
<el-tab-pane label="贴纸" name="image"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="boxContent">
|
||||
<!-- 图标 -->
|
||||
<div class="iconBox" v-if="activeName === 'icon'">
|
||||
<div class="item" v-for="item in nodeIconList" :key="item.name">
|
||||
<div class="title">{{ item.name }}</div>
|
||||
<div class="list">
|
||||
<div
|
||||
class="icon"
|
||||
v-for="icon in item.list"
|
||||
:key="icon.name"
|
||||
v-html="getHtml(icon.icon)"
|
||||
:class="{
|
||||
selected: iconList.includes(item.type + '_' + icon.name)
|
||||
}"
|
||||
@click="setIcon(item.type, icon.name)"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Sidebar>
|
||||
<!-- 贴纸 -->
|
||||
<div class="imageBox" v-if="activeName === 'image'">
|
||||
<div class="item" v-for="item in nodeImageList" :key="item.name">
|
||||
<div class="title">{{ item.name }}</div>
|
||||
<div class="list">
|
||||
<div
|
||||
class="icon"
|
||||
v-for="image in item.list"
|
||||
:key="image.url"
|
||||
:class="{
|
||||
selected: nodeImage === image.url
|
||||
}"
|
||||
@click="setImage(image)"
|
||||
>
|
||||
<img :src="image.url" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Sidebar>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import Sidebar from './Sidebar'
|
||||
import { mapState } from 'vuex'
|
||||
@@ -43,204 +56,206 @@ import icon from '@/config/icon'
|
||||
import image from '@/config/image'
|
||||
|
||||
export default {
|
||||
name: 'NodeIconSidebar',
|
||||
components: {
|
||||
Sidebar
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'icon',
|
||||
nodeIconList: [...nodeIconList, ...icon],
|
||||
nodeImageList: [...image],
|
||||
iconList: [],
|
||||
nodeImage: '',
|
||||
activeNodes: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['activeSidebar', 'isDark']),
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
if (val === 'nodeIconSidebar') {
|
||||
this.$refs.sidebar.show = true
|
||||
} else {
|
||||
this.$refs.sidebar.show = false
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
this.activeNodes = args[1]
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
this.nodeImage = firstNode.getData('image')
|
||||
this.iconList = firstNode.getData('icon') || []// 回显图标
|
||||
} else {
|
||||
this.iconList = []
|
||||
this.nodeImage = ''
|
||||
}
|
||||
})
|
||||
this.$bus.$on('showNodeIcon', () => {
|
||||
this.dialogVisible = true
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 获取图标渲染方式
|
||||
getHtml(icon) {
|
||||
return /^<svg/.test(icon) ? icon : `<img src="${icon}" />`
|
||||
},
|
||||
|
||||
// 设置icon
|
||||
setIcon(type, name) {
|
||||
let key = type + '_' + name
|
||||
let index = this.iconList.findIndex(item => {
|
||||
return item === key
|
||||
})
|
||||
// 删除icon
|
||||
if (index !== -1) {
|
||||
this.iconList.splice(index, 1)
|
||||
} else {
|
||||
let typeIndex = this.iconList.findIndex(item => {
|
||||
return item.split('_')[0] === type
|
||||
})
|
||||
// 替换icon
|
||||
if (typeIndex !== -1) {
|
||||
this.iconList.splice(typeIndex, 1, key)
|
||||
} else {
|
||||
// 增加icon
|
||||
this.iconList.push(key)
|
||||
}
|
||||
}
|
||||
this.activeNodes.forEach(node => {
|
||||
node.setIcon([...this.iconList])
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
// 设置贴纸
|
||||
setImage(image) {
|
||||
this.activeNodes.forEach(node => {
|
||||
this.nodeImage = image.url
|
||||
node.setImage({
|
||||
...image
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
name: 'NodeIconSidebar',
|
||||
components: {
|
||||
Sidebar
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'icon',
|
||||
nodeIconList: [...nodeIconList, ...icon],
|
||||
nodeImageList: [...image],
|
||||
iconList: [],
|
||||
nodeImage: '',
|
||||
activeNodes: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['activeSidebar', 'isDark'])
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
if (val === 'nodeIconSidebar') {
|
||||
this.$refs.sidebar.show = true
|
||||
} else {
|
||||
this.$refs.sidebar.show = false
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_active', this.handleNodeActive)
|
||||
this.$bus.$on('showNodeIcon', this.handleShowNodeIcon)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_active', this.handleNodeActive)
|
||||
this.$bus.$off('showNodeIcon', this.handleShowNodeIcon)
|
||||
},
|
||||
methods: {
|
||||
handleNodeActive(...args) {
|
||||
this.activeNodes = args[1]
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
this.nodeImage = firstNode.getData('image')
|
||||
this.iconList = firstNode.getData('icon') || [] // 回显图标
|
||||
} else {
|
||||
this.iconList = []
|
||||
this.nodeImage = ''
|
||||
}
|
||||
},
|
||||
|
||||
handleShowNodeIcon() {
|
||||
this.dialogVisible = true
|
||||
},
|
||||
|
||||
// 获取图标渲染方式
|
||||
getHtml(icon) {
|
||||
return /^<svg/.test(icon) ? icon : `<img src="${icon}" />`
|
||||
},
|
||||
|
||||
// 设置icon
|
||||
setIcon(type, name) {
|
||||
let key = type + '_' + name
|
||||
let index = this.iconList.findIndex(item => {
|
||||
return item === key
|
||||
})
|
||||
// 删除icon
|
||||
if (index !== -1) {
|
||||
this.iconList.splice(index, 1)
|
||||
} else {
|
||||
let typeIndex = this.iconList.findIndex(item => {
|
||||
return item.split('_')[0] === type
|
||||
})
|
||||
// 替换icon
|
||||
if (typeIndex !== -1) {
|
||||
this.iconList.splice(typeIndex, 1, key)
|
||||
} else {
|
||||
// 增加icon
|
||||
this.iconList.push(key)
|
||||
}
|
||||
}
|
||||
this.activeNodes.forEach(node => {
|
||||
node.setIcon([...this.iconList])
|
||||
})
|
||||
},
|
||||
|
||||
// 设置贴纸
|
||||
setImage(image) {
|
||||
this.activeNodes.forEach(node => {
|
||||
this.nodeImage = image.url
|
||||
node.setImage({
|
||||
...image
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" scoped>
|
||||
.box {
|
||||
padding: 0 20px;
|
||||
|
||||
&.isDark {
|
||||
.title {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
padding: 0 20px;
|
||||
|
||||
&.isDark {
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.boxContent {
|
||||
.iconBox {
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
font-weight: bold;
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.boxContent {
|
||||
.iconBox {
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
font-weight: bold;
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
/deep/ img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/deep/ svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.title {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.imageBox {
|
||||
margin-bottom: 20px;
|
||||
font-weight: bold;
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.title {
|
||||
margin-bottom: 10px;
|
||||
.icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
/deep/ img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
/deep/ img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
border: 2px solid #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.imageBox {
|
||||
margin-bottom: 20px;
|
||||
font-weight: bold;
|
||||
|
||||
.title {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
/deep/ img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
border: 2px solid #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,11 +6,19 @@
|
||||
width="500"
|
||||
>
|
||||
<div class="title">方式一</div>
|
||||
<ImgUpload ref="ImgUpload" v-model="img" style="margin-bottom: 12px;"></ImgUpload>
|
||||
<ImgUpload
|
||||
ref="ImgUpload"
|
||||
v-model="img"
|
||||
style="margin-bottom: 12px;"
|
||||
></ImgUpload>
|
||||
<div class="title">方式二</div>
|
||||
<div class="inputBox">
|
||||
<span class="label">请输入图片地址</span>
|
||||
<el-input v-model="imgUrl" size="mini" placeholder="http://xxx.com/xx.jpg"></el-input>
|
||||
<el-input
|
||||
v-model="imgUrl"
|
||||
size="mini"
|
||||
placeholder="http://xxx.com/xx.jpg"
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="title">可选</div>
|
||||
<div class="inputBox">
|
||||
@@ -50,10 +58,19 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
this.$bus.$on('node_active', this.handleNodeActive)
|
||||
this.$bus.$on('showNodeImage', this.handleShowNodeImage)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_active', this.handleNodeActive)
|
||||
this.$bus.$off('showNodeImage', this.handleShowNodeImage)
|
||||
},
|
||||
methods: {
|
||||
handleNodeActive(...args) {
|
||||
this.activeNodes = args[1]
|
||||
})
|
||||
this.$bus.$on('showNodeImage', () => {
|
||||
},
|
||||
|
||||
handleShowNodeImage() {
|
||||
this.reset()
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
@@ -68,9 +85,8 @@ export default {
|
||||
this.imgTitle = firstNode.getData('imageTitle')
|
||||
}
|
||||
this.dialogVisible = true
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
cancel() {
|
||||
this.dialogVisible = false
|
||||
this.reset()
|
||||
|
||||
@@ -43,7 +43,15 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
this.$bus.$on('node_active', this.handleNodeActive)
|
||||
this.$bus.$on('showNodeNote', this.handleShowNodeNote)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_active', this.handleNodeActive)
|
||||
this.$bus.$off('showNodeNote', this.handleShowNodeNote)
|
||||
},
|
||||
methods: {
|
||||
handleNodeActive(...args) {
|
||||
this.activeNodes = args[1]
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
@@ -51,16 +59,16 @@ export default {
|
||||
} else {
|
||||
this.note = ''
|
||||
}
|
||||
})
|
||||
this.$bus.$on('showNodeNote', () => {
|
||||
},
|
||||
|
||||
handleShowNodeNote() {
|
||||
this.$bus.$emit('startTextEdit')
|
||||
this.dialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.initEditor()
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-05-09 11:37:05
|
||||
|
||||
@@ -59,7 +59,15 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
this.$bus.$on('node_active', this.handleNodeActive)
|
||||
this.$bus.$on('showNodeTag', this.handleShowNodeTag)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_active', this.handleNodeActive)
|
||||
this.$bus.$off('showNodeTag', this.handleShowNodeTag)
|
||||
},
|
||||
methods: {
|
||||
handleNodeActive(...args) {
|
||||
this.activeNodes = args[1]
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
@@ -68,13 +76,13 @@ export default {
|
||||
this.tagArr = []
|
||||
this.tag = ''
|
||||
}
|
||||
})
|
||||
this.$bus.$on('showNodeTag', () => {
|
||||
},
|
||||
|
||||
handleShowNodeTag() {
|
||||
this.$bus.$emit('startTextEdit')
|
||||
this.dialogVisible = true
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-24 21:48:14
|
||||
|
||||
@@ -73,7 +73,19 @@ export default {
|
||||
},
|
||||
created() {
|
||||
window.addEventListener('keydown', this.onKeyDown)
|
||||
this.$bus.$on('data_change', () => {
|
||||
this.$bus.$on('data_change', this.handleDataChange)
|
||||
this.$bus.$on('node_tree_render_end', this.handleNodeTreeRenderEnd)
|
||||
},
|
||||
mounted() {
|
||||
this.refresh()
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('keydown', this.onKeyDown)
|
||||
this.$bus.$off('data_change', this.handleDataChange)
|
||||
this.$bus.$off('node_tree_render_end', this.handleNodeTreeRenderEnd)
|
||||
},
|
||||
methods: {
|
||||
handleDataChange() {
|
||||
// 在大纲里操作节点时不要响应该事件,否则会重新刷新树
|
||||
if (this.notHandleDataChange) {
|
||||
this.notHandleDataChange = false
|
||||
@@ -84,8 +96,9 @@ export default {
|
||||
return
|
||||
}
|
||||
this.refresh()
|
||||
})
|
||||
this.$bus.$on('node_tree_render_end', () => {
|
||||
},
|
||||
|
||||
handleNodeTreeRenderEnd() {
|
||||
// 当前存在未完成的节点插入操作
|
||||
if (this.insertType) {
|
||||
this[this.insertType]()
|
||||
@@ -100,15 +113,8 @@ export default {
|
||||
this.afterCreateNewNode()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
this.refresh()
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('keydown', this.onKeyDown)
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
// 刷新树数据
|
||||
refresh() {
|
||||
let data = this.mindMap.getData()
|
||||
@@ -332,7 +338,8 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node__content:hover, .el-upload-list__item:hover {
|
||||
/deep/ .el-tree-node__content:hover,
|
||||
.el-upload-list__item:hover {
|
||||
background-color: hsla(0, 0%, 100%, 0.02) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
class="searchContainer"
|
||||
:class="{ isDark: isDark, show: show }"
|
||||
<div
|
||||
class="searchContainer"
|
||||
:class="{ isDark: isDark, show: show }"
|
||||
@mouseleave="onMouseleave"
|
||||
>
|
||||
<div class="closeBtnBox">
|
||||
@@ -89,16 +89,23 @@ export default {
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('show_search', this.showSearch)
|
||||
this.mindMap.on('search_info_change', data => {
|
||||
this.currentIndex = data.currentIndex + 1
|
||||
this.total = data.total
|
||||
this.showSearchInfo = true
|
||||
})
|
||||
this.mindMap.on('search_info_change', this.handleSearchInfoChange)
|
||||
this.mindMap.keyCommand.addShortcut('Control+f', this.showSearch)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('show_search', this.showSearch)
|
||||
this.mindMap.off('search_info_change', this.handleSearchInfoChange)
|
||||
this.mindMap.keyCommand.removeShortcut('Control+f', this.showSearch)
|
||||
},
|
||||
methods: {
|
||||
isUndef,
|
||||
|
||||
handleSearchInfoChange(data) {
|
||||
this.currentIndex = data.currentIndex + 1
|
||||
this.total = data.total
|
||||
this.showSearchInfo = true
|
||||
},
|
||||
|
||||
showSearch() {
|
||||
this.$bus.$emit('closeSideBar')
|
||||
this.show = true
|
||||
|
||||
@@ -49,13 +49,18 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('closeSideBar', () => {
|
||||
this.close()
|
||||
})
|
||||
this.$bus.$on('closeSideBar', this.handleCloseSidebar)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('closeSideBar', this.handleCloseSidebar)
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setActiveSidebar']),
|
||||
|
||||
handleCloseSidebar() {
|
||||
this.close()
|
||||
},
|
||||
|
||||
close() {
|
||||
this.show = false
|
||||
this.setActiveSidebar('')
|
||||
|
||||
@@ -81,15 +81,19 @@ export default {
|
||||
this.initGroup()
|
||||
this.theme = this.mindMap.getTheme()
|
||||
this.handleDark()
|
||||
|
||||
this.mindMap.on('view_theme_change', () => {
|
||||
this.theme = this.mindMap.getTheme()
|
||||
this.handleDark()
|
||||
})
|
||||
this.mindMap.on('view_theme_change', this.handleViewThemeChange)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.mindMap.off('view_theme_change', this.handleViewThemeChange)
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setIsDark']),
|
||||
|
||||
handleViewThemeChange() {
|
||||
this.theme = this.mindMap.getTheme()
|
||||
this.handleDark()
|
||||
},
|
||||
|
||||
initGroup() {
|
||||
let baiduThemes = [
|
||||
'default',
|
||||
|
||||
@@ -247,7 +247,7 @@ export default {
|
||||
this.$bus.$off('node_active', this.onNodeActive)
|
||||
this.$bus.$off('back_forward', this.onBackForward)
|
||||
this.$bus.$off('write_local_file', this.onWriteLocalFile)
|
||||
this.$bus.$on('painter_start', this.onPainterStart)
|
||||
this.$bus.$off('painter_start', this.onPainterStart)
|
||||
this.$bus.$off('painter_end', this.onPainterEnd)
|
||||
},
|
||||
methods: {
|
||||
|
||||
Reference in New Issue
Block a user