vue3: markmap using typescript
在项目目录文件下,通过cmd运行下述指令。 npm create vue@latest cd vue-project npm install npm run format npm run dev 或 npm init vue@latest cd vue-prject npm run build --打包项目 创建项目没有node_modules npm init -y npm install vue-router npm install markmap-lib npm install markmap-render npm install markmap-view npm install markmap-cli npm install markmap-toolbar npm install coc-markmap npm i markmap-autoloade
项目结构:
/* * @creater: geovindu * @since: 2025-06-24 22:22:55 * @LastAuthor: geovindu * @lastTime: 2025-06-24 22:23:29 * @文件相对于项目的路径: \jsstudy\markmapdemo\src\views\markmap.ts * @message: geovindu * @IDE: vscode * @Development: node.js 20, vuejs3.0 * @package: * @ISO: windows10 * @database: mysql 8.0 sql server 2019 postgresSQL 16 * Copyright (c) 2025 by geovindu email:geovindu@163.com, All Rights Reserved. */ import { loadJS, loadCSS } from 'markmap-common'; import { Transformer } from 'markmap-lib'; import * as markmap from 'markmap-view'; // 定义类型 type LoadJS = ( scripts: string[], options: { getMarkmap: () => typeof markmap } ) => Promise<void>; type LoadCSS = (styles: string[]) => void; // 创建转换器实例 export const transformer = new Transformer(); const { scripts, styles } = transformer.getAssets(); // 加载资源 const loadJSWithType: LoadJS = (scripts, options) => { return loadJS(scripts, options); }; const loadCSSWithType: LoadCSS = (styles) => { loadCSS(styles); }; loadCSSWithType(styles); loadJSWithType(scripts, { getMarkmap: () => markmap });
<!-- * @creater: geovindu * @since: 2025-06-24 22:24:23 * @LastAuthor: geovindu * @lastTime: 2025-06-24 22:39:38 * @文件相对于项目的路径: \jsstudy\markmapdemo\src\views\VueComposition.vue * @message: geovindu * @IDE: vscode * @Development: node.js 20, vuejs3.0 * @package: * @ISO: windows10 * @database: mysql 8.0 sql server 2019 postgresSQL 16 * Copyright (c) 2025 by geovindu email:geovindu@163.com, All Rights Reserved. --> <template> <div class="flex-1"> <textarea class="w-full h-full border border-gray-400" v-model="value" /> </div> <svg class="flex-1" ref="svgRef" /> </template> <script lang="ts" setup> import { ref, onMounted, onUpdated } from 'vue'; import { Markmap } from 'markmap-view'; import { transformer } from './markmap'; // 定义类型 type MarkmapInstance = Markmap; const initValue = `# 中国行政区划 ## 北京市 ### 市辖区 #### 东城区 ##### 五道口街道 ###### 教苑社区 - 林海花园 - 江海花园 - 学清苑小区 ## 江西省 ### 吉安市 #### 永丰县 ##### 沿陂镇 ###### 涂家村委 - 涂家村 - 艾家村 - 黄家村 ## 广东省 ### 深圳市 #### 罗湖区 ##### 东晓街道 ###### 兰心社区 - 江海花园 - 江心花园 - 兰亭国际 ###### 田心社区 - 田心村 - 东晓花园 - 鹿鸣园 ##### 桂园街道 ###### 大塘龙社区 - 大塘龙小区 - 万科桂苑 - 天地大厦 `; const svgRef = ref<SVGSVGElement | null>(null); const value = ref<string>(initValue); let mm: MarkmapInstance | null = null; const update = async () => { if (!mm || !svgRef.value) return; try { const { root } = transformer.transform(value.value); await mm.setData(root); mm.fit(); } catch (error) { console.error('更新Markmap失败:', error); } }; onMounted(() => { if (svgRef.value) { mm = Markmap.create(svgRef.value); update(); } }); onUpdated(update); </script> <style scoped> textarea { font-family: monospace; font-size: 14px; } </style>
<!-- * @creater: geovindu * @since: 2025-06-24 22:23:43 * @LastAuthor: geovindu * @lastTime: 2025-06-24 22:37:14 * @文件相对于项目的路径: \jsstudy\markmapdemo\src\views\VueLegacy.vue * @message: geovindu * @IDE: vscode * @Development: node.js 20, vuejs3.0 * @package: * @ISO: windows10 * @database: mysql 8.0 sql server 2019 postgresSQL 16 * Copyright (c) 2025 by geovindu email:geovindu@163.com, All Rights Reserved. --> <template> <div class="flex flex-col h-screen"> <div class="flex-1 flex"> <textarea class="w-full h-full border border-gray-400 p-2" v-model="value" placeholder="输入 Markdown 内容..." /> <svg ref="svgRef" class="w-full h-full border border-gray-400" /> </div> </div> </template> <script lang="ts" setup> import { ref, onMounted, onUpdated, watch } from 'vue'; import { Markmap } from 'markmap-view'; import { transformer } from './markmap'; // 定义类型 type MarkmapInstance = Markmap; // 初始值和状态 const initValue = `# 中国行政区划 ## 北京市 ### 市辖区 #### 东城区 ##### 五道口街道 ###### 教苑社区 - 林海花园 - 江海花园 - 学清苑小区 ## 江西省 ### 吉安市 #### 永丰县 ##### 沿陂镇 ###### 涂家村委 - 涂家村 - 艾家村 - 黄家村 ## 广东省 ### 深圳市 #### 罗湖区 ##### 东晓街道 ###### 兰心社区 - 江海花园 - 江心花园 - 兰亭国际 ###### 田心社区 - 田心村 - 东晓花园 - 鹿鸣园 ##### 桂园街道 ###### 大塘龙社区 - 大塘龙小区 - 万科桂苑 - 天地大厦 `; const value = ref(initValue); const svgRef = ref<SVGSVGElement | null>(null); let mm: MarkmapInstance | null = null; // 更新 Markmap const update = async () => { if (!mm || !svgRef.value || !value.value) return; try { const { root } = transformer.transform(value.value); await mm.setData(root); mm.fit(); } catch (err) { console.error('更新 Markmap 失败:', err); } }; // 初始化 Markmap onMounted(() => { if (svgRef.value) { mm = Markmap.create(svgRef.value); update(); } }); // 监听值变化并更新 Markmap watch(value, update); // 组件更新后调整 Markmap onUpdated(() => { if (mm && svgRef.value) { mm.fit(); } }); </script> <style scoped> textarea { font-family: monospace; font-size: 14px; resize: none; } </style>
<!-- * @creater: geovindu * @since: 2025-06-24 22:24:23 * @LastAuthor: geovindu * @lastTime: 2025-06-24 22:43:26 * @文件相对于项目的路径: \jsstudy\markmapdemo\src\views\displayview.vue * @message: geovindu * @IDE: vscode *npm install markmap-lib *npm install markmap-render *npm install markmap-view *npm install markmap-cli *npm install markmap-toolbar *npm install coc-markmap * npm i markmap-autoloade * @Development: node.js 20, vuejs3.0 * @package: * @ISO: windows10 * @database: mysql 8.0 sql server 2019 postgresSQL 16 * Copyright (c) 2025 by geovindu email:geovindu@163.com, All Rights Reserved. --> <template> <div class="flex flex-col h-screen p-2"> <select class="border border-gray-400" v-model="type"> <option value="composition">Composition API</option> <option value="legacy">Legacy</option> </select> <component :is="currentComponent" class="flex-1" /> </div> </template> <script lang="ts" setup> import { ref, computed } from 'vue'; import VueComposition from './VueComposition.vue'; import VueLegacy from './VueLegacy.vue'; // 定义类型 type ComponentType = 'composition' | 'legacy'; const type = ref<ComponentType>('composition'); const currentComponent = computed(() => { return { composition: VueComposition, legacy: VueLegacy, }[type.value]; }); </script> <style scoped> @import url('https://cdn.jsdelivr.net/npm/tailwindcss@2.2.0/dist/tailwind.min.css'); select { padding: 0.5rem; font-size: 1rem; margin-bottom: 0.5rem; } </style>
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)