Vue使用mind-map實(shí)現(xiàn)在線思維導(dǎo)圖
概述
在本文,給大家分享一下基于mind-map
實(shí)現(xiàn)在線的思維導(dǎo)圖,并實(shí)現(xiàn):1. 導(dǎo)圖導(dǎo)出為圖片;2. 打開(kāi)xmind
文件。
實(shí)現(xiàn)效果
實(shí)現(xiàn)
1. mind-map簡(jiǎn)介
simple-mind-map
(思緒思維導(dǎo)圖)是一個(gè)簡(jiǎn)單&強(qiáng)大的Web思維導(dǎo)圖庫(kù),不依賴(lài)任何特定框架。可以幫助你快速開(kāi)發(fā)思維導(dǎo)圖產(chǎn)品。
2. 實(shí)現(xiàn)
1)添加依賴(lài)
{ "simple-mind-map": "^0.10.2-fix.1", }
2)引入插件
import MindMap from 'simple-mind-map'
3)插件導(dǎo)入
import MiniMap from 'simple-mind-map/src/plugins/MiniMap.js' import Watermark from 'simple-mind-map/src/plugins/Watermark.js' import KeyboardNavigation from 'simple-mind-map/src/plugins/KeyboardNavigation.js' import ExportPDF from 'simple-mind-map/src/plugins/ExportPDF.js' import ExportXMind from 'simple-mind-map/src/plugins/ExportXMind.js' import Export from 'simple-mind-map/src/plugins/Export.js' import Drag from 'simple-mind-map/src/plugins/Drag.js' import Select from 'simple-mind-map/src/plugins/Select.js' import AssociativeLine from 'simple-mind-map/src/plugins/AssociativeLine.js' import TouchEvent from 'simple-mind-map/src/plugins/TouchEvent.js' import NodeImgAdjust from 'simple-mind-map/src/plugins/NodeImgAdjust.js' import SearchPlugin from 'simple-mind-map/src/plugins/Search.js' import Painter from 'simple-mind-map/src/plugins/Painter.js' import Formula from 'simple-mind-map/src/plugins/Formula.js' import RainbowLines from 'simple-mind-map/src/plugins/RainbowLines.js' import Demonstrate from 'simple-mind-map/src/plugins/Demonstrate.js' import OuterFrame from 'simple-mind-map/src/plugins/OuterFrame.js' // 注冊(cè)插件 MindMap.usePlugin(MiniMap) .usePlugin(Watermark) .usePlugin(Drag) .usePlugin(KeyboardNavigation) .usePlugin(ExportPDF) .usePlugin(ExportXMind) .usePlugin(Export) .usePlugin(Select) .usePlugin(AssociativeLine) .usePlugin(NodeImgAdjust) .usePlugin(TouchEvent) .usePlugin(SearchPlugin) .usePlugin(Painter) .usePlugin(Formula) .usePlugin(RainbowLines) .usePlugin(Demonstrate) .usePlugin(OuterFrame)
4)自定義主題
import cactus from './themes/cactus' import classic5 from './themes/classic5' import classic6 from './themes/classic6' import classic7 from './themes/classic7' import dark3 from './themes/dark3' import dark4 from './themes/dark4' import darkNightLceBlade from './themes/darkNightLceBlade' import index from './themes/index' import lemonBubbles from './themes/lemonBubbles' import morandi from './themes/morandi' import neonLamp from './themes/neonLamp' import oreo from './themes/oreo' import rose from './themes/rose' import seaBlueLine from './themes/seaBlueLine' import shallowSea from './themes/shallowSea' MindMap.defineTheme('cactus', cactus) MindMap.defineTheme('classic5', classic5) MindMap.defineTheme('classic6', classic6) MindMap.defineTheme('classic7', classic7) MindMap.defineTheme('dark3', dark3) MindMap.defineTheme('dark4', dark4) MindMap.defineTheme('darkNightLceBlade', darkNightLceBlade) MindMap.defineTheme('index', index) MindMap.defineTheme('lemonBubbles', lemonBubbles) MindMap.defineTheme('morandi', morandi) MindMap.defineTheme('neonLamp', neonLamp) MindMap.defineTheme('oreo', oreo) MindMap.defineTheme('rose', rose) MindMap.defineTheme('seaBlueLine', seaBlueLine) MindMap.defineTheme('shallowSea', shallowSea)
5)引入圖標(biāo)
import {<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E--> nodeIconList } from 'simple-mind-map/src/svg/icons'
6)導(dǎo)出圖片
mindMapInstance.export('png', true, this.name)
7)打開(kāi)xmind文件
import xmind from 'simple-mind-map/src/parse/xmind.js' { methods:{ ElMessageBox.confirm('是否直接替換當(dāng)前思維導(dǎo)圖?', '警告', { confirmButtonText: '確認(rèn)', cancelButtonText: '取消', type: 'warning', }) .then(() => { const { raw } = file xmind.parseXmindFile(raw).then(data => { that.setData(data) }) }) .catch(() => {}) } }
完整代碼如下:
<template> <div class="mind-map-container"> <div class="mindmap-tools" v-show="!readonly"> <el-upload ref="upload" style="margin-right: 0.8rem" :limit="1" :on-change="handleChange" :show-file-list="false" :accept="'.xmind'" :auto-upload="false" > <template #trigger> <el-button class="my-button" size="small"> <div class="my-button"> <svg t="1720518684993" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29039" width="32" height="32" > <path d="M910.19 175.16L776.1 41.07A136.94 136.94 0 0 0 679.27 1H235A161.29 161.29 0 0 0 73.69 162.25v699.5A161.29 161.29 0 0 0 235 1023h554a161.29 161.29 0 0 0 161.31-161.25V272a136.89 136.89 0 0 0-40.12-96.84z m-148.8 459.72c-1.53 8-14.94 8.24-36.72 11.59s-95.51 17.6-103 17.6-12.56-11.31-13.4-14.66-9.35-33.24-20.53-46.92-49.74-54.17-112.86-51.66-68.14 49.57-69.82 64.65 2.52 30.16-10.89 32.67-103 19.27-109.33 19.69-11.31-4.19-10.89-20.11 6.28-45.24 31.84-65.35 93.83-48.17 100.95-52.38 10.47-7.54 8-13.82-46.54-21.76-65.39-30.18-54.45-26-71.21-54.87-17.59-42.73-15.08-46.92S274 378 274 378s125.67-23 131.53-21.78 16.76 39.37 20.94 47.33 30.16 61.58 93.42 58.64 52.78-41 49.42-53-8.16-22.44-1.46-25.8 108.28-20.52 115.4-19.68 19.27 4.47 18.71 31.83-6.56 46.92-27.93 60.32-65.48 19.55-68.13 26.39 5.58 12.43 25.41 21.36 72.88 36 88.8 51.67 46.59 56.43 41.28 79.6z" p-id="29040" fill="currentColor" ></path> </svg> <div>打開(kāi)xmind文件</div> </div> </el-button> </template> </el-upload> <el-button :disabled="activeNodes.length === 0" class="my-button" size="small" @click="addNode" > <div class="my-button"> <svg t="1719284042715" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="32998" width="32" height="32" > <path d="M510.833431 62.695924c-247.644193 0-448.406636 200.762443-448.406636 448.406636 0 247.65545 200.762443 448.416869 448.406636 448.416869 247.65545 0 448.416869-200.76142 448.416869-448.416869C959.2503 263.458367 758.488881 62.695924 510.833431 62.695924zM779.544429 562.112328 560.358381 562.112328l0 219.186048-102.008278 0L458.350103 562.112328 239.164055 562.112328l0-102.008278 219.186048 0L458.350103 240.918002l102.008278 0 0 219.186048 219.186048 0L779.544429 562.112328z" fill="currentColor" p-id="32999" ></path> </svg> <div>添加同級(jí)節(jié)點(diǎn)</div> </div> </el-button> <el-button :disabled="activeNodes.length === 0" class="my-button" size="small" @click="addChildNode" > <div class="my-button"> <svg t="1719283662028" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23087" width="32" height="32" > <path d="M739.555556 0a56.888889 56.888889 0 0 1 56.888888 56.888889v227.555555a56.888889 56.888889 0 0 1-56.888888 56.888889H227.555556v455.111111h170.666666v-56.888888a56.888889 56.888889 0 0 1 56.888889-56.888889h512a56.888889 56.888889 0 0 1 56.888889 56.888889v227.555555a56.888889 56.888889 0 0 1-56.888889 56.888889H455.111111a56.888889 56.888889 0 0 1-56.888889-56.888889v-56.888889H170.666667a56.888889 56.888889 0 0 1-56.888889-56.888889V341.333333H56.888889a56.888889 56.888889 0 0 1-56.888889-56.888889V56.888889a56.888889 56.888889 0 0 1 56.888889-56.888889h682.666667z" fill="currentColor" p-id="23088" ></path> </svg> <div>添加子節(jié)點(diǎn)</div> </div> </el-button> <el-button :disabled="activeNodes.length === 0" class="my-button" size="small" @click="dropNode" > <div class="my-button"> <svg t="1719283698787" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="24126" width="32" height="32" > <path d="M316.652201 74.043048L339.889115 28.356912A53.16921 53.16921 0 0 1 386.756789 0h250.486058a53.16921 53.16921 0 0 1 46.867674 28.356912l23.236914 45.686136a53.16921 53.16921 0 0 0 47.261521 28.356913h177.624547A51.987672 51.987672 0 0 1 984.615021 153.599941a51.987672 51.987672 0 0 1-52.381518 51.19998H91.766134A51.987672 51.987672 0 0 1 39.384615 153.599941a51.987672 51.987672 0 0 1 52.381519-51.19998h177.624547a53.16921 53.16921 0 0 0 47.26152-28.356913z m-118.153801 181.956854h630.153604a51.593826 51.593826 0 0 1 52.381518 51.19998v614.399764a101.218423 101.218423 0 0 1-30.719988 72.467664 105.944575 105.944575 0 0 1-74.043048 29.932296H250.879919a105.944575 105.944575 0 0 1-74.043049-29.932296 101.218423 101.218423 0 0 1-30.719988-72.467664V307.199882A51.593826 51.593826 0 0 1 196.923016 255.999902z m52.381519 153.59994v460.799823a51.987672 51.987672 0 0 0 52.775364 51.199981h419.839838a51.987672 51.987672 0 0 0 52.775365-51.199981V409.599842a51.987672 51.987672 0 0 0-52.775365-51.19998H303.655283a51.987672 51.987672 0 0 0-54.350748 51.19998z m157.538401 51.199981a51.987672 51.987672 0 0 1 52.775364 51.19998v255.999902a51.987672 51.987672 0 0 1-52.775364 51.19998 51.987672 51.987672 0 0 1-52.381519-51.19998V511.999803a51.987672 51.987672 0 0 1 50.806135-51.19998z m210.313765 0a51.987672 51.987672 0 0 1 52.381518 51.19998v255.999902a51.987672 51.987672 0 0 1-52.381518 51.19998 51.987672 51.987672 0 0 1-52.775364-51.19998V511.999803a51.987672 51.987672 0 0 1 51.19998-51.19998z" p-id="24127" fill="currentColor" ></path> </svg> <div>刪除節(jié)點(diǎn)</div> </div> </el-button> <el-button :disabled="activeNodes.length === 0" class="my-button" size="small" @click="addGeneralization" > <div class="my-button"> <svg t="1719283740026" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26481" width="32" height="32" > <path d="M128 576h416a64 64 0 0 1 64 64v192a64 64 0 0 1-64 64H128a64 64 0 0 1-64-64v-192a64 64 0 0 1 64-64z m32 64h352a32 32 0 0 1 32 32v128a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32v-128a32 32 0 0 1 32-32zM128 128h416a64 64 0 0 1 64 64v192a64 64 0 0 1-64 64H128a64 64 0 0 1-64-64V192a64 64 0 0 1 64-64z m766.56 415.968A352.16 352.16 0 0 1 704 825.632c-23.68 3.52-35.52-7.2-35.52-32.224 0-15.584 11.84-29.568 35.52-41.92A287.712 287.712 0 0 0 832 512c0-99.84-50.816-187.84-128-239.488-23.68-14.848-35.52-29.536-35.52-44.064 0-25.568 11.84-35.584 35.52-30.08a352.16 352.16 0 0 1 190.56 281.664L896 480h32a32 32 0 0 1 0 64h-32l-1.44-0.032zM160 192h352a32 32 0 0 1 32 32v128a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32V224a32 32 0 0 1 32-32z" fill="currentColor" p-id="26482" ></path> </svg> <div>添加概要</div> </div> </el-button> <el-button class="my-button" size="small" @click="exportPng"> <div class="my-button"> <svg t="1719283812353" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="28576" width="32" height="32" > <path d="M896.341333 128c23.381333 0 42.325333 18.986667 42.325334 42.368v398.890667A255.573333 255.573333 0 0 0 853.333333 554.666667V213.333333H170.666667l0.042666 597.333334 396.458667-396.501334a42.624 42.624 0 0 1 56.32-3.584l3.968 3.626667 151.296 151.466667a256.128 256.128 0 0 0-166.826667 330.368L127.658667 896A42.368 42.368 0 0 1 85.333333 853.632V170.368A42.666667 42.666667 0 0 1 127.658667 128h768.682666zM341.333333 298.666667a85.333333 85.333333 0 1 1 0 170.666666 85.333333 85.333333 0 0 1 0-170.666666z m512 469.333333v-128l170.666667 170.666667-170.666667 170.666666v-128h-170.666666v-85.333333h170.666666z" fill="currentColor" p-id="28577" ></path> </svg> <div>導(dǎo)出圖片</div> </div> </el-button> <el-button :disabled="activeNodes.length === 0" :type="activedPanel === 'icon' ? 'primary' : 'default'" class="my-button" size="small" @click="activePanel('icon')" > <div class="my-button"> <svg t="1719283775623" class="icon" viewBox="0 0 1026 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="27549" width="32" height="32" > <path d="M495.465 830.665c-187.138 0-264.948-168.222-268.193-175.401l62.966-28.307c2.486 5.49 62.207 134.667 205.194 134.667 153.067-1.795 211.302-129.213 213.685-134.633l63.103 27.996c-3.141 7.077-79.054 173.364-273.13 175.643l-3.625 0.034zM500.16 991.221c-256.974 0-466.034-209.060-466.034-466.034s209.060-466.034 466.034-466.034 466.034 209.060 466.034 466.034-209.060 466.034-466.034 466.034zM500.16 128.196c-218.897 0-396.991 178.094-396.991 396.991s178.094 396.991 396.991 396.991 396.991-178.094 396.991-396.991-178.059-396.991-396.991-396.991zM311.088 444.27c0 29.689 24.062 53.818 53.818 53.818s53.818-24.096 53.818-53.818-24.062-53.818-53.818-53.818-53.818 24.096-53.818 53.818zM580.765 444.27c0 29.689 24.062 53.818 53.818 53.818s53.818-24.096 53.818-53.818-24.062-53.818-53.818-53.818-53.818 24.096-53.818 53.818z" fill="currentColor" p-id="27550" ></path> </svg> <div>設(shè)置圖標(biāo)</div> </div> </el-button> <el-button :type="activedPanel === 'theme' ? 'primary' : 'default'" class="my-button" size="small" @click="activePanel('theme')" > <div class="my-button"> <svg t="1719283846317" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29654" width="32" height="32" > <path d="M772.8 96v64L936 321.6l-91.2 91.2c-12.8-11.2-27.2-16-43.2-16-36.8 0-65.6 28.8-65.6 65.6V800c0 35.2-28.8 64-64 64H352c-35.2 0-64-28.8-64-64V462.4c0-36.8-28.8-65.6-65.6-65.6-16 0-32 6.4-43.2 16L88 321.6 249.6 160h40l1.6 1.6C336 228.8 420.8 272 512 272c91.2 0 176-41.6 220.8-110.4 0-1.6 1.6-1.6 1.6-1.6h38.4V96m-481.6 0H256c-22.4 0-38.4 6.4-49.6 19.2L43.2 276.8c-25.6 25.6-25.6 65.6 0 89.6l94.4 94.4c11.2 11.2 27.2 17.6 41.6 17.6s30.4-6.4 41.6-17.6h1.6c1.6 0 1.6 0 1.6 1.6V800c0 70.4 57.6 128 128 128h320c70.4 0 128-57.6 128-128V462.4c0-1.6 0-1.6 1.6-1.6h1.6c11.2 11.2 27.2 17.6 41.6 17.6 16 0 30.4-6.4 41.6-17.6l94.4-94.4c25.6-25.6 25.6-65.6 0-89.6L819.2 115.2C806.4 102.4 790.4 96 772.8 96h-40c-22.4 0-41.6 11.2-54.4 30.4-33.6 49.6-96 81.6-168 81.6s-134.4-33.6-168-81.6C332.8 107.2 312 96 291.2 96z" fill="currentColor" p-id="29655" ></path> </svg> <div>選擇主題</div> </div> </el-button> <el-button :type="activedPanel === 'layout' ? 'primary' : 'default'" class="my-button" size="small" @click="activePanel('layout')" > <div class="my-button"> <svg t="1719283873990" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="30805" width="32" height="32" > <path d="M938.666667 640h-64v-42.666667c0-72.533333-55.466667-128-128-128H554.666667V384h64c46.933333 0 85.333333-38.4 85.333333-85.333333V85.333333c0-46.933333-38.4-85.333333-85.333333-85.333333h-213.333334c-46.933333 0-85.333333 38.4-85.333333 85.333333v213.333334c0 46.933333 38.4 85.333333 85.333333 85.333333H469.333333v85.333333H277.333333c-72.533333 0-128 55.466667-128 128v29.866667c0 4.266667 0 8.533333 4.266667 12.8H85.333333c-46.933333 0-85.333333 38.4-85.333333 85.333333v213.333334c0 46.933333 38.4 85.333333 85.333333 85.333333h213.333334c46.933333 0 85.333333-38.4 85.333333-85.333333v-213.333334c0-46.933333-38.4-85.333333-85.333333-85.333333H230.4c0-4.266667 4.266667-8.533333 4.266667-12.8V597.333333c0-25.6 17.066667-42.666667 42.666666-42.666666h469.333334c25.6 0 42.666667 17.066667 42.666666 42.666666v42.666667H725.333333c-46.933333 0-85.333333 38.4-85.333333 85.333333v213.333334c0 46.933333 38.4 85.333333 85.333333 85.333333h213.333334c46.933333 0 85.333333-38.4 85.333333-85.333333v-213.333334c0-46.933333-38.4-85.333333-85.333333-85.333333zM298.666667 725.333333v213.333334H85.333333v-213.333334h213.333334zM405.333333 298.666667V85.333333h213.333334v213.333334h-213.333334zM938.666667 938.666667h-213.333334v-213.333334h213.333334v213.333334z" fill="currentColor" p-id="30806" ></path> </svg> <div>選擇結(jié)構(gòu)</div> </div> </el-button> </div> <div id="mindMapContainer" @dragenter.stop.prevent @dragleave.stop.prevent @dragover.stop.prevent @drop.stop.prevent ></div> <div class="active-panel" v-show="!readonly && activedPanel !== ''"> <!-- 圖標(biāo) --> <div class="active-panel-box" v-if="activedPanel === 'icon'"> <div class="title"> 選擇圖標(biāo) <span class="close" @click="activedPanel = ''">×</span> </div> <div class="content icon"> <div class="icon-group" v-for="group of nodeIconList" :key="group.type"> <div class="group-title"> {{ group.name }} </div> <div class="group-content"> <span class="icon-item" :class="activeNodes.length === 0 ? 'disabled' : ''" v-for="icon of group.list" :key="icon.name" @click="setIcon(group.type, icon.name)" v-html="icon.icon" ></span> </div> </div> </div> </div> <!-- 主題 --> <div class="active-panel-box" v-else-if="activedPanel === 'theme'"> <div class="title"> 選擇主題 <span class="close" @click="activedPanel = ''">×</span> </div> <div class="content"> <li v-for="item of themes" :key="item.value" @click="changeTheme(item.value)" :class="theme === item.value ? 'active' : ''" > <img :src="`/pages/online-doc/icons/theme/${item.value}.jpg`" /> <div>{{ item.label }}</div> </li> </div> </div> <!-- 結(jié)構(gòu) --> <div class="active-panel-box" v-else-if="activedPanel === 'layout'"> <div class="title"> 選擇結(jié)構(gòu) <span class="close" @click="activedPanel = ''">×</span> </div> <div class="content"> <li v-for="item of layouts" :key="item.value" @click="changeLayout(item.value)" :class="layout === item.value ? 'active' : ''" > <img :src="`/pages/online-doc/icons/layout/${item.value}.png`" /> <div>{{ item.label }}</div> </li> </div> </div> </div> </div> <div class="mind-map-scale"> <el-button text @click="zoomOut"> <span style="font-size: 1.2rem; font-weight: bold">─</span> </el-button> <el-input style="display: inline-block; width: 50px; text-align: center" v-model="showScale" disabled /> <el-button text @click="zoomIn"><span style="font-size: 1.2rem">+</span></el-button> </div> </template> <script> import MindMap from 'simple-mind-map' import MiniMap from 'simple-mind-map/src/plugins/MiniMap.js' import Watermark from 'simple-mind-map/src/plugins/Watermark.js' import KeyboardNavigation from 'simple-mind-map/src/plugins/KeyboardNavigation.js' import ExportPDF from 'simple-mind-map/src/plugins/ExportPDF.js' import ExportXMind from 'simple-mind-map/src/plugins/ExportXMind.js' import Export from 'simple-mind-map/src/plugins/Export.js' import Drag from 'simple-mind-map/src/plugins/Drag.js' import Select from 'simple-mind-map/src/plugins/Select.js' import AssociativeLine from 'simple-mind-map/src/plugins/AssociativeLine.js' import TouchEvent from 'simple-mind-map/src/plugins/TouchEvent.js' import NodeImgAdjust from 'simple-mind-map/src/plugins/NodeImgAdjust.js' import SearchPlugin from 'simple-mind-map/src/plugins/Search.js' import Painter from 'simple-mind-map/src/plugins/Painter.js' import Formula from 'simple-mind-map/src/plugins/Formula.js' import RainbowLines from 'simple-mind-map/src/plugins/RainbowLines.js' import Demonstrate from 'simple-mind-map/src/plugins/Demonstrate.js' import OuterFrame from 'simple-mind-map/src/plugins/OuterFrame.js' import { nodeIconList } from 'simple-mind-map/src/svg/icons' import { ElMessageBox } from 'element-plus' import xmind from 'simple-mind-map/src/parse/xmind.js' import cactus from './themes/cactus' import classic5 from './themes/classic5' import classic6 from './themes/classic6' import classic7 from './themes/classic7' import dark3 from './themes/dark3' import dark4 from './themes/dark4' import darkNightLceBlade from './themes/darkNightLceBlade' import index from './themes/index' import lemonBubbles from './themes/lemonBubbles' import morandi from './themes/morandi' import neonLamp from './themes/neonLamp' import oreo from './themes/oreo' import rose from './themes/rose' import seaBlueLine from './themes/seaBlueLine' import shallowSea from './themes/shallowSea' // 注冊(cè)插件 MindMap.usePlugin(MiniMap) .usePlugin(Watermark) .usePlugin(Drag) .usePlugin(KeyboardNavigation) .usePlugin(ExportPDF) .usePlugin(ExportXMind) .usePlugin(Export) .usePlugin(Select) .usePlugin(AssociativeLine) .usePlugin(NodeImgAdjust) .usePlugin(TouchEvent) .usePlugin(SearchPlugin) .usePlugin(Painter) .usePlugin(Formula) .usePlugin(RainbowLines) .usePlugin(Demonstrate) .usePlugin(OuterFrame) MindMap.defineTheme('cactus', cactus) MindMap.defineTheme('classic5', classic5) MindMap.defineTheme('classic6', classic6) MindMap.defineTheme('classic7', classic7) MindMap.defineTheme('dark3', dark3) MindMap.defineTheme('dark4', dark4) MindMap.defineTheme('darkNightLceBlade', darkNightLceBlade) MindMap.defineTheme('index', index) MindMap.defineTheme('lemonBubbles', lemonBubbles) MindMap.defineTheme('morandi', morandi) MindMap.defineTheme('neonLamp', neonLamp) MindMap.defineTheme('oreo', oreo) MindMap.defineTheme('rose', rose) MindMap.defineTheme('seaBlueLine', seaBlueLine) MindMap.defineTheme('shallowSea', shallowSea) let mindMapInstance = null window.mindMapInstance = mindMapInstance export const defaultData = { data: { text: '根節(jié)點(diǎn)', expand: true, isActive: true, }, children: [], } export default { props: { readonly: { type: Boolean, default: false, }, name: { type: String, default: '思維導(dǎo)圖', }, mindData: { type: Object, default() { return defaultData }, }, }, data() { return { nodeIconList, scale: 1, theme: 'classic4', // default(默認(rèn))、classic(腦圖經(jīng)典)、minions(小黃人)、 // pinkGrape(粉紅葡萄)、mint(薄荷)、gold(金色vip)、vitalityOrange(活力橙)、 // greenLeaf(綠葉)、dark2(暗色2)、skyGreen(天清綠)、classic2(腦圖經(jīng)典2)、 // classic3(腦圖經(jīng)典3)、classic4(腦圖經(jīng)典4,v0.2.0+)、classicGreen(經(jīng)典綠)、 // classicBlue(經(jīng)典藍(lán))、blueSky(天空藍(lán))、brainImpairedPink(腦殘粉)、 // dark(暗色)、earthYellow(泥土黃)、freshGreen(清新綠)、freshRed(清新紅)、 // romanticPurple(浪漫紫)、simpleBlack(v0.5.4+簡(jiǎn)約黑)、courseGreen(v0.5.4+課程綠)、 // coffee(v0.5.4+咖啡)、redSpirit(v0.5.4+紅色精神)、blackHumour(v0.5.4+黑色幽默)、 // lateNightOffice(v0.5.4+深夜辦公室)、blackGold(v0.5.4+黑金)、avocado(v.5.10-fix.2+牛油果)、 // autumn(v.5.10-fix.2+秋天)、orangeJuice(v.5.10-fix.2+橙汁) themes: [ { value: 'classic4', label: '腦圖經(jīng)典4' }, { value: 'classic5', label: '腦圖經(jīng)典5' }, { value: 'classic6', label: '腦圖經(jīng)典6' }, { value: 'classic7', label: '腦圖經(jīng)典7' }, { value: 'autumn', label: '秋天' }, { value: 'cactus', label: '仙人掌' }, { value: 'lemonBubbles', label: '檸檬氣泡' }, { value: 'coffee', label: '咖啡' }, { value: 'courseGreen', label: '課程綠' }, { value: 'gold', label: '金色vip' }, { value: 'greenLeaf', label: '綠葉' }, { value: 'minions', label: '小黃人' }, { value: 'morandi', label: '莫蘭迪' }, { value: 'redSpirit', label: '紅色精神' }, { value: 'simpleBlack', label: '簡(jiǎn)約黑' }, { value: 'vitalityOrange', label: '活力橙' }, { value: 'oreo', label: '奧利奧' }, { value: 'rose', label: '玫瑰' }, { value: 'seaBlueLine', label: '海藍(lán)線' }, { value: 'shallowSea', label: '淺海' }, ], layout: 'mindMap', layouts: [ { value: 'mindMap', label: '思維導(dǎo)圖' }, { value: 'logicalStructure', label: '邏輯結(jié)構(gòu)圖' }, { value: 'organizationStructure', label: '組織結(jié)構(gòu)圖' }, { value: 'catalogOrganization', label: '目錄組織圖' }, { value: 'timeline', label: '時(shí)間軸' }, { value: 'timeline2', label: '時(shí)間軸2' }, { value: 'fishbone', label: '魚(yú)骨圖' }, { value: 'verticalTimeline', label: '垂直時(shí)間軸' }, ], activeNodes: [], currentIconList: [], activedPanel: '', } }, computed: { showScale() { return (this.scale * 100).toFixed(0) }, }, mounted() { this.init() }, unmounted() { mindMapInstance.destroy() }, watch: { mindData() { mindMapInstance.destroy() this.init() }, }, methods: { handleChange(file) { const that = this ElMessageBox.confirm('是否直接替換當(dāng)前思維導(dǎo)圖?', '警告', { confirmButtonText: '確認(rèn)', cancelButtonText: '取消', type: 'warning', }) .then(() => { const { raw } = file xmind.parseXmindFile(raw).then(data => { that.setData(data) }) }) .catch(() => {}) }, activePanel(type) { this.activedPanel = type === this.activedPanel ? '' : type }, setIcon(type, name) { if (this.activeNodes.length === 0) return let key = type + '_' + name // 檢查當(dāng)前節(jié)點(diǎn)是否存在該圖標(biāo) let index = this.currentIconList.findIndex(item => { return item === key }) // 存在則刪除icon if (index !== -1) { this.currentIconList.splice(index, 1) } else { // 否則判斷當(dāng)前圖標(biāo)是否和要插入的圖標(biāo)是一個(gè)組的 let typeIndex = this.currentIconList.findIndex(item => { return item.split('_')[0] === type }) // 是一個(gè)組的則進(jìn)行替換 if (typeIndex !== -1) { this.currentIconList.splice(typeIndex, 1, key) } else { // 否則添加icon this.currentIconList.push(key) } } this.activeNodes.forEach(node => { node.setIcon([...this.currentIconList]) }) }, addRelationLine() { mindMapInstance.createLineFromActiveNode() }, addGeneralization() { mindMapInstance.execCommand('ADD_GENERALIZATION') }, dropNode() { mindMapInstance.execCommand('REMOVE_NODE') }, addNode() { mindMapInstance.execCommand('INSERT_NODE') }, addChildNode() { mindMapInstance.execCommand('INSERT_CHILD_NODE') }, changeTheme(theme) { this.theme = theme mindMapInstance.setTheme(theme) }, changeLayout(layout) { this.layout = layout mindMapInstance.setLayout(layout) }, zoomMap(e) { mindMapInstance.view.setScale(e) }, zoomIn() { let scale = mindMapInstance.view.scale scale += 0.2 if (scale > 2) scale = 2 mindMapInstance.view.setScale(scale) }, zoomOut() { let scale = mindMapInstance.view.scale scale -= 0.2 if (scale < 0.1) scale = 0.1 mindMapInstance.view.setScale(scale) }, getData() { return mindMapInstance.getData(true) }, setData(data) { mindMapInstance.setData(data) }, exportPng() { mindMapInstance.export('png', true, this.name) }, init() { const data = this.mindData || defaultData let mindData = data if (data.root) { this.layout = data.layout this.theme = data.theme.template mindData = data.root } mindMapInstance = new MindMap({ enableFreeDrag: false, readonly: this.readonly, layout: this.layout, // 'logicalStructure', theme: this.theme, el: document.getElementById('mindMapContainer'), mousewheelAction: 'zoom', // zoom(放大縮?。?、move(上下移動(dòng)) data: mindData, fit: true, nodeTextEditZIndex: 1000, nodeNoteTooltipZIndex: 1000, initRootNodePosition: ['center', 'center'], }) mindMapInstance.on('scale', e => { this.scale = Number(e.toFixed(2)) }) mindMapInstance.on('node_active', (...args) => { this.activeNodes = args[1] if (this.activeNodes.length > 0) { let firstNode = this.activeNodes[0] this.currentIconList = firstNode.getData('icon') || [] } else { this.currentIconList = [] } }) }, }, } </script> <style lang="scss" scoped> .mind-map-container, #mindMapContainer { width: 100%; height: 100%; overflow: hidden; position: relative; } .my-button { svg { width: 1.5rem; height: 1.5rem; } width: 6rem; height: 3.8rem; text-align: center; line-height: 1.5rem; margin-top: 0.8rem; } .mindmap-tools { position: absolute; top: 10px; right: 10px; z-index: 1000; display: flex; flex-direction: row; justify-content: center; width: 100%; align-items: center; } $iconSize: 1.4rem; .active-panel { position: absolute; top: 10rem; right: 5px; bottom: 10rem; width: 16rem; background: white; user-select: none; .active-panel-box { height: 100%; .title { height: 3rem; line-height: 3rem; padding: 0 0.8rem; font-weight: bold; font-size: 1.1rem; border-bottom: 1px solid #ccc; .close { float: right; cursor: pointer; font-size: 1.3rem; } } .content { height: calc(100% - 3rem); overflow-y: auto; overflow-x: hidden; padding: 1rem; &.icon { padding-right: 0.5rem; } .icon-group { margin-top: 1rem; line-height: 2; &:first-child { margin-top: 0; } } .group-title { font-weight: bold; } .group-content { display: flex; flex-direction: row; flex-wrap: wrap; .icon-item { width: $iconSize; height: $iconSize; margin-right: 0.4rem; margin-top: 0.4rem; cursor: pointer; &.disabled { cursor: not-allowed; opacity: 0.5; } svg { width: $iconSize; height: $iconSize; } } } li { list-style: none; text-align: center; margin-top: 1rem; border: 1px solid #ccc; border-radius: 4px; &:first-child { margin-top: 0; } &:hover { cursor: pointer; box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.2); } &.active { border: 1px solid #67c23a; box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.2); } img { width: 100%; height: 8rem; } } } } } .mind-map-scale { position: absolute; bottom: -1rem; right: 1rem; z-index: 99; background: #efefef; border-radius: 5px; opacity: 0.8; } :deep .mind-map-scale { .el-input__wrapper .el-input__inner { text-align: center !important; } } </style>
以上就是Vue使用mind-map實(shí)現(xiàn)在線思維導(dǎo)圖的詳細(xì)內(nèi)容,更多關(guān)于Vue mind-map思維導(dǎo)圖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
html+vue.js 實(shí)現(xiàn)漂亮分頁(yè)功能可兼容IE
功能比較簡(jiǎn)單,在單一html中使用vue.js分頁(yè)展示數(shù)據(jù),并未安裝腳手架,或使用相關(guān)UI框架,此時(shí)需要手寫(xiě)一個(gè)分頁(yè)器,不失為最合理最便捷的解決方案,需要的朋友可以參考下2020-11-11vue利用v-for嵌套輸出多層對(duì)象,分別輸出到個(gè)表的方法
今天小編就為大家分享一篇vue利用v-for嵌套輸出多層對(duì)象,分別輸出到個(gè)表的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue-router跳轉(zhuǎn)時(shí)打開(kāi)新頁(yè)面的兩種方法
這篇文章主要給大家介紹了關(guān)于vue-router跳轉(zhuǎn)時(shí)打開(kāi)新頁(yè)面的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue-router具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07詳解VScode編輯器vue環(huán)境搭建所遇問(wèn)題解決方案
這篇文章主要介紹了VScode編輯器vue環(huán)境搭建所遇問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Vue.js 實(shí)現(xiàn)微信公眾號(hào)菜單編輯器功能(二)
這篇文章主要介紹了Vue.js 實(shí)現(xiàn)微信公眾號(hào)菜單編輯器功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-05-05Vue源碼解析之?dāng)?shù)組變異的實(shí)現(xiàn)
這篇文章主要介紹了Vue源碼解析之?dāng)?shù)組變異的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12vue3?setup語(yǔ)法糖中獲取slot插槽的dom對(duì)象代碼示例
slot元素是一個(gè)插槽出口,標(biāo)示了父元素提供的插槽內(nèi)容將在哪里被渲染,這篇文章主要給大家介紹了關(guān)于vue3?setup語(yǔ)法糖中獲取slot插槽的dom對(duì)象的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04