自学内容网 自学内容网

jsmind 思维导图 + monaco-editor + vue3 + ts

Index.vue:

<template>
  <div class="m-jsmind-wrap">
    <div class="m-jsmind-header">
      <el-button type="primary" @click="() => handleReset()">重置</el-button>
      <el-button type="primary" @click="() => handleAdd()">增加子节点</el-button>
    </div>
    <div class="m-jsmind-info">
      <div id="jsmind_container" class="m-jsmind"></div>
      <div class="m-jsmind-editor-wrap">
        <MonacoEditor v-model:value="mind" :language="language" :theme="theme" ref="editerRef" />
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import MonacoEditor from './MonacoEditor.vue'
import { initData } from './config'
import './index.css'

let jm: any
let currentNode: any
const mind: any = ref('')
const language = ref('java')
const theme = ref('vs-dark') // default-theme vs-dark
const editerRef: any = ref(null)

//#region 工具条
const handleReset = () => {
  mind.value = JSON.stringify(initData, null, 2)
}

const handleAdd = () => {
  console.log('add')

  if (currentNode) {
    let now = Date.now()
    jm.add_node(currentNode.node, now, '新节点')
  } else {
    ElMessage.warning('请选择父节点')
  }
}
//#endregion

const handleInit = () => {
  let initDataTemp = initData
  try {
    let jsmindDataStr = localStorage.getItem('jsmindData')
    if (jsmindDataStr) {
      let jsmindDataObj = JSON.parse(jsmindDataStr)
      if (typeof jsmindDataObj === 'object') {
        initDataTemp = jsmindDataObj
      }
    }
  } catch (error) {
    console.log(error)
  }
  mind.value = JSON.stringify(initDataTemp, null, 2)
  let options = {
    container: 'jsmind_container',
    theme: 'primary',
    editable: true,
    view: {
      engine: 'canvas',
      draggable: true,
      hide_scrollbars_when_draggable: true
    }
  }
  jm = new jsMind(options)
  let mindValueObj = JSON.parse(mind.value)
  jm.show(mindValueObj)
  jm.add_event_listener((type: any, node: any) => {
    console.log('事件类型:', type, node)

    //1展开 3编辑 4选择
    if ([1, 3].includes(type)) {
      let mindValueObj = jm.get_data()
      mind.value = JSON.stringify(mindValueObj, null, 2)
    } else if (type === 4) {
      console.log('删除节点:', node)
      currentNode = node
    }
  })
}

const handleResize = () => {
  setTimeout(() => {
    editerRef.value.handleUpdate()
  }, 20)
}

watch(
  () => mind.value,
  (newValue) => {
    try {
      let mindValueObj = JSON.parse(newValue)
      jm.show(mindValueObj)
      localStorage.setItem('jsmindData', JSON.stringify(mindValueObj))
    } catch (error) {
      console.log(error)
      ElMessage({
        message: error + '',
        type: 'warning'
      })
    }
  }
)

onMounted(() => {
  handleInit()
  window.addEventListener('resize', () => {
    handleResize()
  })
})
</script>

MonacoEditor.vue:

<template>
  <div ref="editorContainer" class="m-jsmind-editor-container"></div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, watch, defineProps, defineEmits, defineExpose } from 'vue'
import * as monaco from 'monaco-editor'
import './index.css'

const props = defineProps({
  value: String,
  language: {
    type: String,
    default: 'java'
  },
  theme: {
    type: String,
    default: 'vs-dark'
  }
})

const emits = defineEmits(['update:value'])

const editorContainer: any = ref(null)
let editorInstance: any = null

