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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/915412.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在arm64架构下, Ubuntu 18.04.5 LTS 用命令安装和卸载qt4、qt5

问题&#xff1a;需要在 arm64下安装Qt&#xff0c;QT源码编译失败以后&#xff0c;选择在线安装&#xff01; 最后安装的版本是Qt5.9.5 和QtCreator 4.5.2 。 一、ubuntu安装qt4的命令(亲测有效)&#xff1a; sudo add-apt-repository ppa:rock-core/qt4 sudo apt updat…

AIGC学习笔记(5)——AI大模型开发工程师

文章目录 AI大模型开发工程师004 垂直领域的智能在线搜索平台1 智能在线搜索平台需求分析大模型不够“聪明”增强大模型的方式需求分析2 智能在线搜索平台方案设计方案设计技术选型大模型版本GLM-4大模型注册使用Google Cloud平台注册创建可编程的搜索引擎3 智能在线搜索平台代…

【React】状态管理之Redux

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 状态管理之Redux引言1. Redux 的核心概念1.1 单一数据源&#xff08;Single Sou…

Unity类银河战士恶魔城学习总结(P124 CharacterStats UI玩家的UI)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了玩家属性栏&#xff0c;仓库&#xff0c;物品栏UI的制作 UI_StatSlot.cs 这个脚本是用来在Unity的UI上显示玩家属性&#xf…

蓝桥杯每日真题 - 第7天

题目&#xff1a;&#xff08;爬山&#xff09; 题目描述&#xff08;X届 C&C B组X题&#xff09; 解题思路&#xff1a; 前缀和构造&#xff1a;为了高效地计算子数组的和&#xff0c;我们可以先构造前缀和数组 a&#xff0c;其中 a[i] 表示从第 1 个元素到第 i 个元素的…

Llama旋转位置编码代码实现及详解

旋转位置编码RoPE 在旋转位置编码与Transformer和BERT之间的区别中介绍了旋转位置编码&#xff08;RoPE&#xff09;的特点和优势&#xff0c;这种输入长度动态可变的优势使得在Llama编码时&#xff0c;不需要掩码将多余的嵌入掩住。为了详细了解RoPE是如何实现的&#xff0c;…

WebSocket和HTTP协议的性能比较与选择

WebSocket和HTTP协议的性能比较与选择 引言&#xff1a; 在web应用开发中&#xff0c;无论是实时聊天应用、多人在线游戏还是实时数据传输&#xff0c;网络连接的稳定性和传输效率都是关键要素之一。目前&#xff0c;WebSocket和HTTP是两种常用的网络传输协议&#xff0c;它们…

WebRTC项目一对一视频

开发步骤 1.客户端显示界面 2.打开摄像头并显示到页面 3.websocket连接 4.join、new-peer、resp-join信令实现 5.leave、peer-leave信令实现 6.offer、answer、candidate信令实现 7.综合调试和完善 1.客户端显示界面 步骤&#xff1a;创建html页面 主要是input、button、vide…

GIS基础知识:WKT格式、WKB格式

什么是WKT格式&#xff1f; WKT&#xff08;Well-Known Text&#xff09;是一种用于描述地理空间几何对象的文本格式。 这种格式是由Open Geospatial Consortium&#xff08;OGC&#xff09;定义并维护的一种开放标准&#xff0c;主要用于在不同的GIS系统和数据库之间交换空间…

力扣(LeetCode)611. 有效三角形的个数(Java)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:雾失楼台&#xff0c;月迷津渡&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主…

Mac Nginx 前端打包部署

安装homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 安装Nginx brew install nginx nginx相关命令 nginx启动命令&#xff1a;nginx nginx -s reload #重新加载配置 nginx -s reopen #重启 nginx -s stop #…

利用VMware workstation pro 17安装 Centos7虚拟机以及修改网卡名称

通过百度网盘分享的文件&#xff1a;安装虚拟机必备软件 链接&#xff1a;https://pan.baidu.com/s/1rbYhDh8x1hTzlSNihm49EA?pwdomxy 提取码&#xff1a;omxy 123网盘 https://www.123865.com/s/eXPrVv-UsKch 提取码:eNcy 先自行安装好VMware workstation pro 17 设置虚拟机…

《实时流计算系统设计与实现》-Part 2-笔记

做不到实时 做不到实时的原因 实时计算很难。通过增量计算的方式来间接获得问题的&#xff08;伪&#xff09;实时结果&#xff0c;即使这些结果带有迟滞性和近似性&#xff0c;但只要能够带来尽可能最新的信息&#xff0c;那也是有价值的。 原因可分成3个方面&#xff1a; …

《C陷阱与缺陷》

文章目录 1、【词法陷阱】1.1 符号与组成符号间的关系1.1 与 1.3 y x/*p 与 y x/(*p)&#xff0c;a-1 与 a - 1 与 a -1, 老版本编译器的处理是不同的&#xff0c;严格的ANSI C则会报错1.4 十进制的 076&#xff0c;会被处理为八进制&#xff0c;ANSI C禁止这种用法&#x…

初阶C++之C++入门基础

大家好&#xff01;欢迎来到C篇学习&#xff0c;这篇文章的内容不会很难&#xff0c;为c的引入&#xff0c;c的重点内容将在第二篇的文章中讲解&#xff0c;届时难度会陡然上升&#xff0c;请做好准备&#xff01; 我们先看网络上的一个梗&#xff1a;21天内⾃学精通C 好了&am…

Maven 构建项目

Maven 是一个项目管理和构建工具&#xff0c;主要用于 Java 项目。它简化了项目的构建、依赖管理、报告生成、发布等一系列工作。 构建自动化&#xff1a;Maven 提供了一套标准化的构建生命周期&#xff0c;包括编译、测试、打包、部署等步骤&#xff0c;通过简单的命令就可以执…

Android中桌面小部件的开发流程及常见问题和解决方案

在Android中&#xff0c;桌面小部件&#xff08;App Widget&#xff09;是应用程序可以在主屏幕或其他地方显示的一个可视化组件&#xff0c;提供简化信息和交互功能。Android桌面小部件的framework为开发者提供了接口&#xff0c;使得可以创建和更新小部件的内容。以下是Andro…

opencv(c++)----图像的读取以及显示

opencv(c)----图像的读取以及显示 imread: 作用&#xff1a;读取图像文件并将其加载到 Mat 对象中。参数&#xff1a; 第一个参数是文件路径&#xff0c;可以是相对路径或绝对路径。第二个参数是读取标志&#xff0c;比如 IMREAD_COLOR 表示以彩色模式读取图像。 返回值&#x…

马斯克万卡集群AI数据中心引发的科技涟漪:智算数据中心挑战与机遇的全景洞察

一、AI 爆发重塑数据中心格局 随着AI 技术的迅猛发展&#xff0c;尤其是大模型的崛起&#xff0c;其对数据中心产生了极为深远的影响。大模型以其数以亿计甚至更多的参数和对海量数据的处理需求&#xff0c;成为了 AI 发展的核心驱动力之一&#xff0c;同时也为数据中心带来了…

搭建Python2和Python3虚拟环境

搭建Python3虚拟环境 1. 更新pip2. 搭建Python3虚拟环境第一步&#xff1a;安装python虚拟化工具第二步&#xff1a; 创建虚拟环境 3. 搭建Python2虚拟环境第一步&#xff1a;安装虚拟环境模块第二步&#xff1a;创建虚拟环境 4. workon命令管理虚拟机第一步&#xff1a;安装扩…