更新客户端

This commit is contained in:
wanglin2 2023-07-18 16:02:39 +08:00
commit b8d52f9fa5
74 changed files with 1884 additions and 152 deletions

View File

@ -86,7 +86,7 @@ const mindMap = new MindMap({
# License
MIT
[MIT](./LICENSE)
# 微信交流群
@ -96,11 +96,48 @@ MIT
# 请作者喝杯咖啡
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡哟~
> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds
> 转账请备注哦~你的头像和名称会出现在[文档页面](https://wanglin2.github.io/mind-map/#/doc/zh/introduction/%E8%AF%B7%E4%BD%9C%E8%80%85%E5%96%9D%E6%9D%AF%E5%92%96%E5%95%A1)
> 转账请备注【思维导图】。你的头像和名字将会出现在下面和[文档页面](https://wanglin2.github.io/mind-map/#/doc/zh/introduction/%E8%AF%B7%E4%BD%9C%E8%80%85%E5%96%9D%E6%9D%AF%E5%92%96%E5%95%A1)
<p>
<img src="./web/src/assets/img/alipay.jpg" style="width: 300px" />
<img src="./web/src/assets/img/wechat.jpg" style="width: 300px" />
</p>
<p>
<span>
<img src="./web/src/assets/avatar/Think.jpg" style="width: 50px;height: 50px;" />
<span>Think</span>
</span>
<span>
<img src="./web/src/assets/avatar/志斌.jpg" style="width: 50px;height: 50px;" />
<span>志斌</span>
</span>
<span>
<img src="./web/src/assets/avatar/小土渣的宇宙.jpeg" style="width: 50px;height: 50px;" />
<span>小土渣的宇宙</span>
</span>
<span>
<img src="./web/src/assets/avatar/qp.jpg" style="width: 50px;height: 50px;" />
<span>qp</span>
</span>
<span>
<img src="./web/src/assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;" />
<span>ZXR</span>
</span>
<span>
<img src="./web/src/assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;" />
<span>花儿朵朵</span>
</span>
<span>
<img src="./web/src/assets/avatar/suka.jpg" style="width: 50px;height: 50px;" />
<span>suka</span>
</span>
<span>
<img src="./web/src/assets/avatar/Chris.jpg" style="width: 50px;height: 50px;" />
<span>Chris</span>
</span>
</p>

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 184 KiB

View File

@ -32,9 +32,6 @@ class MindMap {
this.svg = SVG().addTo(this.el).size(this.width, this.height)
this.draw = this.svg.group()
// 节点id
this.uid = 1
// 初始化主题
this.initTheme()
@ -238,7 +235,7 @@ class MindMap {
// 获取思维导图数据,节点树、主题、布局等
getData(withConfig) {
let nodeData = this.command.removeDataUid(this.command.getCopyData())
let nodeData = this.command.getCopyData()
let data = {}
if (withConfig) {
data = {

View File

@ -1,11 +1,11 @@
{
"name": "simple-mind-map",
"version": "0.6.0",
"version": "0.6.7",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "0.6.0",
"version": "0.6.7",
"license": "MIT",
"dependencies": {
"@svgdotjs/svg.js": "^3.0.16",

View File

@ -1,6 +1,6 @@
{
"name": "simple-mind-map",
"version": "0.6.6",
"version": "0.6.7",
"description": "一个简单的web在线思维导图",
"authors": [
{

View File

@ -79,10 +79,6 @@ export const defaultOpt = {
},
// 是否只有当鼠标在画布内才响应快捷键事件
enableShortcutOnlyWhenMouseInSvg: true,
// 是否开启节点动画过渡
enableNodeTransitionMove: true,
// 如果开启节点动画过渡可以通过该属性设置过渡的时间单位ms
nodeTransitionMoveDuration: 300,
// 初始根节点的位置
initRootNodePosition: null,
// 导出png、svg、pdf时的图形内边距

View File

@ -89,7 +89,7 @@ class Command {
this.history.shift()
}
this.activeHistoryIndex = this.history.length - 1
this.mindMap.emit('data_change', this.removeDataUid(data))
this.mindMap.emit('data_change', data)
this.mindMap.emit(
'back_forward',
this.activeHistoryIndex,
@ -110,7 +110,7 @@ class Command {
this.history.length
)
let data = simpleDeepClone(this.history[this.activeHistoryIndex])
this.mindMap.emit('data_change', this.removeDataUid(data))
this.mindMap.emit('data_change', data)
return data
}
}
@ -125,7 +125,7 @@ class Command {
this.activeHistoryIndex += step
this.mindMap.emit('back_forward', this.activeHistoryIndex, this.history.length)
let data = simpleDeepClone(this.history[this.activeHistoryIndex])
this.mindMap.emit('data_change', this.removeDataUid(data))
this.mindMap.emit('data_change', data)
return data
}
}

View File

@ -7,7 +7,7 @@ import Timeline from '../../layouts/Timeline'
import VerticalTimeline from '../../layouts/VerticalTimeline'
import Fishbone from '../../layouts/Fishbone'
import TextEdit from './TextEdit'
import { copyNodeTree, simpleDeepClone, walk } from '../../utils'
import { copyNodeTree, simpleDeepClone, walk, bfsWalk } from '../../utils'
import { shapeList } from './node/Shape'
import { lineStyleProps } from '../../themes/default'
import { CONSTANTS } from '../../constants/constant'
@ -195,6 +195,9 @@ class Render {
// 设置节点形状
this.setNodeShape = this.setNodeShape.bind(this)
this.mindMap.command.add('SET_NODE_SHAPE', this.setNodeShape)
// 定位节点
this.goTargetNode = this.goTargetNode.bind(this)
this.mindMap.command.add('GO_TARGET_NODE', this.goTargetNode)
}
// 注册快捷键
@ -259,7 +262,6 @@ class Render {
// 渲染
render(callback = () => {}, source) {
let t = Date.now()
// 如果当前还没有渲染完毕,不再触发渲染
if (this.isRendering) {
// 等待当前渲染完毕后再进行一次渲染
@ -290,7 +292,7 @@ class Render {
// 更新根节点
this.root = root
// 渲染节点
const onEnd = () => {
this.root.render(() => {
this.isRendering = false
this.mindMap.emit('node_tree_render_end')
callback && callback()
@ -303,18 +305,6 @@ class Render {
this.mindMap.command.addHistory()
}
}
}
let { enableNodeTransitionMove, nodeTransitionMoveDuration } =
this.mindMap.opt
this.root.render(() => {
let dur = Date.now() - t
if (enableNodeTransitionMove && dur <= nodeTransitionMoveDuration) {
setTimeout(() => {
onEnd()
}, nodeTransitionMoveDuration - dur);
} else {
onEnd()
}
})
})
this.mindMap.emit('node_active', null, this.activeNodeList)
@ -439,11 +429,14 @@ class Render {
first.parent.destroy()
}
let index = this.getNodeIndex(first)
let isRichText = !!this.mindMap.richText
first.parent.nodeData.children.splice(index + 1, 0, {
inserting: openEdit,
data: {
text: text,
expand: true,
richText: isRichText,
resetRichText: isRichText,
...(appointData || {})
},
children: []
@ -468,11 +461,14 @@ class Render {
node.nodeData.children = []
}
let text = node.isRoot ? defaultInsertSecondLevelNodeText : defaultInsertBelowSecondLevelNodeText
let isRichText = !!this.mindMap.richText
node.nodeData.children.push({
inserting: openEdit,
data: {
text: text,
expand: true,
richText: isRichText,
resetRichText: isRichText,
...(appointData || {})
},
children: []
@ -992,6 +988,19 @@ class Render {
})
}
// 定位到指定节点
goTargetNode(node) {
let uid = typeof node === 'string' ? node : node.nodeData.data.uid
if (!uid) return
this.expandToNodeUid(uid, () => {
let targetNode = this.findNodeByUid(uid)
if (targetNode) {
targetNode.active()
this.moveNodeToCenter(targetNode)
}
})
}
// 更新节点数据
setNodeData(node, data) {
Object.keys(data).forEach(key => {
@ -1028,6 +1037,44 @@ class Render {
this.mindMap.view.translateY(offsetY)
this.mindMap.view.setScale(1)
}
// 展开到指定uid的节点
expandToNodeUid(uid, callback = () => {}) {
let parentsList = []
const cache = {}
bfsWalk(this.renderTree, (node, parent) => {
if (node.data.uid === uid) {
parentsList = parent ? [...cache[parent.data.uid], parent] : []
return 'stop'
} else {
cache[node.data.uid] = parent ? [...cache[parent.data.uid], parent]: []
}
})
let needRender = false
parentsList.forEach((node) => {
if (!node.data.expand) {
needRender = true
node.data.expand = true
}
})
if (needRender) {
this.mindMap.render(callback)
} else {
callback()
}
}
// 根据uid找到对应的节点实例
findNodeByUid(uid) {
let res = null
walk(this.root, null, (node) => {
if (node.nodeData.data.uid === uid) {
res = node
return true
}
})
return res
}
}
export default Render

View File

@ -365,8 +365,8 @@ class Node {
this._unVisibleRectRegionNode.fill({
color: 'transparent'
})
this.group.add(this._unVisibleRectRegionNode)
}
this.group.add(this._unVisibleRectRegionNode)
this.renderer.layout.renderExpandBtnRect(this._unVisibleRectRegionNode, this.expandBtnSize, width, height, this)
}
}
@ -476,8 +476,6 @@ class Node {
return
}
let {
enableNodeTransitionMove,
nodeTransitionMoveDuration,
alwaysShowExpandBtn
} = this.mindMap.opt
if (alwaysShowExpandBtn) {
@ -503,13 +501,7 @@ class Node {
let t = this.group.transform()
// 如果节点位置没有变化,则返回
if (this.left === t.translateX && this.top === t.translateY) return
if (!isLayout && enableNodeTransitionMove) {
this.group
.animate(nodeTransitionMoveDuration)
.translate(this.left - t.translateX, this.top - t.translateY)
} else {
this.group.translate(this.left - t.translateX, this.top - t.translateY)
}
this.group.translate(this.left - t.translateX, this.top - t.translateY)
}
// 重新渲染节点,即重新创建节点内容、计算节点大小、计算节点内容布局、更新展开收起按钮,概要及位置
@ -531,8 +523,6 @@ class Node {
// 递归渲染
render(callback = () => {}) {
let { enableNodeTransitionMove, nodeTransitionMoveDuration } =
this.mindMap.opt
// 节点
// 重新渲染连线
this.renderLine()
@ -580,13 +570,7 @@ class Node {
})
)
} else {
if (enableNodeTransitionMove && !isLayout) {
setTimeout(() => {
callback()
}, nodeTransitionMoveDuration)
} else {
callback()
}
callback()
}
// 手动插入的节点立即获得焦点并且开启编辑模式
if (this.nodeData.inserting) {

View File

@ -1,4 +1,5 @@
import Node from './Node'
import { createUid } from '../../../utils/index'
// 检查是否存在概要
function checkHasGeneralization () {
@ -18,7 +19,7 @@ function createGeneralizationNode () {
data: {
data: this.nodeData.data.generalization
},
uid: this.mindMap.uid++,
uid: createUid(),
renderer: this.renderer,
mindMap: this.mindMap,
draw: this.draw,

View File

@ -1,6 +1,7 @@
import Node from '../core/render/node/Node'
import { CONSTANTS, initRootNodePositionMap } from '../constants/constant'
import Lru from '../utils/Lru'
import { createUid } from '../utils/index'
// 布局基类
class Base {
@ -101,7 +102,7 @@ class Base {
}
} else {
// 创建新节点
let uid = this.mindMap.uid++
let uid = data.data.uid || createUid()
newNode = new Node({
data,
uid,

View File

@ -28,8 +28,7 @@ class KeyboardNavigation {
this.focus(dir)
} else {
let root = this.mindMap.renderer.root
this.mindMap.renderer.moveNodeToCenter(root)
root.active()
this.mindMap.execCommand('GO_TARGET_NODE', root)
}
}
@ -81,8 +80,7 @@ class KeyboardNavigation {
// 找到了则让目标节点聚焦
if (targetNode) {
this.mindMap.renderer.moveNodeToCenter(targetNode)
targetNode.active()
this.mindMap.execCommand('GO_TARGET_NODE', targetNode)
}
}

View File

@ -47,7 +47,7 @@ class NodeImgAdjust {
// 节点图片鼠标移动事件
onNodeImgMousemove(node, img) {
// 如果当前正在拖动调整中那么直接返回
if (this.isMousedown || this.isAdjusted) return
if (this.isMousedown || this.isAdjusted || this.mindMap.opt.readonly) return
// 如果在当前节点内移动,以及自定义元素已经是显示状态,那么直接返回
if (this.node === node && this.isShowHandleEl) return
// 更新当前节点信息

View File

@ -1,3 +1,5 @@
import { v4 as uuidv4 } from 'uuid'
// 深度优先遍历树
export const walk = (
root,
@ -31,9 +33,11 @@ export const walk = (
// 广度优先遍历树
export const bfsWalk = (root, callback) => {
callback(root)
let stack = [root]
let isStop = false
if (callback(root, null) === 'stop') {
isStop = true
}
while (stack.length) {
if (isStop) {
break
@ -41,8 +45,9 @@ export const bfsWalk = (root, callback) => {
let cur = stack.shift()
if (cur.children && cur.children.length) {
cur.children.forEach(item => {
if (isStop) return
stack.push(item)
if (callback(item) === 'stop') {
if (callback(item, cur) === 'stop') {
isStop = true
}
})
@ -424,3 +429,8 @@ export const getImageSize = src => {
}
})
}
// 创建节点唯一的id
export const createUid = () => {
return uuidv4()
}

View File

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
<link rel="icon" href="./dist/logo.png">
<link rel="icon" href="./dist/logo.ico">
<title>思绪思维导图</title>
</head>
<body>

BIN
web/public/logo.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2479351 */
src: url('iconfont.woff2?t=1688536767282') format('woff2'),
url('iconfont.woff?t=1688536767282') format('woff'),
url('iconfont.ttf?t=1688536767282') format('truetype');
src: url('iconfont.woff2?t=1689407546912') format('woff2'),
url('iconfont.woff?t=1689407546912') format('woff'),
url('iconfont.ttf?t=1689407546912') format('truetype');
}
.iconfont {
@ -13,6 +13,54 @@
-moz-osx-font-smoothing: grayscale;
}
.iconjiantouyou:before {
content: "\e62d";
}
.iconbianji1:before {
content: "\e60a";
}
.icondaohang1:before {
content: "\e632";
}
.iconyanjing:before {
content: "\e8bf";
}
.iconwangzhan:before {
content: "\e628";
}
.iconcsdn:before {
content: "\e608";
}
.iconshejiaotubiao-10:before {
content: "\e644";
}
.iconstar:before {
content: "\e7df";
}
.iconfork:before {
content: "\e641";
}
.iconxiazai:before {
content: "\e613";
}
.iconteamwork:before {
content: "\e870";
}
.iconshuiyin:before {
content: "\e67a";
}
.iconxmind:before {
content: "\ea57";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -114,8 +114,9 @@ export default {
},
navigatorToolbar: {
openMiniMap: 'Open mini map',
readonly: 'Readonly',
edit: 'Edit'
closeMiniMap: 'Close mini map',
readonly: 'Change to eadonly',
edit: 'Change to edit'
},
nodeHyperlink: {
title: 'Link',

View File

@ -114,8 +114,9 @@ export default {
},
navigatorToolbar: {
openMiniMap: '开启小地图',
readonly: '只读模式',
edit: '编辑模式'
closeMiniMap: '关闭小地图',
readonly: '切换为只读模式',
edit: '切换为编辑模式'
},
nodeHyperlink: {
title: '超链接',

View File

@ -15,7 +15,8 @@
import Header from './components/Header.vue'
import Sidebar from './components/Sidebar.vue'
import CatalogBar from './components/CatalogBar.vue'
import 'highlight.js/styles/atom-one-dark.css'
// import 'highlight.js/styles/atom-one-dark.css'
import 'highlight.js/styles/github.css'
export default {
components: {
@ -103,7 +104,7 @@ export default {
a {
font-weight: 500;
text-decoration: none;
color: #42b883;
color: #1ea59a;
transition: color 0.25s;
&:hover {

View File

@ -225,7 +225,7 @@ export default {
left: -10px;
width: 4px;
height: 20px;
background-color: #42b883;
background-color: #1ea59a;
border-radius: 4px;
transition: top 0.25s cubic-bezier(0, 1, 0.5, 1), opacity 0.25s,
background-color 0.5s;

View File

@ -1,8 +1,8 @@
<template>
<div class="headerContainer">
<div class="left">
<div class="title">
<img src="../../../assets/img/logo.png" alt="">
<div class="title" @click="toIndex">
<img src="../../../assets/img/logo2.png" alt="">
SimpleMindMap
</div>
</div>
@ -74,6 +74,10 @@ export default {
}
},
toIndex() {
this.$router.push('/index')
},
toDemo() {
this.$router.push('/')
},
@ -108,6 +112,7 @@ export default {
font-weight: bold;
display: flex;
align-items: center;
cursor: pointer;
img {
width: 30px;
@ -130,7 +135,7 @@ export default {
font-size: 14px;
&:hover {
color: #42b883;
color: #1ea59a;
}
}

View File

@ -108,7 +108,7 @@ export default {
}
&.active {
color: #42b883;
color: #1ea59a;
}
}
}

View File

@ -1,5 +1,15 @@
# Changelog
## 0.6.7
Fix: 1.Fixed the issue of missing placeholder elements for the expand and collapse button after node collapse and expansion. 2.Fixed the issue of being able to scale images in read-only mode.
New: 1.Support locating to a node based on node instance or node uid. 2.Modify the creation method of node uids and export data to add node uids.
Remove: 1.Remove the node transition effect.
Demo: 1.Add website homepage. 2.Fixed the issue of missing node styles when creating new nodes in the outline. 3.Fixed the issue of missing edited text after pressing Enter or Tab after editing nodes in the outline. 4.Optimize the node positioning of the outline, and the collapsed nodes will automatically expand. 5.The sidebar button supports folding. 6.Optimize small screen adaptation.
## 0.6.6
New: 1.Support exporting to Xmind new version files. 2.Importing the new version of Xmind file supports importing images from nodes. 3.Add a vertical timeline structure.

View File

@ -1,6 +1,11 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.6.7</h2>
<p>Fix: 1.Fixed the issue of missing placeholder elements for the expand and collapse button after node collapse and expansion. 2.Fixed the issue of being able to scale images in read-only mode.</p>
<p>New: 1.Support locating to a node based on node instance or node uid. 2.Modify the creation method of node uids and export data to add node uids.</p>
<p>Remove: 1.Remove the node transition effect.</p>
<p>Demo: 1.Add website homepage. 2.Fixed the issue of missing node styles when creating new nodes in the outline. 3.Fixed the issue of missing edited text after pressing Enter or Tab after editing nodes in the outline. 4.Optimize the node positioning of the outline, and the collapsed nodes will automatically expand. 5.The sidebar button supports folding. 6.Optimize small screen adaptation.</p>
<h2>0.6.6</h2>
<p>New: 1.Support exporting to Xmind new version files. 2.Importing the new version of Xmind file supports importing images from nodes. 3.Add a vertical timeline structure.</p>
<p>Fix: 1.The TouchEvent plugin no longer sends click events, solving the problem of two windows opening when clicking on a hyperlink on the mobile end. 2.Fix the issue of dragging and moving a node to become a child node of another node, where the parent node of that node points to not being updated. 3.Fixed an issue where the node border style was not updated when dragging a second level node into a third level node. 4.Fix the issue where the mouse will not trigger the button display when moving into the unfolded or retracted button position, except for the structure growing to the right.</p>

View File

@ -51,8 +51,8 @@ const mindMap = new MindMap({
| expandBtnStylev0.5.0+ | Object | { color: '#808080', fill: '#fff' } | Expand the color of the stow button | |
| expandBtnIconv0.5.0+ | Object | { open: '', close: '' } | Customize the icon of the expand/collapse button, and you can transfer the svg string of the icon | |
| enableShortcutOnlyWhenMouseInSvgv0.5.1+ | Boolean | true | Only respond to shortcut key events when the mouse is inside the canvas | |
| enableNodeTransitionMovev0.5.1+ | Boolean | true | Whether to enable node animation transition | |
| nodeTransitionMoveDurationv0.5.1+ | Number | 300 | If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds | |
| enableNodeTransitionMovev0.5.1+v0.6.7+ is remove this feature | Boolean | true | Whether to enable node animation transition | |
| nodeTransitionMoveDurationv0.5.1+v0.6.7+ is remove this feature | Number | 300 | If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds | |
| initRootNodePositionv0.5.3+ | Array | null | The position of the initial root node can be passed as an array, default is `['center', 'center']`, Represents the root node at the center of the canvas, In addition to `center`, keywords can also be set to `left`, `top`, `right`, and `bottom`, In addition to passing keywords, each item in the array can also pass a number representing a specific pixel, Can pass a percentage string, such as `['40%', '60%']`, Represents a horizontal position at `40%` of the canvas width, and a vertical position at `60%` of the canvas height | |
| exportPaddingXv0.5.5+ | Number | 10 | Horizontal padding of graphics when exporting PNG, SVG, and PDF | |
| exportPaddingYv0.5.5+ | Number | 10 | Vertical padding of graphics when exporting PNG, SVG, and PDF | |
@ -347,6 +347,7 @@ redo. All commands are as follows:
| SET_NODE_CUSTOM_POSITION (v0.2.0+) | Set a custom position for a node | node (the node to set), left (custom x coordinate, default is undefined), top (custom y coordinate, default is undefined) |
| RESET_LAYOUT (v0.2.0+) | Arrange layout with one click | |
| SET_NODE_SHAPE (v0.2.4+) | Set the shape of a node | node (the node to set), shape (the shape, all shapes: [Shape.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js)) |
| GO_TARGET_NODEv0.6.7+ | Navigate to a node, and if the node is collapsed, it will automatically expand to that node | nodeNode instance or node uid to locate |
### setData(data)

View File

@ -218,14 +218,14 @@
<td></td>
</tr>
<tr>
<td>enableNodeTransitionMovev0.5.1+</td>
<td>enableNodeTransitionMovev0.5.1+v0.6.7+ is remove this feature</td>
<td>Boolean</td>
<td>true</td>
<td>Whether to enable node animation transition</td>
<td></td>
</tr>
<tr>
<td>nodeTransitionMoveDurationv0.5.1+</td>
<td>nodeTransitionMoveDurationv0.5.1+v0.6.7+ is remove this feature</td>
<td>Number</td>
<td>300</td>
<td>If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds</td>
@ -920,6 +920,11 @@ redo. All commands are as follows:</p>
<td>Set the shape of a node</td>
<td>node (the node to set), shape (the shape, all shapes: <a href="https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js">Shape.js</a>)</td>
</tr>
<tr>
<td>GO_TARGET_NODEv0.6.7+</td>
<td>Navigate to a node, and if the node is collapsed, it will automatically expand to that node</td>
<td>nodeNode instance or node uid to locate</td>
</tr>
</tbody>
</table>
<h3>setData(data)</h3>

View File

@ -148,4 +148,16 @@ Open source is not easy. If this project is helpful to you, you can invite the a
<img src="../../../../assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>ZXR</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>花儿朵朵</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/suka.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>suka</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/Chris.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>Chris</p>
</div>
</div>

View File

@ -107,6 +107,18 @@ full screen, support mini map</li>
<img src="../../../../assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>ZXR</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>花儿朵朵</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/suka.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>suka</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/Chris.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>Chris</p>
</div>
</div>
</div>
</template>

View File

@ -91,4 +91,22 @@ Move a node behind another node
Move a node to the center of the canvas.
Currently, if there is zoom, returning to the center will reset the zoom.
Currently, if there is zoom, returning to the center will reset the zoom.
### expandToNodeUid(uid, callback)
> v0.6.7+
- `uid`: uid of node
- `callback`: Expand completed callback function
Expand to the node of the specified uid.
### findNodeByUid(uid)
> v0.6.7+
- `uid`: uid of node
Find the corresponding node instance based on the uid.

View File

@ -62,6 +62,27 @@ is an object, e.g. <code>{text: 'I am new text'}</code></p>
</blockquote>
<p>Move a node to the center of the canvas.</p>
<p>Currently, if there is zoom, returning to the center will reset the zoom.</p>
<h3>expandToNodeUid(uid, callback)</h3>
<blockquote>
<p>v0.6.7+</p>
</blockquote>
<ul>
<li>
<p><code>uid</code>: uid of node</p>
</li>
<li>
<p><code>callback</code>: Expand completed callback function</p>
</li>
</ul>
<p>Expand to the node of the specified uid.</p>
<h3>findNodeByUid(uid)</h3>
<blockquote>
<p>v0.6.7+</p>
</blockquote>
<ul>
<li><code>uid</code>: uid of node</li>
</ul>
<p>Find the corresponding node instance based on the uid.</p>
</div>
</template>

View File

@ -1,5 +1,15 @@
# Changelog
## 0.6.7
修复1.修复节点收起再展开后展开收起按钮占位元素丢失的问题。 2.修复只读模式下可以缩放图片的问题。
新增1.支持根据节点实例或节点uid定位到某个节点。 2.修改节点uid的创建方式导出数据添加节点的uid。
移除1.移除节点过渡效果。
Demo1.添加网站首页。 2.修复大纲里创建新节点时节点样式丢失的问题。 3.修复大纲里编辑节点后按回车或Tab键后编辑文本丢失的问题。 4.优化大纲的节点定位,被收起的节点会自动展开。 5.侧边栏按钮支持收起。 6.优化小屏适配。
## 0.6.6
新增1.支持导出为Xmind新版文件。2.导入Xmind新版文件支持导入节点中的图片。 3.新增竖向时间轴结构。

View File

@ -1,6 +1,11 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.6.7</h2>
<p>修复1.修复节点收起再展开后展开收起按钮占位元素丢失的问题 2.修复只读模式下可以缩放图片的问题</p>
<p>新增1.支持根据节点实例或节点uid定位到某个节点 2.修改节点uid的创建方式导出数据添加节点的uid</p>
<p>移除1.移除节点过渡效果</p>
<p>Demo1.添加网站首页 2.修复大纲里创建新节点时节点样式丢失的问题 3.修复大纲里编辑节点后按回车或Tab键后编辑文本丢失的问题 4.优化大纲的节点定位被收起的节点会自动展开 5.侧边栏按钮支持收起 6.优化小屏适配</p>
<h2>0.6.6</h2>
<p>新增1.支持导出为Xmind新版文件2.导入Xmind新版文件支持导入节点中的图片 3.新增竖向时间轴结构</p>
<p>修复1.TouchEvent插件不再派发click事件解决移动端点击超链接会打开两个窗口的问题 2.修复拖拽移动一个节点成为另一个节点的子节点时该节点的父节点指向未更新的问题 3.修复二级节点拖拽成三级节点时节点边框样式未更新的问题 4.修复向右生长的结构外其他结构鼠标移入展开收起按钮位置时不会触发按钮显示的问题</p>

View File

@ -51,8 +51,8 @@ const mindMap = new MindMap({
| expandBtnStylev0.5.0+ | Object | { color: '#808080', fill: '#fff' } | 展开收起按钮的颜色 | |
| expandBtnIconv0.5.0+ | Object | { open: '', close: '' } | 自定义展开收起按钮的图标可以传图标的svg字符串 | |
| enableShortcutOnlyWhenMouseInSvgv0.5.1+ | Boolean | true | 是否只有当鼠标在画布内才响应快捷键事件 | |
| enableNodeTransitionMovev0.5.1+ | Boolean | true | 是否开启节点动画过渡 | |
| nodeTransitionMoveDurationv0.5.1+ | Number | 300 | 如果开启节点动画过渡可以通过该属性设置过渡的时间单位ms | |
| enableNodeTransitionMovev0.5.1+v0.6.7+已去除该特性) | Boolean | true | 是否开启节点动画过渡 | |
| nodeTransitionMoveDurationv0.5.1+v0.6.7+已去除该特性) | Number | 300 | 如果开启节点动画过渡可以通过该属性设置过渡的时间单位ms | |
| initRootNodePositionv0.5.3+ | Array | null | 初始根节点的位置,可传一个数组,默认为`['center', 'center']`,代表根节点处于画布中心位置,除了`center`,关键词还可以设置`left`、`top`、`right`、`bottom`,除了可以传关键词,数组的每项还可以传递一个数字,代表具体的像素,可以传递一个百分比字符串,比如`['40%', '60%']`,代表水平位置在画布宽度的`40%`的位置,垂直位置在画布高度的`60%`的位置 | |
| exportPaddingXv0.5.5+ | Number | 10 | 导出png、svg、pdf时的图形水平内边距 | |
| exportPaddingYv0.5.5+ | Number | 10 | 导出png、svg、pdf时的图形垂直内边距 | |
@ -340,6 +340,7 @@ mindMap.updateConfig({
| SET_NODE_CUSTOM_POSITIONv0.2.0+ | 设置节点自定义位置 | node要设置的节点、 left自定义的x坐标默认为undefined、 top自定义的y坐标默认为undefined |
| RESET_LAYOUTv0.2.0+ | 一键整理布局 | |
| SET_NODE_SHAPEv0.2.4+ | 设置节点形状 | node要设置的节点、shape形状全部形状[Shape.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js) |
| GO_TARGET_NODEv0.6.7+ | 定位到某个节点,如果该节点被收起,那么会自动展开到该节点 | node要定位到的节点实例或节点uid |
### setData(data)

View File

@ -218,14 +218,14 @@
<td></td>
</tr>
<tr>
<td>enableNodeTransitionMovev0.5.1+</td>
<td>enableNodeTransitionMovev0.5.1+v0.6.7+已去除该特性</td>
<td>Boolean</td>
<td>true</td>
<td>是否开启节点动画过渡</td>
<td></td>
</tr>
<tr>
<td>nodeTransitionMoveDurationv0.5.1+</td>
<td>nodeTransitionMoveDurationv0.5.1+v0.6.7+已去除该特性</td>
<td>Number</td>
<td>300</td>
<td>如果开启节点动画过渡可以通过该属性设置过渡的时间单位ms</td>
@ -915,6 +915,11 @@ mindMap.setTheme(<span class="hljs-string">&#x27;主题名称&#x27;</span>)
<td>设置节点形状</td>
<td>node要设置的节点shape形状全部形状<a href="https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js">Shape.js</a></td>
</tr>
<tr>
<td>GO_TARGET_NODEv0.6.7+</td>
<td>定位到某个节点如果该节点被收起那么会自动展开到该节点</td>
<td>node要定位到的节点实例或节点uid</td>
</tr>
</tbody>
</table>
<h3>setData(data)</h3>

View File

@ -18,6 +18,9 @@ mindMap.on('data_change', (data) => {
const node = data._node
mindMap.renderer.moveNodeToCenter(node)
node.active()
// 在v0.6.7+版本可以这么做:
mindMap.execCommand('GO_TARGET_NODE', node)// 或者传节点的uid
```
当在大纲树上编辑了某个节点的内容,需要同步到思维导图树上:

View File

@ -13,6 +13,9 @@
<pre class="hljs"><code><span class="hljs-keyword">const</span> node = data._node
mindMap.renderer.moveNodeToCenter(node)
node.active()
<span class="hljs-comment">// v0.6.7+</span>
mindMap.execCommand(<span class="hljs-string">&#x27;GO_TARGET_NODE&#x27;</span>, node)<span class="hljs-comment">// uid</span>
</code></pre>
<p>当在大纲树上编辑了某个节点的内容需要同步到思维导图树上</p>
<pre class="hljs"><code>data._node.setText(<span class="hljs-string">&#x27;xxx&#x27;</span>)

View File

@ -108,7 +108,9 @@
## 请作者喝杯咖啡
开源不易,如果本项目有帮助到你的话,可以请作者喝杯咖啡哟~
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡哟~
> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds
> 转账请备注【思维导图】。你的头像和名字将会出现在下面。
@ -137,4 +139,16 @@
<img src="../../../../assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>ZXR</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>花儿朵朵</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/suka.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>suka</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/Chris.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>Chris</p>
</div>
</div>

View File

@ -69,7 +69,10 @@
<h2>License</h2>
<p><a href="https://opensource.org/licenses/MIT">MIT</a></p>
<h2>请作者喝杯咖啡</h2>
<p>开源不易如果本项目有帮助到你的话可以请作者喝杯咖啡哟~</p>
<p>开源不易如果本项目有帮助到你的话可以考虑请作者喝杯咖啡哟~</p>
<blockquote>
<p>厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds</p>
</blockquote>
<blockquote>
<p>转账请备注思维导图你的头像和名字将会出现在下面</p>
</blockquote>
@ -96,6 +99,18 @@
<img src="../../../../assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>ZXR</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>花儿朵朵</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/suka.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>suka</p>
</div>
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
<img src="../../../../assets/avatar/Chris.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>Chris</p>
</div>
</div>
</div>
</template>

View File

@ -82,4 +82,22 @@
移动节点到画布中心。
目前如果是存在缩放的情况下回到中心会重置缩放。
目前如果是存在缩放的情况下回到中心会重置缩放。
### expandToNodeUid(uid, callback)
> v0.6.7+
- `uid`节点uid
- `callback`:展开完成的回调函数
展开到指定uid的节点。
### findNodeByUid(uid)
> v0.6.7+
- `uid`节点uid
根据uid找到对应的节点实例。

View File

@ -51,6 +51,27 @@
</blockquote>
<p>移动节点到画布中心</p>
<p>目前如果是存在缩放的情况下回到中心会重置缩放</p>
<h3>expandToNodeUid(uid, callback)</h3>
<blockquote>
<p>v0.6.7+</p>
</blockquote>
<ul>
<li>
<p><code>uid</code>节点uid</p>
</li>
<li>
<p><code>callback</code>展开完成的回调函数</p>
</li>
</ul>
<p>展开到指定uid的节点</p>
<h3>findNodeByUid(uid)</h3>
<blockquote>
<p>v0.6.7+</p>
</blockquote>
<ul>
<li><code>uid</code>节点uid</li>
</ul>
<p>根据uid找到对应的节点实例</p>
</div>
</template>

View File

@ -95,4 +95,10 @@ export default {
}
}
}
@media screen and (max-width: 635px) {
.countContainer {
display: none;
}
}
</style>

View File

@ -74,6 +74,7 @@ export default {
.btn {
cursor: pointer;
font-size: 18px;
}
}
</style>

View File

@ -19,25 +19,51 @@
<MouseAction :mindMap="mindMap"></MouseAction>
</div>
<div class="item">
<el-checkbox v-model="openMiniMap" @change="toggleMiniMap">{{
$t('navigatorToolbar.openMiniMap')
}}</el-checkbox>
<el-tooltip
effect="dark"
:content="
openMiniMap
? $t('navigatorToolbar.closeMiniMap')
: $t('navigatorToolbar.openMiniMap')
"
placement="top"
>
<div
class="btn iconfont icondaohang1"
@click="toggleMiniMap"
></div>
</el-tooltip>
</div>
<div class="item">
<el-switch
<!-- <el-switch
v-model="isReadonly"
:active-text="$t('navigatorToolbar.readonly')"
:inactive-text="$t('navigatorToolbar.edit')"
@change="readonlyChange"
>
</el-switch>
</div>
<div class="item">
<Scale :mindMap="mindMap"></Scale>
</el-switch> -->
<el-tooltip
effect="dark"
:content="
isReadonly
? $t('navigatorToolbar.edit')
: $t('navigatorToolbar.readonly')
"
placement="top"
>
<div
class="btn iconfont"
:class="[isReadonly ? 'iconyanjing' : 'iconbianji1']"
@click="readonlyChange"
></div>
</el-tooltip>
</div>
<div class="item">
<Fullscreen :mindMap="mindMap"></Fullscreen>
</div>
<div class="item">
<Scale :mindMap="mindMap"></Scale>
</div>
<div class="item">
<span class="iconfont icongithub" @click="openGithub"></span>
</div>
@ -77,16 +103,15 @@ export default {
openMiniMap: false
}
},
mounted() {
this.toggleMiniMap(this.openMiniMap)
},
methods: {
readonlyChange(value) {
this.mindMap.setMode(value ? 'readonly' : 'edit')
readonlyChange() {
this.isReadonly = !this.isReadonly
this.mindMap.setMode(this.isReadonly ? 'readonly' : 'edit')
},
toggleMiniMap(show) {
this.$bus.$emit('toggle_mini_map', show)
toggleMiniMap() {
this.openMiniMap = !this.openMiniMap
this.$bus.$emit('toggle_mini_map', this.openMiniMap)
},
onLangChange(lang) {
@ -126,6 +151,18 @@ export default {
color: #303133;
text-decoration: none;
}
.btn {
cursor: pointer;
font-size: 18px;
}
}
}
@media screen and (max-width: 502px) {
.navigatorContainer {
left: 20px;
overflow-x: auto;
}
}
</style>

View File

@ -46,11 +46,10 @@ export default {
data: [],
defaultProps: {
label(data) {
return data.data.text.replaceAll(/\n/g, '</br>')
return data.data.richText ? data.data.text : data.data.text.replaceAll(/\n/g, '</br>')
}
},
notHandleDataChange: false,
isCreateNode: false
notHandleDataChange: false
}
},
computed: {
@ -77,11 +76,12 @@ export default {
},
methods: {
onBlur(e, node) {
if (this.isCreateNode) {
this.isCreateNode = false
return
const richText = node.data.data.richText
if (richText) {
node.data._node.setText(e.target.innerHTML, true)
} else {
node.data._node.setText(e.target.innerText)
}
node.data._node.setText(e.target.innerText)
},
getKey() {
@ -102,24 +102,21 @@ export default {
//
insertNode() {
this.notHandleDataChange = false
this.isCreateNode = true
this.mindMap.execCommand('INSERT_NODE', false)
},
//
insertChildNode() {
this.notHandleDataChange = false
this.isCreateNode = true
this.mindMap.execCommand('INSERT_CHILD_NODE', false)
},
//
onClick(e, data) {
onClick(e, node) {
this.notHandleDataChange = true
let node = data.data._node
if (node.nodeData.data.isActive) return
node.mindMap.renderer.moveNodeToCenter(node)
node.active()
let targetNode = node.data._node
if (targetNode && targetNode.nodeData.data.isActive) return
this.mindMap.execCommand('GO_TARGET_NODE', node.data.data.uid)
},
}
}

View File

@ -2,8 +2,11 @@
<div
class="sidebarTriggerContainer"
@click.stop
:class="{ show: activeSidebar }"
:class="{ hasActive: show && activeSidebar, show: show }"
>
<div class="toggleShowBtn" :class="{hide: !show}" @click="show = !show">
<span class="iconfont iconjiantouyou"></span>
</div>
<div class="trigger">
<div
class="triggerItem"
@ -32,7 +35,7 @@ export default {
name: 'SidebarTrigger',
data() {
return {
show: false
show: true
}
},
computed: {
@ -55,17 +58,57 @@ export default {
<style lang="less" scoped>
.sidebarTriggerContainer {
position: fixed;
right: 0px;
right: -60px;
margin-top: 110px;
transition: all 0.3s;
top: 50%;
transform: translateY(-50%);
&.show {
right: 0;
}
&.hasActive {
right: 305px;
}
.toggleShowBtn {
position: absolute;
left: -6px;
width: 35px;
height: 60px;
background: #409eff;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
transition: left .1s linear;
z-index: 0;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
display: flex;
align-items: center;
padding-left: 4px;
&.hide {
left: -8px;
span {
transform: rotateZ(180deg);
}
}
&:hover {
left: -18px;
}
span {
color: #fff;
transition: all 0.1s;
}
}
.trigger {
position: relative;
width: 60px;
border-color: #eee;
background-color: #fff;

View File

@ -520,4 +520,17 @@ export default {
}
}
}
@media screen and (max-width: 1040px) {
.toolbarContainer {
.toolbar {
left: 20px;
right: 20px;
transform: translateX(0);
width: auto;
max-width: none;
}
}
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<div class="indexContainer">
<Header></Header>
<Block1></Block1>
<Block2></Block2>
<Block3></Block3>
<Block4></Block4>
<Block5></Block5>
</div>
</template>
<script>
import Header from './components/Header.vue'
import Block1 from './components/Block1.vue'
import Block2 from './components/Block2.vue'
import Block3 from './components/Block3.vue'
import Block4 from './components/Block4.vue'
import Block5 from './components/Block5.vue'
export default {
components: {
Header,
Block1,
Block2,
Block3,
Block4,
Block5
},
data() {
return {}
},
created() {},
methods: {}
}
</script>
<style lang="less" scoped>
.indexContainer {
}
</style>

View File

@ -0,0 +1,206 @@
<template>
<div class="block1Container" :style="{ height: height + 'px' }">
<div class="blockContent">
<div class="infoBox">
<div class="blockTitle">Simple mind map</div>
<Split></Split>
<div class="infoList">
<p class="infoRow">是一个思维导图库</p>
<p class="infoRow">同时也是一个思维导图软件</p>
<p class="infoRow">开源免费强大...</p>
</div>
<div class="desc">
无论你是开发者还是使用者只要喜欢思维导图都能在这个项目里找到你需要的
</div>
<div class="btnBox">
<div class="btn" @click="useOnline">在线使用</div>
<div class="btn btn2" @click="jumpDoc">开发文档</div>
</div>
</div>
<div class="picBox">
<div class="animation1"></div>
<div class="animation2"></div>
<div class="animation3"></div>
<div class="pic"></div>
</div>
</div>
</div>
</template>
<script>
import Split from './Split.vue'
export default {
components: {
Split
},
data() {
return {
height: 0
}
},
created() {
window.addEventListener('resize', this.onResize)
this.onResize()
},
mounted() {},
beforeDestroy() {
window.removeEventListener('resize', this.onResize)
},
methods: {
onResize() {
this.height = window.innerHeight
},
useOnline() {
this.$router.push('/')
},
jumpDoc() {
this.$router.push('/doc/zh/')
}
}
}
</script>
<style lang="less" scoped>
.block1Container {
background-color: #f0f9fa;
border-radius: 0 0 0 450px;
display: flex;
justify-content: center;
align-items: center;
.blockContent {
width: 100%;
max-width: 1140px;
display: flex;
align-items: center;
justify-content: space-between;
.infoBox {
.blockTitle {
font-size: 16px;
color: #1e3547;
margin-bottom: 10px;
}
.infoList {
margin-top: 20px;
.infoRow {
font-size: 45px;
color: #1e3547;
font-weight: 700;
margin-bottom: 20px;
}
}
.desc {
color: #828f99;
font-size: 20px;
line-height: 1.5;
}
.btnBox {
display: flex;
align-items: center;
margin-top: 20px;
.btn {
height: 44px;
padding: 0 20px;
line-height: 44px;
cursor: pointer;
background: #1ea59a;
border-color: #1ea59a;
color: #fff;
font-weight: 600;
font-size: 15px;
border-radius: 5px;
transition: all 0.5s;
margin-right: 10px;
&:hover {
transform: translateY(-4px);
}
&.btn2 {
background-color: #f5828b;
}
}
}
}
.picBox {
position: relative;
.pic {
width: 500px;
height: 500px;
background-image: url('../../../assets/img/block1.png');
background-size: cover;
}
.animation1 {
width: 38px;
height: 38px;
border: 7px solid #f5828b;
border-radius: 50%;
position: absolute;
right: -50px;
bottom: 86px;
animation-name: zoom1;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-direction: alternate;
box-shadow: 0 12px 50px 0 rgba(0, 0, 0, 0.14);
}
.animation2 {
border-radius: 50%;
background-color: #1ea59a;
box-shadow: 0 20px 30px 0 rgba(48, 61, 114, 0.4);
position: absolute;
width: 25px;
height: 25px;
top: -60px;
right: 60px;
animation: spin 2s infinite alternate;
bottom: 60px;
}
.animation3 {
border-radius: 50%;
background-color: #25233a;
box-shadow: 0 20px 30px 0 rgba(245, 130, 139, 0.4);
position: absolute;
width: 25px;
height: 25px;
bottom: 50px;
left: 0px;
animation: spin 3s infinite alternate;
}
}
}
}
@keyframes zoom1 {
0% {
transform: scale(0.9);
}
100% {
transform: scale(1.5);
}
}
@keyframes spin {
0% {
transform: translateY(0);
}
100% {
transform: translateY(40px);
}
}
</style>

View File

@ -0,0 +1,263 @@
<template>
<div class="block2Container">
<div class="blockContent">
<div class="blockTitle">为什么选择Simple mind map</div>
<div class="dataList">
<div class="dataItem" v-for="(item, index) in dataList" :key="index">
<div class="iconBox">
<span class="icon iconfont" :class="[item.icon]"></span>
</div>
<div class="dataValue">{{ item.value }}</div>
</div>
</div>
<div class="desc">
如果你是开发者Simple mind
map提供了一个功能完善的 js 思维导图库不依赖任何框架你可以使用它来快速完成Web思维导图产品的开发
</div>
<div class="desc">
如果你是使用者Simple mind
map提供了一个完整的思维导图软件支持在线和客户端两种使用方式所有功能完全免费
</div>
<div class="functionList">
<div
class="functionItem"
v-for="(item, index) in functionList"
:key="index"
>
<div class="icon iconfont" :class="[item.icon]"></div>
<div class="info">
<div class="name">{{ item.name }}</div>
<div class="value">{{ item.value }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
dataList: [
{
icon: 'iconstar',
value: 'Github star数量450+'
},
{
icon: 'iconfork',
value: 'Github fork数量100+'
},
{
icon: 'iconxiazai',
value: 'npm总下载次数10000+'
},
{
icon: 'iconteamwork',
value: '代码贡献者6+'
}
],
functionList: [
{
icon: 'iconjingzi',
name: '主题',
value: '内置多种主题,允许高度自定义样式,支持注册新主题。'
},
{
icon: 'iconjiegou',
name: '结构',
value:
'支持常见的逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图结构。'
},
{
icon: 'iconjianpan',
name: '快捷键',
value: '常用操作支持快捷键,方便使用。'
},
{
icon: 'iconzitixiahuaxian',
name: '富文本',
value:
'节点支持普通文本和富文本两种类型,通过富文本可以创建样式丰富的节点文本内容。'
},
{
icon: 'iconimage',
name: '图片',
value: '选中任一节点,选择上传图片,让内容达到图文并茂。'
},
{
icon: 'icongaikuozonglan',
name: '概要',
value: '补充表述几个节点之间的关系。'
},
{
icon: 'iconxiaolian',
name: '图标',
value: '通过添加图标来让节点内容更丰富。'
},
{
icon: 'iconchaolianjie',
name: '超链接',
value: '节点可插入超链接,鼠标点击即可实现跳转。'
},
{
icon: 'iconflow-Mark',
name: '备注',
value: '详细的内容可以放在备注中,节点内显得更简单明了。'
},
{
icon: 'iconbiaoqian',
name: '标签',
value: '如果添加带颜色的标签,来突出要表达的重点。'
},
{
icon: 'iconlianjiexian',
name: '关联线',
value: '通过添加关联线来表明节点之间的关联关系。'
},
{
icon: 'iconmouseL',
name: '拖动',
value: '画布和节点都可以进行拖动。'
},
{
icon: 'icondaohang',
name: '导航器',
value: '通过导航器可以方便知道当前画布处于思维导图的哪个部分。'
},
{
icon: 'icondaochu',
name: '导入导出',
value: '支持多种文件格式的导入和导出。'
},
{
icon: 'iconshuiyin',
name: '水印',
value: '内置支持水印功能,防止隐私泄露。'
},
{
icon: 'iconwithdraw',
name: '前进后退',
value: '不小心误操作删除或修改内容支持一键撤回或恢复。'
},
{
icon: 'iconfuhao-dagangshu',
name: '大纲',
value: '根据大纲编辑思维导图,让内容更详细也不容易出错。'
},
{
icon: 'iconshezhi',
name: '丰富的设置',
value: '提供了丰富的功能设置,可以选择合适你的操作行为。'
}
]
}
}
}
</script>
<style lang="less" scoped>
.block2Container {
display: flex;
justify-content: center;
align-items: center;
.blockContent {
padding: 100px 0;
width: 100%;
max-width: 1140px;
.dataList {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 40px;
.dataItem {
box-shadow: 0 5px 30px -10px rgba(0, 0, 0, 0.1);
border-radius: 20px;
margin-right: 30px;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
&:last-of-type {
margin-right: 0;
}
.iconBox {
width: 55px;
height: 55px;
border-radius: 10px;
background-color: rgba(30, 165, 154, 0.1);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
.icon {
font-size: 30px;
color: #1ea59a;
}
}
.dataValue {
color: #1e3547;
font-weight: 700;
}
}
}
.blockTitle {
font-size: 30px;
font-weight: 700;
color: #1e3547;
text-align: center;
margin-bottom: 40px;
}
.desc {
color: #828f99;
font-size: 17px;
line-height: 1.7;
}
.functionList {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-top: 60px;
.functionItem {
display: flex;
width: 30%;
margin-bottom: 50px;
.icon {
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
font-size: 50px;
margin-right: 24px;
color: #1ea59a;
}
.info {
.name {
margin-bottom: 5px;
color: #1e3547;
font-weight: 600;
font-size: 18px;
}
.value {
font-size: 14px;
color: #828f99;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,102 @@
<template>
<div class="block3Container">
<div class="blockContent">
<div class="picBox"></div>
<div class="infoBox">
<div class="infoTitle">客户端</div>
<div class="info">支持WindowsMacLinux平台</div>
<div class="info">
在线版数据默认保存在浏览器缓存里同时也可以操作电脑本地文件但是在线版受限于网络环境访问可能比较慢多个文件切换也不够方便所以提供客户端版本功能简单但不简陋
</div>
<div class="btnList">
<div class="btn">
<a href="https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3" target="_blank">百度网盘下载</a>
</div>
<div class="btn btn2">
<a href="https://github.com/wanglin2/mind-map/releases" target="_blank">Github下载</a>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
methods: {}
}
</script>
<style lang="less" scoped>
.block3Container {
background-color: #f0f9fa;
border-radius: 0 0 350px 0;
display: flex;
justify-content: center;
align-items: center;
.blockContent {
width: 100%;
max-width: 1140px;
height: 520px;
display: flex;
align-items: center;
.picBox {
width: 500px;
height: 500px;
background-image: url('../../../assets/img/block3.png');
flex-shrink: 0;
}
.infoBox {
.infoTitle {
font-weight: 700;
color: #1e3547;
font-size: 40px;
}
.info {
color: #828f99;
font-size: 16px;
line-height: 1.7;
margin-top: 20px;
}
.btnList {
display: flex;
align-items: center;
.btn {
height: 44px;
cursor: pointer;
background: #1ea59a;
border-color: #1ea59a;
border-radius: 5px;
transition: all 0.5s;
margin-right: 10px;
margin-top: 20px;
&:hover {
transform: translateY(-4px);
}
&.btn2 {
background-color: #f5828b;
}
a {
height: 100%;
padding: 0 20px;
line-height: 44px;
color: #fff;
font-weight: 600;
font-size: 15px;
text-decoration: none;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,140 @@
<template>
<div class="block4Container">
<div class="blockContent">
<div class="infoBox">
<div class="infoTitle">JavaScript库</div>
<div class="info">
simple-mind-map是一个简单&强大的Web思维导图库不依赖任何特定框架可以帮助你快速开发思维导图产品
</div>
<div class="info">
使用非常简单只需三步即可渲染出一个思维导图
</div>
<div class="info">第一步安装</div>
<div class="codeBox">
<pre><code class="language-bash" ref="code1">
npm i simple-mind-map
</code></pre>
</div>
<div class="info">第二步引入</div>
<div class="codeBox">
<pre><code class="language-javascript" ref="code2">
import MindMap from "simple-mind-map"
</code></pre>
</div>
<div class="info">第三步实例化</div>
<div class="codeBox">
<pre><code class="language-javascript" ref="code3">
const mindMap = new MindMap({
// 0
el: document.getElementById('mindMapContainer'),
//
data: {
"data": {
"text": "根节点"
},
"children": []
}
})
</code></pre>
</div>
<div class="btnList">
<div class="btn" @click="jumpDoc">查看更多</div>
</div>
</div>
<div class="picBox"></div>
</div>
</div>
</template>
<script>
import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'
import bash from 'highlight.js/lib/languages/bash'
import 'highlight.js/styles/github.css'
hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('bash', bash)
export default {
mounted() {
hljs.highlightElement(this.$refs.code1)
hljs.highlightElement(this.$refs.code2)
hljs.highlightElement(this.$refs.code3)
},
methods: {
jumpDoc() {
this.$router.push('/doc/zh/')
}
}
}
</script>
<style lang="less" scoped>
.block4Container {
display: flex;
justify-content: center;
align-items: center;
.blockContent {
width: 100%;
max-width: 1140px;
display: flex;
align-items: center;
padding: 50px 0;
.picBox {
width: 500px;
height: 500px;
background-image: url('../../../assets/img/block4.png');
flex-shrink: 0;
}
.infoBox {
margin-right: 50px;
.infoTitle {
font-weight: 700;
color: #1e3547;
font-size: 40px;
}
.info {
color: #828f99;
font-size: 16px;
line-height: 1.7;
margin-top: 20px;
}
.codeBox {
font-size: 16px;
margin-top: 10px;
}
.btnList {
display: flex;
align-items: center;
.btn {
height: 44px;
cursor: pointer;
background: #1ea59a;
border-color: #1ea59a;
border-radius: 5px;
transition: all 0.5s;
margin-right: 10px;
margin-top: 20px;
height: 100%;
padding: 0 20px;
line-height: 44px;
color: #fff;
font-weight: 600;
font-size: 15px;
&:hover {
transform: translateY(-4px);
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,229 @@
<template>
<div class="block5Container">
<div class="blockContent">
<div class="infoBox">
<div class="infoTitle">街角小林出品</div>
<div class="infoDesc">
90六年+前端开发工程师热爱前端写作开源
</div>
<div class="linkBtnList">
<div class="linkBtn">
<a href="https://github.com/wanglin2" target="_blank">
<span class="linkBtnIcon iconfont icongithub"></span>
</a>
</div>
<div class="linkBtn">
<a href="https://juejin.cn/user/325111170756279" target="_blank">
<span class="linkBtnIcon text">掘金</span>
</a>
</div>
<div class="linkBtn">
<a
href="https://segmentfault.com/u/jiejiaoxiaolin/articles"
target="_blank"
>
<span class="linkBtnIcon text">思否</span>
</a>
</div>
<div class="linkBtn">
<a href="http://lxqnsys.com/" target="_blank">
<span class="linkBtnIcon iconfont iconwangzhan"></span>
</a>
</div>
<div class="linkBtn">
<a
href="https://www.zhihu.com/people/wang-lin-49-43-65"
target="_blank"
>
<span class="linkBtnIcon iconfont iconshejiaotubiao-10"></span>
</a>
</div>
<div class="linkBtn">
<a
href="https://blog.csdn.net/sinat_33488770?type=blog"
target="_blank"
>
<span class="linkBtnIcon iconfont iconcsdn"></span>
</a>
</div>
</div>
</div>
<div class="linkBox">
<div class="linkTitle">更多作品</div>
<div class="linkList">
<div class="linkItem" v-for="item in linkList" :key="item.name">
<a :href="item.url" target="_blank">{{ item.name }}</a>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
linkList: [
{
name: 'CodeRun',
url: 'https://github.com/wanglin2/code-run'
},
{
name: 'TinyWhiteboard',
url: 'https://github.com/wanglin2/tiny_whiteboard'
},
{
name: 'Mark.js',
url: 'https://github.com/wanglin2/markjs'
},
{
name: 'WebMapEngine',
url: 'https://github.com/wanglin2/web_map_demo'
},
{
name: 'SimpleNoviceGuide',
url: 'https://github.com/wanglin2/simple-novice-guide'
},
{
name: 'CanvasEditor',
url: 'https://github.com/wanglin2/canvas-editor-demo'
},
{
name: 'JsonTreeView',
url: 'https://github.com/wanglin2/json-tree-view'
},
{
name: 'SimpleFlowChart',
url: 'https://github.com/wanglin2/simple-flow-chart'
},
{
name: 'VideoTimeLine',
url: 'https://github.com/wanglin2/VideoTimeLine'
},
{
name: 'MarkdownEditor',
url: 'https://github.com/wanglin2/markdown_editor_sync_scroll_demo'
},
{
name: 'AssociationLine',
url: 'https://github.com/wanglin2/AssociationLineDemo'
},
{
name: 'HandPaintedStyle',
url: 'https://github.com/wanglin2/handPaintedStyle'
}
]
}
},
methods: {}
}
</script>
<style lang="less" scoped>
.block5Container {
background-color: #f0f9fa;
border-radius: 450px 0 0 0;
display: flex;
justify-content: center;
align-items: center;
.blockContent {
width: 100%;
max-width: 1140px;
height: 350px;
display: flex;
padding-top: 100px;
.infoBox {
.infoTitle {
font-size: 20px;
font-weight: 700;
color: #1e3547;
line-height: 1.4;
margin-bottom: 20px;
}
.infoDesc {
color: #828f99;
font-size: 16px;
}
.linkBtnList {
margin-top: 30px;
display: flex;
align-items: center;
.linkBtn {
width: 38px;
height: 38px;
border-radius: 50%;
overflow: hidden;
background-color: #f0f9fa;
border: 2px solid #dbf1f1;
margin-right: 10px;
a {
width: 100%;
height: 100%;
text-decoration: none;
display: flex;
justify-content: center;
align-items: center;
transition: all 0.5s;
&:hover {
background-color: #1ea59a;
.linkBtnIcon {
color: #fff;
}
}
.linkBtnIcon {
font-size: 20px;
color: #1e3547;
transition: all 0.5s;
&.text {
font-size: 13px;
}
}
}
}
}
}
.linkBox {
margin-left: 150px;
.linkTitle {
font-size: 20px;
font-weight: 700;
color: #1e3547;
line-height: 1.4;
margin-bottom: 20px;
}
.linkList {
display: flex;
flex-wrap: wrap;
.linkItem {
margin-right: 20px;
margin-bottom: 10px;
a {
color: #828f99;
font-size: 15px;
transition: all 0.5s;
text-decoration: none;
&:hover {
color: #1ea59a;
}
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,167 @@
<template>
<div class="indexHeaderContainer" :class="{ active: active }">
<div class="headerContent">
<div class="logoBox">
<span class="logo"></span>
<span class="title">SimpleMindMap</span>
</div>
<div class="nav">
<div
class="navItem"
@click="jumpTop"
:class="{
active: activeTab === 'home'
}"
>
首页
</div>
<div class="navItem" @click="useOnline">在线使用</div>
<div
class="navItem"
@click="jumpClient"
:class="{
active: activeTab === 'client'
}"
>
客户端
</div>
<div class="navItem" @click="jumpDoc">开发文档</div>
<div class="navItem">
<a href="https://github.com/wanglin2/mind-map" target="_blank"
>Github</a
>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
active: false,
activeTab: 'home',
clientEl: null
}
},
created() {
window.addEventListener('scroll', this.onScroll)
},
mounted() {
this.clientEl = document.querySelector('.block3Container')
},
beforeDestroy() {
window.removeEventListener('scroll', this.onScroll)
},
methods: {
onScroll() {
this.active = window.scrollY > 0
let offsetTop = this.clientEl.offsetTop
if (
window.scrollY + window.innerHeight >= offsetTop &&
window.scrollY <= offsetTop + this.clientEl.offsetHeight
) {
this.activeTab = 'client'
} else {
this.activeTab = 'home'
}
},
useOnline() {
this.$router.push('/')
},
jumpDoc() {
this.$router.push('/doc/zh/')
},
jumpTop() {
window.scrollTo(0, 0)
},
jumpClient() {
window.scrollTo(0, this.clientEl.offsetTop - 76)
}
}
}
</script>
<style lang="less" scoped>
.indexHeaderContainer {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 76px;
transition: all 0.5s;
background-color: transparent;
z-index: 999;
&.active {
background-color: #fff;
box-shadow: 0 5px 30px -10px rgba(0, 0, 0, 0.1);
}
.headerContent {
height: 100%;
max-width: 1140px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
.logoBox {
display: flex;
align-items: center;
.logo {
width: 22px;
height: 22px;
background-image: url('../../../assets/img/logo2.png');
background-size: cover;
margin-right: 5px;
}
.title {
color: #000;
font-size: 20px;
}
}
.nav {
display: flex;
align-items: center;
.navItem {
color: #828f99;
font-size: 15px;
transition: all 0.5s;
margin-right: 40px;
cursor: pointer;
&:last-of-type {
margin-right: 0;
}
&.active {
color: #1ea59a;
}
&:hover {
color: #1ea59a;
}
a {
text-decoration: none;
color: #828f99;
&:hover {
color: #1ea59a;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,16 @@
<template>
<div class="splitContainer"></div>
</template>
<script>
export default {}
</script>
<style lang="less" scoped>
.splitContainer {
width: 122px;
height: 15px;
background-image: url('../../../assets/img/split.png');
background-size: cover;
}
</style>

View File

@ -10,12 +10,17 @@
<img src="../../../assets/img/icon.png" alt="" />
<h2>思绪思维导图</h2>
<p>版本{{ version }}</p>
<p>
官网
<span @click="open('homepage')">思绪思维导图</span>
</p>
<p>
获取源码
<span @click="open('mind-map')">mind-map</span>
</p>
<p>
下载最新版本
<span @click="open('baiduNet')">百度云</span>
<span @click="open('releases')">releases</span>
</p>
</div>
@ -55,14 +60,20 @@ export default {
open(type) {
let url = ''
switch (type) {
case 'homepage':
url = 'https://wanglin2.github.io/mind-map/#/index'
break
case 'mind-map':
url = 'https://github.com/wanglin2/mind-map/tree/electron'
break;
break
case 'baiduNet':
url = 'https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3'
break
case 'releases':
url = 'https://github.com/wanglin2/mind-map/releases'
break
default:
break;
break
}
window.electronAPI.openUrl(url)
}
@ -72,9 +83,9 @@ export default {
<style lang="less" scoped>
.aboutDialog {
/deep/ .el-dialog__body {
padding: 0;
}
/deep/ .el-dialog__body {
padding: 0;
}
}
.aboutBox {
@ -99,6 +110,11 @@ export default {
span {
cursor: pointer;
color: #409eff;
margin-right: 10px;
&:last-of-type {
margin-right: 0;
}
}
}
}

View File

@ -7,35 +7,51 @@
<div class="fileListBox">
<Empty v-if="list.length <= 0"></Empty>
<el-table v-else :data="list" style="width: 100%">
<el-table-column prop="name" label="名称"> </el-table-column>
<el-table-column label="名称">
<template slot-scope="scope">
<span class="textBtn" @click="openFile(scope.row.url)">{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column prop="url" label="文件路径"> </el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
icon="el-icon-edit"
circle
size="mini"
@click="openFile(scope.row.url)"
></el-button>
<el-button
icon="el-icon-document-copy"
circle
size="mini"
@click="copyFile(scope.row.url)"
></el-button>
<el-button
type="danger"
icon="el-icon-delete"
circle
size="mini"
@click="deleteFile(scope.row.url, scope.$index)"
></el-button>
<el-button
icon="el-icon-folder-opened"
circle
size="mini"
@click="openFileInDir(scope.row.url)"
></el-button>
<el-tooltip effect="light" content="编辑" placement="top">
<el-button
icon="el-icon-edit"
circle
size="mini"
@click="openFile(scope.row.url)"
></el-button>
</el-tooltip>
<el-tooltip effect="light" content="复制" placement="top">
<el-button
icon="el-icon-document-copy"
circle
size="mini"
@click="copyFile(scope.row.url)"
></el-button>
</el-tooltip>
<el-tooltip effect="light" content="删除" placement="top">
<el-button
type="danger"
icon="el-icon-delete"
circle
size="mini"
@click="deleteFile(scope.row.url, scope.$index)"
></el-button>
</el-tooltip>
<el-tooltip
effect="light"
content="打开文件所在目录"
placement="top"
>
<el-button
icon="el-icon-folder-opened"
circle
size="mini"
@click="openFileInDir(scope.row.url)"
></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
@ -160,6 +176,10 @@ export default {
.fileListBox {
flex-grow: 1;
overflow: hidden;
.textBtn {
cursor: pointer;
}
}
}
</style>

View File

@ -0,0 +1,101 @@
<template>
<el-dialog
class="sponsorDialog"
title="友情赞助"
:visible.sync="dialogVisible"
width="480px"
@close="onClose"
>
<div class="sponsorBox">
<p>开源不易如果本软件/项目有帮助到你的话</p>
<p>可以考虑请作者喝杯咖啡哟~</p>
<p>转账请备注思维导图</p>
<p>你的头像和名字将会出现在<span @click="open('github')">仓库首页</span></p>
<div>
<img src="../../../assets/img/alipay.jpg" alt="">
<img src="../../../assets/img/wechat.jpg" alt="">
</div>
</div>
</el-dialog>
</template>
<script>
export default {
model: {
prop: 'value',
event: 'change'
},
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
dialogVisible: false,
}
},
watch: {
value(val, oldVal) {
this.dialogVisible = val
}
},
methods: {
onClose() {
this.$emit('change', false)
},
open(type) {
let url = ''
switch (type) {
case 'github':
url = 'https://github.com/wanglin2/mind-map#%E8%AF%B7%E4%BD%9C%E8%80%85%E5%96%9D%E6%9D%AF%E5%92%96%E5%95%A1'
break
default:
break
}
window.electronAPI.openUrl(url)
}
}
}
</script>
<style lang="less" scoped>
.sponsorDialog {
/deep/ .el-dialog__body {
padding: 0;
}
}
.sponsorBox {
display: flex;
flex-direction: column;
justify-content: center;
padding: 30px;
img {
width: 200px;
}
h2 {
margin-bottom: 20px;
}
p {
margin-bottom: 10px;
span {
cursor: pointer;
color: #409eff;
margin-right: 10px;
&:last-of-type {
margin-right: 0;
}
}
}
}
</style>

View File

@ -121,6 +121,7 @@ export default {
width: 10px;
height: 10px;
margin-left: 10px;
flex-shrink: 0;
.modifyDot {
width: 100%;

View File

@ -14,6 +14,9 @@
<span class="settingBtn el-icon-setting"></span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="about">关于软件</el-dropdown-item>
<el-dropdown-item command="sponsor">友情赞助</el-dropdown-item>
<el-dropdown-item command="help">使用帮助</el-dropdown-item>
<el-dropdown-item command="doc">开发文档</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
@ -23,6 +26,7 @@
<FileList></FileList>
</div>
<AboutDialog v-model="showAboutDialog"></AboutDialog>
<SponsorDialog v-model="showSponsorDialog"></SponsorDialog>
</div>
</template>
@ -32,6 +36,7 @@ import MacControl from '../components/MacControl.vue'
import Sidebar from '../components/Sidebar.vue'
import FileList from '../components/FileList.vue'
import AboutDialog from '../components/AboutDialog.vue'
import SponsorDialog from '../components/SponsorDialog.vue'
export default {
components: {
@ -39,11 +44,13 @@ export default {
MacControl,
Sidebar,
FileList,
AboutDialog
AboutDialog,
SponsorDialog
},
data() {
return {
showAboutDialog: false
showAboutDialog: false,
showSponsorDialog: false
}
},
methods: {
@ -52,6 +59,15 @@ export default {
case 'about':
this.showAboutDialog = true
break
case 'sponsor':
this.showSponsorDialog = true
break
case 'help':
window.electronAPI.openUrl('https://wanglin2.github.io/mind-map/#/help/')
break
case 'doc':
window.electronAPI.openUrl('https://wanglin2.github.io/mind-map/#/doc/zh/')
break
default:
break
}

View File

@ -6,6 +6,7 @@ import routerList from '@/pages/Doc/routerList'
import WorkbenchePage from '@/pages/Workbenche/Index'
import WorkbencheHomePage from '@/pages/Workbenche/views/Home'
import WorkbencheEditPage from '@/pages/Workbenche/views/Edit'
import IndexPage from '@/pages/Index/Index'
// 处理没有翻译的章节路由
const handleRouterList = () => {
@ -52,6 +53,16 @@ const routes = [
}
]
},
{
path: '/index',
name: 'Index',
component: IndexPage
},
{
path: '/',
name: 'Edit',
component: EditPage
},
...routerList.map((item) => {
return {
path: `/doc/${item.lang}/`,