const handleInit = () => {
  try {
    if (editorContainer.value) {
      if (editorInstance) {
        editorInstance.dispose();
      }
      editorInstance = monaco.editor.create(editorContainer.value, {
        value: props.value || '',
        language: props.language,
        theme: props.theme,
        readOnly: false,
        domReadOnly: true,
        quickSuggestions: false,
        minimap: { enabled: false },
        lineNumbersMinChars: 1,
        lineNumbers: 'off',
        wordWrap: 'on',
        unicodeHighlight: {
          ambiguousCharacters: false
        }
      })

      editorInstance.onDidChangeModelContent(() => {
        emits('update:value', editorInstance.getValue())
      })
    }
  } catch (error) {
    console.log(error)
  }
}

const handleUpdate = () => {
  handleInit()
}

watch(
  () => props.language,
  (newLanguage) => {
    if (editorInstance) {
      monaco.editor.setModelLanguage(editorInstance.getModel(), newLanguage)
    }
  }
)

watch(
  () => props.value,
  (newValue) => {
    if (editorInstance && editorInstance.getValue() !== newValue) {
      editorInstance.setValue(newValue)
    }
  }
)

onMounted(() => {
  handleInit()
})

onBeforeUnmount(() => {
  if (editorInstance) {
    editorInstance.dispose()
  }
})

defineExpose({
  handleUpdate
})
</script>

index.css:

.m-jsmind-wrap{display: flex;flex-direction: column; padding: 10px;position: absolute;top:0;left:0;right:0;bottom:0;}
.m-jsmind-header{height: 50px;}
.m-jsmind-info{display: flex; flex:1;}
.m-jsmind{box-shadow: 0px 0px 5px #888888;flex: 1; height: 100%;margin: 0 10px 0 0 ;}
.m-jsmind-editor-wrap{flex: 1; margin: 0 0 0 10px;height: 100%;}
.m-jsmind-editor-container {height: 100%;}

config.ts:

let initData = {
  meta: {
    name: 'jsMind-demo-tree',
    author: 'xutongbao',
    version: '0.2'
  },
  format: 'node_tree',
  data: {
    id: 'root',
    topic: 'jsMind',
    children: [
      {
        id: 'easy',
        topic: 'Easy',
        direction: 'left',
        expanded: true,
        children: [
          { id: 'easy1', topic: 'Easy to show' },
          { id: 'easy2', topic: 'Easy to edit' },
          { id: 'easy3', topic: 'Easy to store' },
          { id: 'easy4', topic: 'Easy to embed' }
        ]
      },
      {
        id: 'open',
        topic: 'Open Source',
        direction: 'right',
        expanded: true,
        children: [
          { id: 'open1', topic: 'on GitHub' },
          { id: 'open2', topic: 'BSD License' }
        ]
      },
      {
        id: 'powerful',
        topic: 'Powerful',
        direction: 'right',
        children: [
          { id: 'powerful1', topic: 'Base on Javascript' },
          { id: 'powerful2', topic: 'Base on HTML5' },
          { id: 'powerful3', topic: 'Depends on you' }
        ]
      },
      {
        id: 'other',
        topic: 'test node',
        direction: 'left',
        children: [
          { id: 'other1', topic: "I'm from local variable" },
          { id: 'other2', topic: 'I can do everything' }
        ]
      }
    ]
  }
}

export {
  initData
}

index.html:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>admin</title>
    <link rel="stylesheet" type="text/css" href="jsmind/jsmind.css" />
    <script src="jsmind/jsmind.js"></script>
    <script src="jsmind/jsmind.draggable-node.js"></script>

    <style>
      html {
        height: 100%;
        margin: 0 0 0 0;
      }
      body {
        height: 100% !important;
        min-height: 100% !important;
        overflow-y: auto;
      }
      .m-tooltip-base {
        display: inline-block;
        width: 500px;
        height: 500px;
        background: red;
      }
    </style>
  </head>
  <body id="m-body">
    <div id="app"></div>
    <!-- <div class="gc-spread-toolTip m-tooltip-base">tooltip</div> -->
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

人工智能学习网站

https://chat.xutongbao.top


原文地址:https://blog.csdn.net/xutongbao/article/details/143743413

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!