123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- <template>
- <div :class="$style.jsMind">
- <div :class="[$style.navbarwrapper, { [$style.editbtn]: !readOnly }]">
- <div>
- <a-button-group>
- <a-button icon="zoom-in" :disabled="zoomIndisabled" title="放大" @click="fnZoomIn">
- </a-button>
- <a-button icon="zoom-out" :disabled="zoomOutdisabled" title="缩小" @click="fnZoomOut">
- </a-button>
- </a-button-group>
- </div>
- <div v-if="!readOnly" :class="$style.primarybtn">
- <a-button
- icon="small-dash"
- :disabled="noSelectedNode"
- title="添加子节点"
- @click="fnAddNode"
- >
- </a-button>
- <a-button
- icon="dash"
- :disabled="noSelectedNode"
- title="添加兄弟节点"
- @click="fnAddBrotherNode"
- >
- </a-button>
- <a-button icon="delete" :disabled="noSelectedNode" title="删除节点" @click="fnDeleteNode">
- </a-button>
- <a-button
- icon="link"
- :disabled="noSelectedNode"
- title="设置链接"
- @click="fnShowAddLinkModal"
- >
- </a-button>
- </div>
- <a-modal
- title="设置链接"
- :visible="visible"
- @ok="fnAddLinkOk"
- @cancel="() => (visible = false)"
- >
- <a-input v-model="link">
- <a-select slot="addonBefore" v-model="protocol" default-value="Http://">
- <a-select-option value="http://">
- http://
- </a-select-option>
- <a-select-option value="https://">
- https://
- </a-select-option>
- </a-select>
- </a-input>
- </a-modal>
- </div>
- <js-mind ref="jsMind" :values="objectValue" :options="options" height="660px"></js-mind>
- </div>
- </template>
- <script>
- import { Message } from 'ant-design-vue'
- import Vue from 'vue'
- import jm from 'vue-jsmind'
- import components from './_import-components/km-js-mind-import'
- Vue.use(jm)
- // 生成ID
- function newid() {
- return (
- new Date().getTime().toString(16) +
- Math.random()
- .toString(16)
- .substr(2)
- ).substr(2, 16)
- }
- export default {
- name: 'KmJsMind',
- components,
- props: {
- // 是否只读
- readOnly: {
- type: Boolean,
- default: false,
- },
- // 数据
- value: {
- type: [Object, String],
- default: undefined,
- },
- },
- data() {
- return {
- visible: false,
- noSelectedNode: true,
- protocol: 'Http://',
- link: '',
- zoomIndisabled: false,
- zoomOutdisabled: false,
- jm: {},
- options: {
- editable: !this.readOnly,
- // 将新建节点的默认值改为中文
- shortcut: {
- handles: {
- addchild_custom: function(jm, e) {
- const selectedNode = jm.get_selected_node()
- if (selectedNode) {
- const nodeid = newid()
- jm.add_node(selectedNode, nodeid, '新建节点')
- jm.select_node(nodeid)
- jm.begin_edit(nodeid)
- }
- },
- addbrother_custom: function(jm, e) {
- const selectedNode = jm.get_selected_node()
- if (selectedNode) {
- if (selectedNode.isroot) {
- Message.warn('根节点不能新建兄弟节点')
- return
- }
- const nodeid = newid()
- jm.insert_node_after(selectedNode, nodeid, '新建节点')
- jm.select_node(nodeid)
- jm.begin_edit(nodeid)
- }
- },
- },
- mapping: {
- addchild_custom: 45, // <Insert>
- addbrother_custom: 13, // <Enter>
- },
- },
- },
- }
- },
- computed: {
- objectValue() {
- // 没有数据时默认的模板数据
- let objectValue = {
- /* 元数据,定义思维导图的名称、作者、版本等信息 */
- meta: {
- name: 'example',
- author: 'example',
- version: '0.1',
- },
- format: 'node_tree',
- data: {
- id: 'root',
- topic: '中心主题',
- children: [
- {
- id: 'children1',
- topic: '分支主题1',
- },
- {
- id: 'children2',
- topic: '分支主题2',
- },
- {
- id: 'children3',
- topic: '分支主题3',
- },
- ],
- },
- }
- if (this.value) {
- if (JSON.parse(this.value)) {
- objectValue = {
- meta: {
- name: 'example',
- author: 'example',
- version: '0.1',
- },
- format: 'node_tree',
- data: JSON.parse(this.value),
- }
- }
- }
- return objectValue
- },
- },
- mounted() {
- this.jm = this.$refs.jsMind.jm
- // 更新数据
- var _this = this
- this.jm.add_event_listener(function(type, data) {
- if (data.evt) {
- _this.updateValue()
- }
- })
- // 如果没有默认值,给更新下默认值
- if (!this.value) {
- this.updateValue()
- }
- // 设置按钮状态
- window.addEventListener('mousedown', (event) => {
- if (!this.readOnly) {
- const ele = event.target
- if (ele.tagName === 'JMNODE') {
- this.noSelectedNode = false
- } else if (ele.tagName === 'JMNODES') {
- this.noSelectedNode = true
- }
- }
- })
- },
- methods: {
- // 获取选中的节点
- fnGetSelectedNode() {
- const selectedNode = this.jm.get_selected_node()
- if (!selectedNode) {
- Message.warn('请先选择一个节点')
- } else {
- return selectedNode
- }
- },
- // 需要手动调一下才能更新
- refresh(item) {
- const objectValue = {
- meta: {
- name: 'example',
- author: 'example',
- version: '0.1',
- },
- format: 'node_tree',
- data: JSON.parse(item),
- }
- this.jm.show(objectValue)
- },
- // 编辑节点
- fnEditNode(node) {
- if (node) {
- this.jm.select_node(node)
- this.jm.begin_edit(node)
- } else {
- const selectedNode = this.fnGetSelectedNode()
- if (selectedNode) {
- this.jm.select_node(node)
- this.jm.begin_edit(selectedNode)
- }
- }
- },
- // 新增子节点
- fnAddNode() {
- const selectedNode = this.fnGetSelectedNode()
- const nodeid = newid()
- const topic = '新建节点'
- const node = this.jm.add_node(selectedNode, nodeid, topic)
- this.fnEditNode(node)
- },
- // 新增兄弟节点
- fnAddBrotherNode() {
- const selectedNode = this.fnGetSelectedNode()
- if (selectedNode.isroot) {
- Message.warn('根节点不能新建兄弟节点')
- return
- }
- if (selectedNode) {
- const nodeid = newid()
- const topic = '新建节点'
- this.jm.insert_node_after(selectedNode, nodeid, topic)
- this.fnEditNode(nodeid)
- }
- },
- // 删除节点
- fnDeleteNode() {
- const selectedNode = this.fnGetSelectedNode()
- this.jm.remove_node(selectedNode)
- },
- // 添加链接
- fnShowAddLinkModal() {
- const selectedNode = this.fnGetSelectedNode()
- if (selectedNode.data.protocol && selectedNode.data.link) {
- this.protocol = selectedNode.data.protocol
- this.link = selectedNode.data.link
- } else {
- this.link = ''
- }
- this.visible = true
- },
- fnAddLinkOk() {
- const selectedNode = this.fnGetSelectedNode()
- if (this.link) {
- let url = this.link
- if (
- url.substr(0, 7).toLowerCase() !== 'http://' &&
- url.substr(0, 8).toLowerCase() !== 'https://'
- ) {
- url = this.protocol + url
- }
- Object.assign(selectedNode.data, {
- link: this.link,
- protocol: this.protocol,
- 'background-color': '#eee',
- })
- let topic = selectedNode.topic
- topic = `<a href="${url}" target="_blank">${topic}</a>`
- this.jm.update_node(selectedNode.id, topic)
- this.visible = false
- } else {
- Message.warn('请输入链接地址')
- }
- },
- // 放大
- fnZoomOut() {
- if (this.jm.view.zoomOut()) {
- this.zoomIndisabled = false
- } else {
- this.zoomOutdisabled = true
- }
- },
- // 缩小
- fnZoomIn() {
- if (this.jm.view.zoomIn()) {
- this.zoomOutdisabled = false
- } else {
- this.zoomIndisabled = true
- }
- },
- // 更新数据
- updateValue() {
- this.$emit('input', JSON.stringify(this.jm.get_data().data))
- },
- },
- }
- </script>
- <style module lang="scss">
- @use '@/common/design' as *;
- $jmexpander-line-height: 8px;
- .js-mind {
- .editbtn {
- border-bottom: 1px solid #e4e7ed;
- box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2);
- }
- .navbarwrapper {
- position: inherit;
- z-index: 100;
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- padding: 5px;
- background-color: $white;
- .primarybtn {
- button {
- margin: 0 5px;
- }
- }
- }
- :global(.jsmind-editor) {
- color: $text-color;
- }
- :global(a) {
- color: $blue-6;
- }
- }
- </style>
|