项目需要 思维导图这个功能,暂时还不知道具体需要什么功能,就自己先搞了一下,简单实现节点添加 编辑  删除 拖拽 及下载导图等功能,还有鼠标右键点击节点出现自定义菜单的功能,看了好多的自己以及其他人写的,发现很多都是有缺失的,不能拿来直接使用,下面我总结了一下,可以直接复制使用。

(注:jsmind.menu.js 引用一定要放到 jsmind后面)

按钮事件  或者 鼠标右键按钮事件 可二选一选用,废话不多说 直接上代码

<template><div class="brain_content"><div class="header_btn"><el-button @click='zoomOut' ref="zoomOut">缩小</el-button><el-button @click='zoomIn' ref="zoomIn">放大</el-button><el-button @click="addNode">添加节点</el-button><el-button @click="onRemoveNode">删除节点</el-button></div><js-mind class="js_mind" :options="options" :values="mind" v-show="isShow" ref="jsMind" height="100%"></js-mind></div>
</template><script>
import Vue from 'vue'
import jm from "vue-jsmind"
import '../../../../../public/static/js/jsmind.menu.js'Vue.use(jm)
if (window.jsMind) {console.log('wind')Vue.prototype.jsMind = window.jsMind
}
export default {data () {return {drawer: false,direction: 'rtl',theme_value: '',mind: {meta: {/* 元数据,定义思维导图的名称、作者、版本等信息 */name: 'ztengluo',author: 'hizzgdev@163.com',version: '0.2'},format: 'node_tree',data: {id: 'root',topic: '三国',children: [{id: 'easy', // [必选] ID, 所有节点的ID不应有重复,否则ID重复的结节将被忽略topic: '魏', // [必选] 节点上显示的内容direction: 'left', // [可选] 节点的方向,此数据仅在第一层节点上有效,目前仅支持 left 和 right 两种,默认为 rightexpanded: true, // [可选] 该节点是否是展开状态,默认为 truechildren: [{ id: 'easy1', topic: '曹操' },{ id: 'easy2', topic: '张辽' },{ id: 'easy3', topic: '司马懿' },{ id: 'easy4', topic: '司马昭' },{ id: 'easy5', topic: '邓艾' },{ id: 'easy6', topic: '夏侯淳' },]},{id: 'open',topic: '蜀',direction: 'right',expanded: true,children: [{ id: 'open1', topic: '刘备',children: [{ id: 'open2', topic: '文',children: [{ id: 'open3', topic: '诸葛亮' },{ id: 'open4', topic: '徐庶' },]},{ id: 'open5', topic: '武',children: [{ id: 'open6', topic: '黄忠' },{ id: 'open7', topic: '马超' },{ id: 'open8', topic: '姜维' },{ id: 'open9', topic: '张飞' },{ id: 'open10', topic: '赵云' },]},]},]},{id: 'powerful',topic: '吴',direction: 'right',children: [{ id: 'powerful1', topic: '孙策' },{ id: 'powerful2', topic: '孙权' },{ id: 'powerful3', topic: '周瑜' },{ id: 'powerful4', topic: '鲁肃' },{ id: 'powerful5', topic: '吕蒙' },{ id: 'powerful6', topic: '黄盖' },]}]}},options: {container: 'jsmind_container', // [必选] 容器的IDeditable: false, // [可选] 是否启用编辑theme: 'clouds', // [可选] 主题support_html : true,    // 是否支持节点里的HTML元素view:{engine: 'canvas',   // 思维导图各节点之间线条的绘制引擎hmargin:100,        // 思维导图距容器外框的最小水平距离vmargin:50,         // 思维导图距容器外框的最小垂直距离line_width:1,       // 思维导图线条的粗细line_color:'#C18AFB'   // 思维导图线条的颜色},menuOpts:{showMenu: true,injectionList: [{target:'edit',text: '编辑节点',callback: function (node) {console.log(node)}},{target:'addChild',text: '添加子节点',callback: function (node) {console.log(node)}},{target:'addBrother',text: '添加兄弟节点',callback: function (node) {console.log(node)}},{target:'delete',text: '删除节点',callback: function (node,next) {console.log(node)}},{target:'screenshot',text: '下载导图',callback: function (node,next) {console.log(node)}},{target:'showAll',text: '展开全部节点',callback: function (node,next) {console.log(node)}},{target:'hideAll',text: '收起全部节点',callback: function (node,next) {console.log(node)}},],},},isShow: true,isLoad: false,}},methods: {// 缩小zoomOut () {if (this.jm.view.zoomOut()) {this.$refs.zoomOut.disabled = false} else {this.$refs.zoomOut.disabled = true}},// 放大zoomIn () {if (this.jm.view.zoomIn()) {this.$refs.zoomIn.disabled = false} else {this.$refs.zoomIn.disabled = true}},// 新增节点addNode () {var selectedNode = this.jm.get_selected_node() // as parent of new nodeif (!selectedNode) { alert('请先选择一个节点'); return }var nodeid = this.jsMind.util.uuid.newid()var topic = '请输入子节点名称'this.jm.add_node(selectedNode, nodeid, topic)},// 删除节点 onRemoveNode () {var selectedId = this.get_selected_nodeid()if (!selectedId) { alert('请先选择一个节点'); return }this.jm.remove_node(selectedId)},// 获取选中标签的 IDget_selected_nodeid () {var selectedNode = this.jm.get_selected_node()if (selectedNode) {return selectedNode.id} else {return null}}},mounted () {// 阻止浏览器默认右键事件document.oncontextmenu = function () {return false;};this.jm = this.$refs.jsMind.jmthis.jm.enable_edit()},
}
</script><style lang="less" scoped>
.brain_content {/deep/ jmnodes.theme-clouds jmnode{background-color: #f0fadd;color:#333;}/deep/ jmnodes.theme-clouds jmnode:hover{background-color:#D6E3BD;}/deep/ jmnodes.theme-clouds jmnode.selected{background-color: #b6d47e;color:#333;}height: 100%;padding: 10px;display: flex;flex-direction: column;.header_btn {height: 40px;line-height: 40px;}.js_mind {flex: 1;}
}
</style>

下面上一下jsmind.menu.js 文件

/** Released under BSD License* Copyright (c) 2019-2020 Allen_sun_js@hotmail.com** Project Home:*  https://github.com/allensunjian*/(function ($w, temp) {var Jm = $w[temp]var name = 'menu'var $d = $w['document']var menuEvent = 'oncontextmenu'var clickEvent = 'onclick'var overEvent = 'mouseover'var $c = function (tag) { return $d.createElement(tag) }var _noop = function () { }var logger = (typeof console === 'undefined') ? {log: _noop, debug: _noop, error: _noop, warn: _noop, info: _noop} : consolevar $t = function (n, t) { if (n.hasChildNodes()) { n.firstChild.nodeValue = t } else { n.appendChild($d.createTextNode(t)) } }var $h = function (n, t) {if (t instanceof HTMLElement) {t.innerHTML = ''n.appendChild(t)} else {n.innerHTML = t}}if (!Jm || Jm[name]) returnJm.menu = function (_jm) {this._get_menu_options(_jm, function () {this.init(_jm)this._mount_events()})}Jm.menu.prototype = {defaultDataMap: {funcMap: {edit: {isDepNode: true,// defaultFn不受到中台变量的控制,始终会先于fn去执行defaultFn: function (node) {var f = this._menu_default_mind_methods._menu_begin_edit.call(this.jm)f && this._menu_default_mind_methods._menu_edit_node_begin(this.jm.view, node)},fn: _noop,text: 'edit node'},addChild: {isDepNode: true,fn: function (nodeid, text) {var selected_node = this.get_selected_node()if (selected_node) {var node = this.add_node(selected_node, nodeid, text)if (node) {this.select_node(nodeid)this.begin_edit(nodeid)}}},text: 'append child'},addBrother: {isDepNode: true,fn: function (nodeid, text) {var selected_node = this.get_selected_node()if (!!selected_node && !selected_node.isroot) {var node = this.insert_node_after(selected_node, nodeid, text)if (node) {this.select_node(nodeid)this.begin_edit(nodeid)}}},text: 'append brother'},delete: {isDepNode: true,fn: function () {this.shortcut.handle_delnode.call(this.shortcut, this)},text: 'delete node'},showAll: {sDepNode: false,fn: function () {this.expand_all(this)},text: 'show all'},hideAll: {isDepNode: false,fn: function () {this.collapse_all(this)},text: 'hide all'},screenshot: {isDepNode: false,fn: function () {if (!this.screenshot) {logger.error('[jsmind] screenshot dependent on jsmind.screenshot.js !')return}this.screenshot.shootDownload()},text: 'load mind picture'},showNode: {isDepNode: true,fn: function (node) {this.expand_node(node)},text: 'show target node'},hideNode: {isDepNode: true,fn: function (node) {this.collapse_node(node)},text: 'hide target node'}},menuStl: {'width': '150px','padding': '12px 0','position': 'fixed','z-index': '10','background': '#fff','box-shadow': '0 2px 12px 0 rgba(0,0,0,0.1)','border-radius': '5px','font-size': '12px','display': 'none'},menuItemStl: {padding: '5px 15px',cursor: 'pointer',display: 'block','text-align': 'center','transition': 'all .2s'},injectionList: ['edit', 'addChild', 'delete']},init: function (_jm) {this._create_menu(_jm)this._get_injectionList(_jm)this.menuOpts.switchMidStage && Jm.util.dom.add_event(_jm.view.e_editor, 'blur', function (e) {this._menu_default_mind_methods._menu_edit_node_end.call(_jm.view)if (typeof this.menuOpts.editCaller === 'function') {this.menuOpts.editCaller($w.menu._update_node_info, this._menu_default_mind_methods._menu_update_edit_node)return}this._menu_default_mind_methods._menu_update_edit_node()}.bind(this))},_event_contextMenu (e) {e.preventDefault()this.menu.style.left = e.clientX + 'px'this.menu.style.top = e.clientY + 'px'this.menu.style.display = 'block'this.selected_node = this.jm.get_selected_node()},_event_hideMenu () {this.menu.style.display = 'none'},_mount_events () {$w[menuEvent] = this._event_contextMenu.bind(this)$w[clickEvent] = this._event_hideMenu.bind(this)},_create_menu (_jm) {var d = $c('menu')this._set_menu_wrap_syl(d)this.menu = dthis.e_panel = _jm.view.e_panelthis.e_panel.appendChild(d)},_create_menu_item (j, text, fn, isDepNode, cb, defaultFn) {var d = $c('menu-item'); var _this = thisthis._set_menu_item_syl(d)d.innerText = textd.addEventListener('click', function () {if (this.selected_node || !isDepNode) {defaultFn.call(_this, this.selected_node)if (!_this._get_mid_opts()) {cb(this.selected_node, _noop)fn.call(j, Jm.util.uuid.newid(), this.menuOpts.newNodeText || '请输入节点名称')return}cb(this.selected_node, _this._mid_stage_next(function () {var retArgs = [this.selected_node]var argus = Array.prototype.slice.call(arguments[0], 0)argus[1] = this.menuOpts.newNodeText || '请输入节点名称'if (argus[0]) {retArgs = argus}fn.apply(j, retArgs)}.bind(this)))return}alert(this.menuOpts.tipContent || 'Continue with node selected!')}.bind(this))d.addEventListener('mouseover', function () {d.style.background = 'rgb(179, 216, 255)'})d.addEventListener('mouseleave', function () {d.style.background = '#fff'})return d},_set_menu_wrap_syl (d) {var os = this._get_option_sty('menu', this._get_mixin_sty)d.style.cssText = this._format_cssText(os)},_set_menu_item_syl (d) {var os = this._get_option_sty('menuItem', this._get_mixin_sty)d.style.cssText = this._format_cssText(os)},_format_cssText (o) {var text = ''Object.keys(o).forEach(function (k) {text += k + ':' + o[k] + ';'})return text},_empty_object (o) {return Object.keys(o).length == 0},_get_option_sty (type, fn) {var sty = this.menuOpts.stylevar menu = this.defaultDataMap.menuStlvar menuItem = this.defaultDataMap.menuItemStlvar o = {menu, menuItem}if (!sty) return o[type]if (!sty[type]) return o[type]if (!sty[type] || this._empty_object(sty[type])) return o[type]return fn(o[type], sty[type])},_get_mixin_sty (dSty, oSty) {var o = {}Object.keys(oSty).forEach(function (k) {o[k] = oSty[k]})Object.keys(dSty).forEach(function (k) {if (!o[k]) o[k] = dSty[k]})return o},_get_menu_options (j, fn) {var options = j.optionsif (!options.menuOpts) returnif (!options.menuOpts.showMenu) returnthis.menuOpts = j.options.menuOptsfn.call(this)},_get_injectionDetail () {var iLs = this.menuOpts.injectionListvar dLs = this.defaultDataMap.injectionListif (!iLs) return dLsif (!Array.isArray(iLs)) {logger.error('[jsmind] injectionList must be a Array')return}if (iLs.length == 0) return dLsreturn iLs},_get_injectionList (j) {var list = this._get_injectionDetail()var _this = thislist.forEach(function (k) {var o = nullvar text = ''var callback = _noopvar defaultFn = _noopif (typeof k === 'object') {o = _this.defaultDataMap.funcMap[k.target]text = k.textk.callback && (callback = k.callback)} else {o = _this.defaultDataMap.funcMap[k]text = o.text}if (o.defaultFn) defaultFn = o.defaultFn_this.menu.appendChild(_this._create_menu_item(j, text, o.fn, o.isDepNode, callback, defaultFn))})},_get_mid_opts () {var b = this.menuOpts.switchMidStageif (!b) return falseif (typeof b !== 'boolean') {logger.error('[jsmind] switchMidStage must be Boolean')return false}return b},_switch_view_db_event (b, jm) {Jm.prototype.dblclick_handle = _noopJm.shortcut_provider.prototype.handler = _noopJm.view_provider.prototype.edit_node_end = _noop},_mid_stage_next (fn) {return function () {fn(arguments)}},_reset_mind_event_edit () {},_menu_default_mind_methods: {_menu_begin_edit: function () {var f = this.get_editable()if (!f) {logger.error('fail, this mind map is not editable.')};return f},_menu_edit_node_begin (scope, node) {if (!node.topic) {logger.warn("don't edit image nodes")return}if (scope.editing_node != null) {this._menu_default_mind_methods._menu_edit_node_end.call(scope)}scope.editing_node = nodevar view_data = node._data.viewvar element = view_data.elementvar topic = node.topicvar ncs = getComputedStyle(element)scope.e_editor.value = topicscope.e_editor.style.width = (element.clientWidth - parseInt(ncs.getPropertyValue('padding-left')) - parseInt(ncs.getPropertyValue('padding-right'))) + 'px'element.innerHTML = ''element.appendChild(scope.e_editor)element.style.zIndex = 5scope.e_editor.focus()scope.e_editor.select()},_menu_edit_node_end: function () {if (this.editing_node != null) {var node = this.editing_nodethis.editing_node = nullvar view_data = node._data.viewvar element = view_data.elementvar topic = this.e_editor.valueelement.style.zIndex = 'auto'element.removeChild(this.e_editor)$w.menu._update_node_info = {id: node.id, topic: topic}if (Jm.util.text.is_empty(topic) || node.topic === topic) {if (this.opts.support_html) {$h(element, node.topic)} else {$t(element, node.topic)}}}},_menu_update_edit_node: function () {var info = $w.menu._update_node_info$w.menu.jm.update_node(info.id, info.topic)}}}var plugin = new Jm.plugin('menu', function (_jm) {$w.menu = new Jm.menu(_jm)menu.jm = _jmif (menu.menuOpts) _jm.menu = menu})Jm.register_plugin(plugin)function preventMindEventDefault () {Jm.menu.prototype._switch_view_db_event()}Jm.preventMindEventDefault = preventMindEventDefault
})(window, 'jsMind')

备注:(如果要更改 思维导图 如hover节点样式 以及选中样式 或者其他配置中不可配置的样式时, 可以选中引入 jsmind.css 文件,然后在css文件中找到对应主题进行更改, 或者跟我这个一样直接在当前页面中 使用 deep属性直接更改他们的样式,会把你当前设置主题的样式给覆盖掉)

vue-JsMind思维导图实现(包含鼠标右键自定义菜单)相关推荐

  1. 【思维导图】vue的思维导图(超全的)

    一.使用思维导图总结Vue.js官方文档(例子优化.难点及易错点注释)[上] 二.使用思维导图总结Vue.js官方文档(例子优化.难点及易错点注释)[下] 三.用一张思维导图总结了 Vue | Vue ...

  2. vue.js思维导图笔记

  3. vue鼠标右键自定义菜单_vue-右键菜单功能

    [TOC] >[success] # :-: vue-右键菜单功能 [在线demo点击我](https://xunleif2e.github.io/vue-context-menu/demo/d ...

  4. vue鼠标右键自定义菜单_使用Vue自定义指令实现右键菜单

    前言 浏览器里右键时会有一个默认的菜单,在我的开源项目中正好有自定义右键菜单的需求,在npm库找了下与之相关的包,发现都是以组件形式实现的,感觉那种做法太过繁琐. 于是,我就想着能不能像vue的内置指 ...

  5. XMind ZEN 2020 10.2.0 for Mac中文版 最好用的Mac思维导图应用

    XMind: ZEN 2020 10.2.0 for Mac版基于全新的 Snowbrush 内核开发,外观简约.美观,XMind: ZEN 2020 10.2.0思维导图结构包含一个中心主题,各主要 ...

  6. 项目经理怎么运用思维导图

    项目经理,作为项目团队的领导,需要对项目的项目的质量.安全.进度.成本进行规划与管理,如何让项目规划.进程.成本预算等等一目了然,并且让团队的每一个人都参与进来.MindManager其中一个用途便是 ...

  7. rpm -e --nodeps_微课 | rpm的思维导图

    前导课程: 微课 | rpm的查询.升级与卸载命令 本次微课将演示使用xmind绘制rpm思维导图的过程,包括视频+文字,大约需要你10分钟.另外,文末还有一则IT冷笑话,学习之余.会心一笑:) 这个 ...

  8. 思维导图 | XMind 8 Update 8 Pro 自动破解版

    如果你曾经用过思维导图,那么一定对Xmind不陌生.以前做的比较简单,没有仔细研究,细看才发现原来Xmind竟是这么强大的工具! 有时候时常觉得头脑迷惑,许多事情想不透彻,我想这应该就是欠缺逻辑思维的 ...

  9. Xmind 8 pro 软件破解版 思维导图

    Xmind是一款非常专业的思维导图软件,收费好几百元,不过还是很多用户,因为目前用的最多,也简单易用.XMind界面友好.功能优秀.可用性极强,从而数百万人选择了它,XMind不仅可以绘制思维导图,还 ...

  10. 苹果手机上如何快速画出思维导图

    自从有了手机让我们工作生活更便捷,比如说我们突发灵感想起一件事,就可以迅速打开相应的APP来记录下来,以免遗忘.那么思维导图就是一款可以帮助你快速整理一天工作安排的软件,高效.极简和便捷. 如何利用导 ...

最新文章

  1. linux下彻底杀死ngnix进程方法
  2. python3常用函数大全_Python3NumPy——常用函数
  3. 安装了libevent和memcached之后却发现在执行的时候出现了 error while loading shared libraries问题...
  4. Highcharts Pie 饼图提示标签IE下重叠解决方法,及json数据绑定方法
  5. Cell子刊:MRI有助于揭示睡眠之谜
  6. 实现PHP基本安全的11条准则
  7. 云原生时代, Kubernetes 多集群架构初探
  8. Egret 之 消除游戏 开发 PART 6 Egret elimination game development PART 6
  9. ad18常用快捷键可以修改吗_常用发泡剂之聚氨酯发泡剂在冬季可以用吗?
  10. Arturia SQ80 V for Mac 音频波形合成器
  11. LeetCode每周刷题(2019.6.24-2019.6.30)
  12. Python Web开发 Django框架下开发一个博客
  13. FISCO BCOS 日志分析 关键词 格式
  14. 创维智能网络机顶盒e950_拆创维E950机顶盒
  15. 苹果电脑上不错的几款辅助鼠标软件
  16. 《一》微信小程序简介
  17. word插入的页眉页脚看不到问题排查
  18. 【mysql】复制一张表的数据到另一张表
  19. groovy使用场景
  20. 大兴安岭和大草原的秋季游玩攻略

热门文章

  1. 关于VS2008的Web创作组件安装错误
  2. shell深井冰之linux命令行下使用豆瓣FM
  3. 苹果手机Windows平台投屏神器airplayer,方便的使用苹果手机投屏演示
  4. my ReadBook_wangluoyingxiaoyucehua / network marketing / wangluoyingxiao
  5. kubernetes 网络callico和flannel两种网络
  6. Flowplayer简单酷炫的视频播放器
  7. Macbook怎么开启三指移动 ForceTouch TrackPad开启三指移动方法
  8. 扩展Alibaba P3C 实现自定义代码规范检查
  9. 中国吸尘器产业发展前瞻与市场投资盈利分析报告2021年版
  10. python写入文件出现空行