Compare commits

..

21 Commits

Author SHA1 Message Date
wanglin2
516676b484 更新群二维码 2023-08-04 20:14:26 +08:00
wanglin2
10ed3d4f7c Merge branch 'feature' into main 2023-08-01 18:55:55 +08:00
wanglin2
8fc7f7d32c 打包 2023-08-01 18:55:32 +08:00
wanglin2
27a0efa4e0 Demo:1.打包不修改静态资源的文件名;2.支持运行时设置静态资源路径 2023-08-01 18:54:40 +08:00
wanglin2
7d227e901a Merge branch 'feature' into main 2023-08-01 09:51:30 +08:00
wanglin2
080d7489e7 打包 2023-08-01 09:51:12 +08:00
wanglin2
b11bd5a7ef Demo:提供应用接管模式,方便对接自己的存储服务 2023-08-01 09:49:44 +08:00
wanglin2
80ae38d295 Merge branch 'feature' into main 2023-07-31 09:48:07 +08:00
wanglin2
a4b7915196 Doc:update 2023-07-31 09:45:20 +08:00
wanglin2
4d4f1b993e Merge branch 'feature' into main 2023-07-30 21:55:37 +08:00
wanglin2
b814bd35ca 打包0.6.11-fix.1 2023-07-30 21:55:20 +08:00
wanglin2
c57361a360 Fix:修复节点文字为白色时编辑的时候看不见的问题 2023-07-30 21:53:32 +08:00
wanglin2
f8c2a62bd6 Merge branch 'feature' into main 2023-07-30 10:58:19 +08:00
wanglin2
59241717f5 打包0.6.11 2023-07-30 10:57:42 +08:00
wanglin2
e90509cac9 Doc: update 2023-07-30 10:56:35 +08:00
wanglin2
8a8cc26c1d Feat:优化小地图,去除小地图内的节点内容,优化性能 2023-07-30 10:51:38 +08:00
wanglin2
1d443b9f94 Doc: update 2023-07-30 09:44:00 +08:00
wanglin2
60a4f443a7 Demo:节点图片上传支持输入网络图片 2023-07-30 09:41:58 +08:00
wanglin2
72c2540dcc Merge branch 'feature' into main 2023-07-29 23:18:46 +08:00
wanglin2
18cec3b75a 打包 2023-07-29 23:18:18 +08:00
wanglin2
d4aae5268e Demo:1.新增主题;2.主题列表新增tab分类 2023-07-29 23:16:59 +08:00
61 changed files with 1646 additions and 180 deletions

View File

@@ -11,13 +11,13 @@
本项目包含两部分:
1.一个js思维导图库不依赖任何框架你可以使用它来快速完成Web思维导图产品的开发。
1.一个 js 思维导图库,不依赖任何框架,你可以使用它来快速完成 Web 思维导图产品的开发。
开发文档:[https://wanglin2.github.io/mind-map/#/doc/zh/](https://wanglin2.github.io/mind-map/#/doc/zh/)
开发文档:[https://wanglin2.github.io/mind-map/#/doc/zh/](https://wanglin2.github.io/mind-map/#/doc/zh/)
2.一个Web思维导图基于思维导图库、Vue2.x、ElementUI开发可以操作电脑本地文件所以你可以直接把它当做一个在线版思维导图应用使用如果觉得github的响应速度慢你也可以部署到你的服务器上。
2.一个 Web 思维导图基于思维导图库、Vue2.x、ElementUI 开发,可以操作电脑本地文件,所以你可以直接把它当做一个在线版思维导图应用使用,如果觉得 github 的响应速度慢,你也可以部署到你的服务器上。
在线地址:[https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/)
在线地址:[https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/)
另外也提供了客户端可供下载使用,支持`Windows``Mac``Linux`,下载地址:
@@ -28,18 +28,15 @@ Github[releases](https://github.com/wanglin2/mind-map/releases)。
# 特性
- [x] 插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小打包体积
- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图六种结构
- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴(横向、竖向)、鱼骨图结构
- [x] 内置多种主题,允许高度自定义样式,支持注册新主题
- [x] 支持快捷键
- [x] 节点内容支持图片、图标、超链接、备注、标签、概要
- [x] 支持前进后退
- [x] 支持拖动、缩放
- [x] 支持右键和Ctrl+左键两种多选方式
- [x] 支持节点自由拖拽、拖拽调整
- [x] 支持多种节点形状
- [x] 支持导出为`json``png``svg``pdf``markdown`,支持从`json``xmind``markdown`导入
- [x] 支持小地图、支持水印
- [x] 支持关联线
- [x] 节点内容支持文本(普通文本、富文本)、图片、图标、超链接、备注、标签、概要
- [x] 节点支持拖拽(拖拽移动、自由调整)、多种节点形状,支持使用 DDM 完全自定义节点内容
- [x] 支持画布拖动、缩放
- [x] 支持鼠标按键拖动选择和Ctrl+左键两种多选节点方式
- [x] 支持导出为`json``png``svg``pdf``markdown``xmind`,支持从`json``xmind``markdown`导入
- [x] 支持快捷键、前进后退、关联线、搜索替换、小地图、水印
- [x] 提供丰富的配置,满足各种场景各种使用习惯
# 安装

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 182 KiB

View File

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

View File

@@ -137,7 +137,7 @@ export const themeList = [
{
name: '简约黑',
value: 'simpleBlack',
dark: true
dark: false
},
{
name: '课程绿',

View File

@@ -266,6 +266,7 @@ class Node {
paddingY += this.shapePadding.paddingY
// 节点形状
this.shapeNode = this.shapeInstance.createShape()
this.shapeNode.addClass('smm-node-shape')
this.group.add(this.shapeNode)
this.updateNodeShape()
// 渲染一个隐藏的矩形区域,用来触发展开收起按钮的显示
@@ -531,6 +532,7 @@ class Node {
isLayout = true
// 创建组
this.group = new G()
this.group.addClass('smm-node')
this.group.css({
cursor: 'default'
})

View File

@@ -1,3 +1,5 @@
import { isWhite, isTransparent, getVisibleColorFromTheme } from '../utils/index'
// 小地图插件
class MiniMap {
// 构造函数
@@ -20,7 +22,7 @@ class MiniMap {
* boxHeight小地图容器的高度
*/
calculationMiniMap(boxWidth, boxHeight) {
let { svgHTML, rect, origWidth, origHeight, scaleX, scaleY } =
let { svg, rect, origWidth, origHeight, scaleX, scaleY } =
this.mindMap.getSvgData()
// 计算数据
let boxRatio = boxWidth / boxHeight
@@ -65,8 +67,10 @@ class MiniMap {
Math.max(0, ((_rectY2 - origHeight) / _rectHeight) * actHeight) +
miniMapBoxTop +
'px'
this.removeNodeContent(svg)
return {
svgHTML, // 小地图html
svgHTML: svg.svg(), // 小地图html
viewBoxStyle, // 视图框的位置信息
miniMapBoxScale, // 视图框的缩放值
miniMapBoxLeft, // 视图框的left值
@@ -74,6 +78,26 @@ class MiniMap {
}
}
// 移除节点的内容
removeNodeContent(svg) {
if (svg.hasClass('smm-node')) {
let shape = svg.findOne('.smm-node-shape')
let fill = shape.attr('fill')
if (isWhite(fill) || isTransparent(fill)) {
shape.attr('fill', getVisibleColorFromTheme(this.mindMap.themeConfig))
}
svg.clear()
svg.add(shape)
return
}
let children = svg.children()
if (children && children.length > 0) {
children.forEach((node) => {
this.removeNodeContent(node)
})
}
}
// 小地图鼠标按下事件
onMousedown(e) {
this.isMousedown = true

View File

@@ -1,7 +1,7 @@
import Quill from 'quill'
import 'quill/dist/quill.snow.css'
import html2canvas from 'html2canvas'
import { walk, getTextFromHtml } from '../utils'
import { walk, getTextFromHtml, isWhite, getVisibleColorFromTheme } from '../utils'
import { CONSTANTS } from '../constants/constant'
let extended = false
@@ -176,11 +176,12 @@ class RichText {
}
// 使用节点的填充色,否则如果节点颜色是白色的话编辑时看不见
let bgColor = node.style.merge('fillColor')
let color = node.style.merge('color')
this.textEditNode.style.marginLeft = `-${paddingX * scaleX}px`
this.textEditNode.style.marginTop = `-${paddingY * scaleY}px`
this.textEditNode.style.zIndex = this.mindMap.opt.nodeTextEditZIndex
this.textEditNode.style.backgroundColor =
bgColor === 'transparent' ? '#fff' : bgColor
bgColor === 'transparent' ? isWhite(color) ? getVisibleColorFromTheme(this.mindMap.themeConfig) : '#fff' : bgColor
this.textEditNode.style.minWidth = originWidth + paddingX * 2 + 'px'
this.textEditNode.style.minHeight = originHeight + 'px'
this.textEditNode.style.left = rect.left + 'px'

View File

@@ -515,4 +515,28 @@ export const replaceHtmlText = (html, searchText, replaceText) => {
}
walk(replaceHtmlTextEl)
return replaceHtmlTextEl.innerHTML
}
// 判断一个颜色是否是白色
export const isWhite = (color) => {
color = String(color).replaceAll(/\s+/g, '')
return ['#fff', '#ffffff', '#FFF', '#FFFFFF', 'rgb(255,255,255)'].includes(color) || /rgba\(255,255,255,[^)]+\)/.test(color)
}
// 判断一个颜色是否是透明
export const isTransparent = (color) => {
color = String(color).replaceAll(/\s+/g, '')
return ['', 'transparent'].includes(color) || /rgba\(\d+,\d+,\d+,0\)/.test(color)
}
// 从当前主题里获取一个非透明非白色的颜色
export const getVisibleColorFromTheme = (themeConfig) => {
let { lineColor, root, second, node } = themeConfig
let list = [lineColor, root.fillColor, root.color, second.fillColor, second.color, node.fillColor, node.color, root.borderColor, second.borderColor, node.borderColor]
for(let i = 0; i < list.length; i++) {
let color = list[i]
if (!isTransparent(color) && !isWhite(color)) {
return color
}
}
}

15
web/package-lock.json generated
View File

@@ -35,7 +35,8 @@
"prettier": "^1.19.1",
"vconsole": "^3.15.1",
"vue-template-compiler": "^2.6.11",
"webpack": "^4.44.2"
"webpack": "^4.44.2",
"webpack-dynamic-public-path": "^1.0.8"
}
},
"node_modules/@achrinza/node-ipc": {
@@ -16224,6 +16225,12 @@
"decamelize": "^1.2.0"
}
},
"node_modules/webpack-dynamic-public-path": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/webpack-dynamic-public-path/-/webpack-dynamic-public-path-1.0.8.tgz",
"integrity": "sha512-AF6onorpvmiC+I/dQ19SOi+oN66oEy9h4deam7gPs1Qa1mOQ9i7IRsOahaukohKAciys7NfX+YFboRn4rmpuKw==",
"dev": true
},
"node_modules/webpack-log": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
@@ -29476,6 +29483,12 @@
}
}
},
"webpack-dynamic-public-path": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/webpack-dynamic-public-path/-/webpack-dynamic-public-path-1.0.8.tgz",
"integrity": "sha512-AF6onorpvmiC+I/dQ19SOi+oN66oEy9h4deam7gPs1Qa1mOQ9i7IRsOahaukohKAciys7NfX+YFboRn4rmpuKw==",
"dev": true
},
"webpack-log": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",

View File

@@ -40,7 +40,8 @@
"prettier": "^1.19.1",
"vconsole": "^3.15.1",
"vue-template-compiler": "^2.6.11",
"webpack": "^4.44.2"
"webpack": "^4.44.2",
"webpack-dynamic-public-path": "^1.0.8"
},
"eslintConfig": {
"root": true,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 695 KiB

View File

@@ -4,8 +4,14 @@
<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.ico">
<link rel="icon" href="dist/logo.ico">
<title>思绪思维导图</title>
<script>
// 自定义静态资源的路径
window.externalPublicPath = './dist/'
// 接管应用
window.takeOverApp = false
</script>
</head>
<body>
<noscript>
@@ -13,5 +19,73 @@
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script>
const getDataFromBackend = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
mindMapData: {
root:{
"data": {
"text": "根节点"
},
"children": []
},
theme:{
"template":"avocado",
"config":{}
},
layout:"logicalStructure",
config: {},
view: null,
},
lang: 'zh',
localConfig: null
})
}, 200)
})
}
const setTakeOverAppMethods = (data) => {
window.takeOverAppMethods = {}
// 获取思维导图数据的函数
window.takeOverAppMethods.getMindMapData = () => {
return data.mindMapData
}
// 保存思维导图数据的函数
window.takeOverAppMethods.saveMindMapData = (data) => {
console.log(data)
}
// 获取语言的函数
window.takeOverAppMethods.getLanguage = () => {
return data.lang
}
// 保存语言的函数
window.takeOverAppMethods.saveLanguage = (lang) => {
console.log(lang)
}
// 获取本地配置的函数
window.takeOverAppMethods.getLocalConfig = () => {
return data.localConfig
}
// 保存本地配置的函数
window.takeOverAppMethods.saveLocalConfig = (config) => {
console.log(config)
}
}
window.onload = async () => {
if (!window.takeOverApp) return
// 请求数据
const data = await getDataFromBackend()
// 设置全局的方法
setTakeOverAppMethods(data)
// 思维导图实例创建完成事件
window.$bus.$on('app_inited', (mindMap) => {
console.log(mindMap)
})
// 可以通过window.$bus.$on()来监听应用的一些事件
// 实例化页面
window.initApp()
}
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -6,6 +6,8 @@ const SIMPLE_MIND_MAP_DATA = 'SIMPLE_MIND_MAP_DATA'
const SIMPLE_MIND_MAP_LANG = 'SIMPLE_MIND_MAP_LANG'
const SIMPLE_MIND_MAP_LOCAL_CONFIG = 'SIMPLE_MIND_MAP_LOCAL_CONFIG'
let mindMapData = null
/**
* @Author: 王林
* @Date: 2021-08-02 22:36:48
@@ -29,6 +31,10 @@ const copyMindMapTreeData = (tree, root) => {
* @Desc: 获取缓存的思维导图数据
*/
export const getData = () => {
if (window.takeOverApp) {
mindMapData = window.takeOverAppMethods.getMindMapData()
return mindMapData
}
let store = localStorage.getItem(SIMPLE_MIND_MAP_DATA)
if (store === null) {
return simpleDeepClone(exampleData)
@@ -48,8 +54,18 @@ export const getData = () => {
*/
export const storeData = data => {
try {
let originData = getData()
let originData = null
if (window.takeOverApp) {
originData = mindMapData
} else {
originData = getData()
}
originData.root = copyMindMapTreeData({}, data)
if (window.takeOverApp) {
mindMapData = originData
window.takeOverAppMethods.saveMindMapData(originData)
return
}
Vue.prototype.$bus.$emit('write_local_file', originData)
let dataStr = JSON.stringify(originData)
localStorage.setItem(SIMPLE_MIND_MAP_DATA, dataStr)
@@ -65,11 +81,21 @@ export const storeData = data => {
*/
export const storeConfig = config => {
try {
let originData = getData()
let originData = null
if (window.takeOverApp) {
originData = mindMapData
} else {
originData = getData()
}
originData = {
...originData,
...config
}
if (window.takeOverApp) {
mindMapData = originData
window.takeOverAppMethods.saveMindMapData(originData)
return
}
Vue.prototype.$bus.$emit('write_local_file', originData)
let dataStr = JSON.stringify(originData)
localStorage.setItem(SIMPLE_MIND_MAP_DATA, dataStr)
@@ -85,6 +111,10 @@ export const storeConfig = config => {
* @Desc: 存储语言
*/
export const storeLang = lang => {
if (window.takeOverApp) {
window.takeOverAppMethods.saveLanguage(lang)
return
}
localStorage.setItem(SIMPLE_MIND_MAP_LANG, lang)
}
@@ -95,6 +125,9 @@ export const storeLang = lang => {
* @Desc: 获取存储的语言
*/
export const getLang = () => {
if (window.takeOverApp) {
return window.takeOverAppMethods.getLanguage() || 'zh'
}
let lang = localStorage.getItem(SIMPLE_MIND_MAP_LANG)
if (lang) {
return lang
@@ -110,6 +143,9 @@ export const getLang = () => {
* @Desc: 存储本地配置
*/
export const storeLocalConfig = config => {
if (window.takeOverApp) {
return window.takeOverAppMethods.saveLocalConfig(config)
}
localStorage.setItem(SIMPLE_MIND_MAP_LOCAL_CONFIG, JSON.stringify(config))
}
@@ -120,6 +156,9 @@ export const storeLocalConfig = config => {
* @Desc: 获取本地配置
*/
export const getLocalConfig = () => {
if (window.takeOverApp) {
return window.takeOverAppMethods.getLocalConfig()
}
let config = localStorage.getItem(SIMPLE_MIND_MAP_LOCAL_CONFIG)
if (config) {
return JSON.parse(config)

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
web/src/assets/img/oreo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
web/src/assets/img/rose.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -44,5 +44,13 @@ export const themeMap = {
autumn: require('../assets/img/autumn.jpg'),
avocado: require('../assets/img/avocado.jpg'),
orangeJuice: require('../assets/img/orangeJuice.jpg'),
oreo: require('../assets/img/oreo.jpg'),
shallowSea: require('../assets/img/shallowSea.jpg'),
lemonBubbles: require('../assets/img/lemonBubbles.jpg'),
rose: require('../assets/img/rose.jpg'),
seaBlueLine: require('../assets/img/seaBlueLine.jpg'),
neonLamp: require('../assets/img/neonLamp.jpg'),
darkNightLceBlade: require('../assets/img/darkNightLceBlade.jpg'),
morandi: require('../assets/img/morandi.jpg'),
}

View File

@@ -0,0 +1,59 @@
// 暗夜冰刃
export default {
backgroundColor: 'rgb(0, 21, 21)',
// 连线的颜色
lineColor: 'rgb(0, 139, 146)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgba(2, 167, 240, 0.5)',
// 关联线默认状态的颜色
associativeLineColor: 'rgb(255, 255, 255)',
// 关联线文字颜色
associativeLineTextColor: 'rgb(255, 255, 255)',
// 根节点样式
root: {
fillColor: 'rgb(0, 243, 255)',
color: 'rgb(0, 21, 21)',
borderColor: '#fff',
borderWidth: 3,
fontSize: 24,
shape: 'parallelogram',
active: {
borderColor: 'rgba(2, 167, 240, 0.5)',
}
},
// 二级节点样式
second: {
fillColor: 'rgb(0, 21, 21)',
color: '#fff',
borderColor: '#fff',
borderWidth: 3,
fontSize: 18,
shape: 'diamond',
active: {
borderColor: 'rgba(2, 167, 240, 0.5)',
}
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: '#fff',
active: {
borderColor: 'rgba(2, 167, 240, 0.5)'
}
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '#fff',
borderColor: 'rgb(0, 117, 255)',
borderWidth: 2,
color: 'rgb(0, 21, 21)',
active: {
borderColor: 'rgb(0, 243, 255)'
}
}
}

View File

@@ -1,9 +1,59 @@
import simpleBlack from './simpleBlack'
import oreo from './oreo'
import shallowSea from './shallowSea'
import lemonBubbles from './lemonBubbles'
import rose from './rose'
import seaBlueLine from './seaBlueLine'
import neonLamp from './neonLamp'
import darkNightLceBlade from './darkNightLceBlade'
import morandi from './morandi'
export default [
{
name: '简约黑',
value: 'simpleBlack',
theme: simpleBlack
name: '奥利奥',
value: 'oreo',
theme: oreo,
dark: false
},
{
name: '浅海',
value: 'shallowSea',
theme: shallowSea,
dark: false
},
{
name: '柠檬气泡',
value: 'lemonBubbles',
theme: lemonBubbles,
dark: false
},
{
name: '玫瑰',
value: 'rose',
theme: rose,
dark: false
},
{
name: '海蓝线',
value: 'seaBlueLine',
theme: seaBlueLine,
dark: false
},
{
name: '霓虹灯',
value: 'neonLamp',
theme: neonLamp,
dark: true
},
{
name: '暗夜冰刃',
value: 'darkNightLceBlade',
theme: darkNightLceBlade,
dark: true
},
{
name: '莫兰迪',
value: 'morandi',
theme: morandi,
dark: false
}
]

View File

@@ -0,0 +1,55 @@
// 柠檬气泡
export default {
backgroundColor: 'rgb(236, 254, 255)',
// 连线的颜色
lineColor: 'rgb(51, 51, 51)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(51, 51, 51)',
// 根节点样式
root: {
fillColor: 'rgb(39, 222, 232)',
color: 'rgb(26, 26, 26)',
borderColor: 'rgb(26, 26, 26)',
borderWidth: 3,
fontSize: 24,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(235, 255, 187)',
}
},
// 二级节点样式
second: {
fillColor: 'rgb(235, 255, 187)',
color: 'rgb(0, 0, 0)',
borderColor: 'rgb(51, 51, 51)',
borderWidth: 3,
fontSize: 18,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(39, 222, 232)',
}
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(0, 0, 0)',
active: {
borderColor: 'rgb(39, 222, 232)'
}
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '#fff',
borderColor: 'rgb(26, 26, 26)',
borderWidth: 2,
color: 'rgb(26, 26, 26)',
active: {
borderColor: 'rgb(39, 222, 232)'
}
}
}

View File

@@ -0,0 +1,59 @@
// 莫兰迪
export default {
backgroundColor: 'rgb(252, 245, 241)',
// 连线的颜色
lineColor: 'rgb(144, 114, 110)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(128, 154, 151)',
// 关联线默认状态的颜色
associativeLineColor: 'rgb(166, 124, 106)',
// 关联线文字颜色
associativeLineTextColor: 'rgb(166, 124, 106)',
// 根节点样式
root: {
fillColor: 'rgb(207, 121, 105)',
color: '#fff',
borderColor: 'rgb(207, 121, 105)',
borderWidth: 3,
fontSize: 24,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(172, 202, 199)',
}
},
// 二级节点样式
second: {
fillColor: 'rgb(239, 210, 207)',
color: 'rgb(144, 79, 68)',
borderColor: 'rgb(222, 186, 183)',
borderWidth: 3,
fontSize: 18,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(172, 202, 199)',
}
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(131, 90, 64)',
active: {
borderColor: 'rgb(172, 202, 199)'
}
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: 'rgb(172, 202, 199)',
borderColor: 'rgb(172, 202, 199)',
borderWidth: 2,
color: 'rgb(91, 102, 97)',
active: {
borderColor: 'rgb(207, 121, 105)'
}
}
}

View File

@@ -0,0 +1,58 @@
// 霓虹灯
export default {
backgroundColor: 'rgb(17, 17, 84)',
// 连线的颜色
lineColor: 'rgb(255, 0, 214)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(255, 181, 0)',
// 关联线默认状态的颜色
associativeLineColor: 'rgb(255, 255, 255)',
// 关联线文字颜色
associativeLineTextColor: 'rgb(255, 255, 255)',
// 根节点样式
root: {
fillColor: 'rgb(251, 233, 248)',
color: 'rgb(208, 5, 176)',
borderColor: 'rgb(255, 0, 214)',
borderWidth: 3,
fontSize: 24,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(255, 181, 0)',
}
},
// 二级节点样式
second: {
fillColor: 'transparent',
color: 'rgb(248, 177, 237)',
borderColor: '',
borderWidth: 3,
fontSize: 18,
active: {
borderColor: 'rgb(255, 181, 0)',
}
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: '#fff',
active: {
borderColor: 'rgb(255, 181, 0)'
}
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '#fff',
borderColor: 'rgb(255, 181, 0)',
borderWidth: 2,
color: 'rgb(17, 17, 84)',
active: {
borderColor: 'rgb(255, 0, 214)'
}
}
}

View File

@@ -1,17 +1,17 @@
// 简约黑
// 奥利奥
export default {
// 连线的颜色
lineColor: 'rgb(34, 34, 34)',
lineWidth: 4,
lineColor: 'rgb(51, 51, 51)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 4,
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(34, 34, 34)',
generalizationLineColor: 'rgb(51, 51, 51)',
// 根节点样式
root: {
fillColor: '#fff',
color: 'rgb(34, 34, 34)',
borderColor: 'rgb(34, 34, 34)',
fillColor: 'rgb(22, 22, 22)',
color: '#fff',
borderColor: 'rgb(22, 22, 22)',
borderWidth: 3,
fontSize: 24,
active: {
@@ -20,21 +20,22 @@ export default {
},
// 二级节点样式
second: {
fillColor: 'rgb(241, 246, 248)',
color: 'rgb(34, 34, 34)',
borderColor: 'rgb(34, 34, 34)',
fillColor: 'rgb(244, 246, 253)',
color: 'rgb(0, 0, 0)',
borderColor: '',
borderWidth: 3,
fontSize: 18,
shape: 'roundedRectangle',
active: {
borderColor: '#a13600',
borderColor: 'rgb(22, 22, 22)',
}
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(34, 34, 34)',
color: 'rgb(0, 0, 0)',
active: {
borderColor: '#a13600'
borderColor: 'rgb(22, 22, 22)'
}
},
// 概要节点样式

View File

@@ -0,0 +1,55 @@
// 玫瑰
export default {
backgroundColor: 'rgb(255, 251, 231)',
// 连线的颜色
lineColor: 'rgb(110, 165, 79)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(136, 100, 0)',
// 根节点样式
root: {
fillColor: 'rgb(254, 92, 92)',
color: '#fff',
borderColor: 'rgb(18, 187, 55)',
borderWidth: 3,
fontSize: 24,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(136, 100, 0)',
}
},
// 二级节点样式
second: {
fillColor: 'rgb(209, 237, 176)',
color: 'rgb(85, 136, 55)',
borderColor: '',
borderWidth: 3,
fontSize: 18,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(254, 92, 92)',
}
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(26, 26, 26)',
active: {
borderColor: 'rgb(209, 237, 176)'
}
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '#fff',
borderColor: 'rgb(136, 100, 0)',
borderWidth: 2,
color: 'rgb(136, 100, 0)',
active: {
borderColor: 'rgb(254, 92, 92)'
}
}
}

View File

@@ -0,0 +1,55 @@
// 海蓝线
export default {
backgroundColor: 'rgb(231, 245, 255)',
// 连线的颜色
lineColor: 'rgb(96, 189, 255)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(0, 155, 255)',
// 根节点样式
root: {
fillColor: 'rgb(96, 189, 255)',
color: '#fff',
borderColor: '#fff',
borderWidth: 3,
fontSize: 24,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(0, 155, 255)',
}
},
// 二级节点样式
second: {
fillColor: '#fff',
color: 'rgb(0, 149, 255)',
borderColor: '',
borderWidth: 3,
fontSize: 18,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(96, 189, 255)',
}
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(0, 66, 157)',
active: {
borderColor: 'rgb(96, 189, 255)'
}
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '#fff',
borderColor: 'rgb(0, 155, 255)',
borderWidth: 2,
color: 'rgb(0, 155, 255)',
active: {
borderColor: 'rgba(2, 167, 240, 0.5)'
}
}
}

View File

@@ -0,0 +1,54 @@
// 浅海
export default {
backgroundColor: 'rgb(187, 241, 250)',
// 连线的颜色
lineColor: 'rgb(74, 139, 170)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(255, 168, 101)',
// 根节点样式
root: {
fillColor: 'rgb(51, 149, 255)',
color: '#fff',
borderColor: 'rgb(51, 149, 255)',
borderWidth: 3,
fontSize: 24,
shape: 'roundedRectangle',
active: {
borderColor: 'rgb(255, 168, 101)',
}
},
// 二级节点样式
second: {
fillColor: 'rgb(74, 139, 170)',
color: '#fff',
borderColor: '',
borderWidth: 3,
fontSize: 18,
active: {
borderColor: 'rgb(255, 168, 101)',
}
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(0, 0, 0)',
active: {
borderColor: 'rgb(255, 168, 101)'
}
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '#fff',
borderColor: 'rgb(255, 168, 101)',
borderWidth: 2,
color: '#000',
active: {
borderColor: 'rgb(51, 149, 255)'
}
}
}

View File

@@ -1,12 +1,10 @@
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import messages from './lang'
import { getLang } from '@/api'
Vue.use(VueI18n)
const i18n = new VueI18n({
locale: getLang(),
messages
})

View File

@@ -8,17 +8,31 @@ import '@/assets/icon-font/iconfont.css'
import 'viewerjs/dist/viewer.css'
import VueViewer from 'v-viewer'
import i18n from './i18n'
import { getLang } from '@/api'
// import VConsole from 'vconsole'
// const vConsole = new VConsole()
Vue.config.productionTip = false
Vue.prototype.$bus = new Vue()
const bus = new Vue()
Vue.prototype.$bus = bus
Vue.use(ElementUI)
Vue.use(VueViewer)
new Vue({
render: h => h(App),
router,
store,
i18n
}).$mount('#app')
const initApp = () => {
i18n.locale = getLang()
new Vue({
render: h => h(App),
router,
store,
i18n
}).$mount('#app')
}
// 是否处于接管应用模式
if (window.takeOverApp) {
window.initApp = initApp
window.$bus = bus
} else {
initApp()
}

View File

@@ -1,12 +1,22 @@
# Changelog
## 0.6.11-fix.1
Fix: 1.Fixed the issue of invisible editing when node text is white.
## 0.6.11
New: 1.Optimize the mini map, remove node content within the mini map, and optimize performance.
Demo: 1.Add a new topic and add tab differentiation to the topic list. 2.Node image upload supports inputting network image addresses. 3.Node image upload supports inputting network images.
## 0.6.10
Fix: 1.Fix the issue of deleting a node after searching for it and not updating the search results when searching again. 2.Fixed an issue where the button for adjusting image size did not update after node operation. 3.Fix the issue of incorrect internal data deep copy location. 4.Fix the issue of ineffective line wrapping in rich text nodes. 5. Fix the issue of node swapping and loss when switching themes and other scenarios.
New: 1.Search supports searching for white space characters and replacing them with white space characters.
Demo: 1.Support calling up search through icon buttons. 2.Support for switching to dark mode through icon buttons. 3.Optimize search: The mouse is not in the search area and not focused, solving the problem of not being able to delete input text when the mouse is not in the search area. 4.Adjust the interface UI for adding node icons and add a series of node icons. 5.Add a sticker list. 6.Fixed the issue of missing focus in the input box after entering the search box. 7.Support clicking on the icon within the node to display an icon for quick replacement and deletion of the floating panel.
Demo: 1.Support calling up search through icon buttons. 2.Support for switching to dark mode through icon buttons. 3.Optimize search: The mouse is not in the search area and not focused, solving the problem of not being able to delete input text when the mouse is not in the search area. 4.Adjust the interface UI for adding node icons and add a series of node icons. 5.Add a sticker list. 6.Fixed the issue of missing focus in the input box after entering the search box. 7.Support clicking on the icon within the node to display an icon for quick replacement and deletion of the floating panel.
## 0.6.9-fix.1

View File

@@ -1,6 +1,11 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.6.11-fix.1</h2>
<p>Fix: 1.Fixed the issue of invisible editing when node text is white.</p>
<h2>0.6.11</h2>
<p>New: 1.Optimize the mini map, remove node content within the mini map, and optimize performance.</p>
<p>Demo: 1.Add a new topic and add tab differentiation to the topic list. 2.Node image upload supports inputting network image addresses. 3.Node image upload supports inputting network images.</p>
<h2>0.6.10</h2>
<p>Fix: 1.Fix the issue of deleting a node after searching for it and not updating the search results when searching again. 2.Fixed an issue where the button for adjusting image size did not update after node operation. 3.Fix the issue of incorrect internal data deep copy location. 4.Fix the issue of ineffective line wrapping in rich text nodes. 5. Fix the issue of node swapping and loss when switching themes and other scenarios.</p>
<p>New: 1.Search supports searching for white space characters and replacing them with white space characters.</p>

View File

@@ -40,7 +40,7 @@ If you want to package 'index.html' into the 'dist' directory as well, you can m
If you want to modify the directory for packaging output, you can modify the 'outputDir' configuration of the 'web/vue.config.js' file to the path you want to output.
If you want to modify the path of the 'index. html' file referencing static resources, you can modify the 'publicPath' configuration of the 'web/vue.config.js' file.
If you want to modify the path of the 'index. html' file referencing static resources, you can modify the 'publicPath' configuration of the 'web/vue.config.js' file. And the `window.externalPublicPath` config in `web/public/index.html` file.
In addition, the default route used is 'hash ', which means that there will be '#'in the path. If you want to use the 'history' route, you can modify the 'web/src/router.js' file to:
@@ -63,4 +63,167 @@ However, this requires backend support, as our application is a single page clie
## Docker
In writing...
## Docker
> Thank you very much [水车](https://github.com/shuiche-it), This section is written by him, and the corresponding Docker package is also maintained by him.
Install directly from Docker Hub:
```
docker run -d -p 8081:8080 shuiche/mind-map:latest
```
Mindmap has activated port 8080 as the web service entry point in the container. When running the container through Docker, it is necessary to specify a local mapping port. In the above case, we mapped the local port 8081 to the container port 8080.
After the installation is completed, check the container's running status through 'Docker PS'.
Open 127.0.0.1:8081 in the browser to use the Web mind map function.
## Docking with one's own storage services
The application data is stored locally in the browser by default, and the local storage capacity of the browser is relatively small, so it is easy to trigger restrictions when inserting more images in the mind map. Therefore, a better choice is to dock with your own storage service, which usually has two ways:
### The first
Simply clone the warehouse code and modify the relevant methods in 'web/src/API/index.js' to obtain data from your database and store it in your data.
### The second
Many times, you may want to always use the latest code from this repository, so the first method is not very convenient because you need to manually merge the code, so the second method is provided.
Specific operating steps:
1. Copy the packaged resources of the web application
This includes the 'dist' directory and the 'index.html' file.
2. Modify the copied 'index.html' file
Firstly, insert the following code into the 'head' tag:
```js
<script>
window.takeOverApp = true
</script>
```
This line of code will prompt the application not to initialize the application 'i.e.: new Vue()', but to give control to you. Next, insert your own 'js' code at the end of the 'body', either inline or out of chain. The inline example is as follows:
```js
<script>
// Your own method of requesting data
const getDataFromBackend = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
// MindMap data
mindMapData: {
root: {
"data": {
"text": "根节点"
},
"children": []
},
theme: { "template":"avocado","config":{} },
layout: "logicalStructure",
config: {},
view: {}
},
// Page language, supporting Chinese (zh) and English (en)
lang: 'zh',
// Page Section Configuration
localConfig: null
})
}, 200)
})
}
// Register Global Method
const setTakeOverAppMethods = (data) => {
window.takeOverAppMethods = {}
// Function for obtaining mind map data
window.takeOverAppMethods.getMindMapData = () => {
return data.mindMapData
}
// Functions for Saving Mind Map Data
window.takeOverAppMethods.saveMindMapData = (data) => {
console.log(data)
// The trigger frequency of this function may be high, so you should do throttling or anti shaking measures
}
// Function to obtain language
window.takeOverAppMethods.getLanguage = () => {
return data.lang
}
// Functions for Saving Languages
window.takeOverAppMethods.saveLanguage = (lang) => {
console.log(lang)
}
// Get locally configured functions
window.takeOverAppMethods.getLocalConfig = () => {
return data.localConfig
}
// Save locally configured functions
window.takeOverAppMethods.saveLocalConfig = (config) => {
console.log(config)
}
}
window.onload = async () => {
if (!window.takeOverApp) return
// request data
const data = await getDataFromBackend()
// Method for setting global
setTakeOverAppMethods(data)
// Mind Map Instance Creation Completion Event
window.$bus.$on('app_inited', (mindMap) => {
console.log(mindMap)
})
// You can use window$ Bus$ On() to listen for some events in the application
// Instantiate Page
window.initApp()
}
</script>
```
As shown above, when you set the 'window.takeOverApp=true' flag, the application will no longer actively instantiate, but will expose the instantiated methods for you to call. You can first request the data of the mind map from the backend, and then register the relevant methods. The application will call internally at the appropriate time to achieve the purpose of echo and save.
The advantage of doing this is that whenever the code in this repository is updated, you can simply copy the packaged files to your own server. With a slight modification of the 'index. html' page, you can achieve synchronous updates and use your own storage service.
## Modifying Static Resource Paths
If you want to maintain synchronous updates with the code in this repository as in the previous section, but also want to modify the storage location of static resources, for example, the default hierarchical relationship is:
```
-dist
--css
--fonts
--img
--js
-logo.ico
-index.html
```
And you want to adjust it to this:
```
-assets
--dist
---css
---fonts
---img
---js
-logo.ico
-index.html
```
So you can configure the 'window.externalPublicPath' in 'index.html' as the default `./dist/` is modified to:
```js
window.externalPublicPath = './assets/dist/'
```
At the same time, the paths of the inline '.ico', '.js', and '.css' resources in 'index.html' need to be manually modified by you.
It should be noted that it is best not to adjust the directory hierarchy within the 'dist' directory, otherwise exceptions may occur.
If you want to replace some of the static resources, such as the theme image and structure image, with your own designed image, you can directly overwrite it with the same name.

View File

@@ -25,7 +25,7 @@ npm link simple-mind-map
<p>If you do not have any code modification requirements, it is also possible to directly copy these files from this repository.</p>
<p>If you want to package 'index.html' into the 'dist' directory as well, you can modify the 'scripts.build' command in the 'web/package.json' file to delete '&amp;&amp; node ../copy.js' from 'vue-cli-service build &amp;&amp; node ../copy.js'.</p>
<p>If you want to modify the directory for packaging output, you can modify the 'outputDir' configuration of the 'web/vue.config.js' file to the path you want to output.</p>
<p>If you want to modify the path of the 'index. html' file referencing static resources, you can modify the 'publicPath' configuration of the 'web/vue.config.js' file.</p>
<p>If you want to modify the path of the 'index. html' file referencing static resources, you can modify the 'publicPath' configuration of the 'web/vue.config.js' file. And the <code>window.externalPublicPath</code> config in <code>web/public/index.html</code> file.</p>
<p>In addition, the default route used is 'hash ', which means that there will be '#'in the path. If you want to use the 'history' route, you can modify the 'web/src/router.js' file to:</p>
<pre class="hljs"><code><span class="hljs-keyword">const</span> router = <span class="hljs-keyword">new</span> VueRouter({
routes
@@ -39,7 +39,138 @@ npm link simple-mind-map
</code></pre>
<p>However, this requires backend support, as our application is a single page client application. If the backend is not properly configured, users will return 404 when accessing sub routes directly in the browser. Therefore, you need to add a candidate resource on the server that covers all situations: if the 'URL' cannot match any static resources, the same 'index. html' page should be returned.</p>
<h2>Docker</h2>
<p>In writing...</p>
<h2>Docker</h2>
<blockquote>
<p>Thank you very much <a href="https://github.com/shuiche-it">水车</a>, This section is written by him, and the corresponding Docker package is also maintained by him.</p>
</blockquote>
<p>Install directly from Docker Hub:</p>
<pre class="hljs"><code>docker run -d -p 8081:8080 shuiche/mind-map:latest
</code></pre>
<p>Mindmap has activated port 8080 as the web service entry point in the container. When running the container through Docker, it is necessary to specify a local mapping port. In the above case, we mapped the local port 8081 to the container port 8080.</p>
<p>After the installation is completed, check the container's running status through 'Docker PS'.</p>
<p>Open 127.0.0.1:8081 in the browser to use the Web mind map function.</p>
<h2>Docking with one's own storage services</h2>
<p>The application data is stored locally in the browser by default, and the local storage capacity of the browser is relatively small, so it is easy to trigger restrictions when inserting more images in the mind map. Therefore, a better choice is to dock with your own storage service, which usually has two ways:</p>
<h3>The first</h3>
<p>Simply clone the warehouse code and modify the relevant methods in 'web/src/API/index.js' to obtain data from your database and store it in your data.</p>
<h3>The second</h3>
<p>Many times, you may want to always use the latest code from this repository, so the first method is not very convenient because you need to manually merge the code, so the second method is provided.</p>
<p>Specific operating steps:</p>
<ol>
<li>Copy the packaged resources of the web application</li>
</ol>
<p>This includes the 'dist' directory and the 'index.html' file.</p>
<ol start="2">
<li>Modify the copied 'index.html' file</li>
</ol>
<p>Firstly, insert the following code into the 'head' tag:</p>
<pre class="hljs"><code>&lt;script&gt;
<span class="hljs-built_in">window</span>.takeOverApp = <span class="hljs-literal">true</span>
&lt;/script&gt;
</code></pre>
<p>This line of code will prompt the application not to initialize the application 'i.e.: new Vue()', but to give control to you. Next, insert your own 'js' code at the end of the 'body', either inline or out of chain. The inline example is as follows:</p>
<pre class="hljs"><code>&lt;script&gt;
<span class="hljs-comment">// Your own method of requesting data</span>
<span class="hljs-keyword">const</span> getDataFromBackend = <span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
resolve({
<span class="hljs-comment">// MindMap data</span>
<span class="hljs-attr">mindMapData</span>: {
<span class="hljs-attr">root</span>: {
<span class="hljs-string">&quot;data&quot;</span>: {
<span class="hljs-string">&quot;text&quot;</span>: <span class="hljs-string">&quot;根节点&quot;</span>
},
<span class="hljs-string">&quot;children&quot;</span>: []
},
<span class="hljs-attr">theme</span>: { <span class="hljs-string">&quot;template&quot;</span>:<span class="hljs-string">&quot;avocado&quot;</span>,<span class="hljs-string">&quot;config&quot;</span>:{} },
<span class="hljs-attr">layout</span>: <span class="hljs-string">&quot;logicalStructure&quot;</span>,
<span class="hljs-attr">config</span>: {},
<span class="hljs-attr">view</span>: {}
},
<span class="hljs-comment">// Page language, supporting Chinese (zh) and English (en)</span>
<span class="hljs-attr">lang</span>: <span class="hljs-string">&#x27;zh&#x27;</span>,
<span class="hljs-comment">// Page Section Configuration</span>
<span class="hljs-attr">localConfig</span>: <span class="hljs-literal">null</span>
})
}, <span class="hljs-number">200</span>)
})
}
<span class="hljs-comment">// Register Global Method</span>
<span class="hljs-keyword">const</span> setTakeOverAppMethods = <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
<span class="hljs-built_in">window</span>.takeOverAppMethods = {}
<span class="hljs-comment">// Function for obtaining mind map data</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.getMindMapData = <span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">return</span> data.mindMapData
}
<span class="hljs-comment">// Functions for Saving Mind Map Data</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.saveMindMapData = <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
<span class="hljs-built_in">console</span>.log(data)
<span class="hljs-comment">// The trigger frequency of this function may be high, so you should do throttling or anti shaking measures</span>
}
<span class="hljs-comment">// Function to obtain language</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.getLanguage = <span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">return</span> data.lang
}
<span class="hljs-comment">// Functions for Saving Languages</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.saveLanguage = <span class="hljs-function">(<span class="hljs-params">lang</span>) =&gt;</span> {
<span class="hljs-built_in">console</span>.log(lang)
}
<span class="hljs-comment">// Get locally configured functions</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.getLocalConfig = <span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">return</span> data.localConfig
}
<span class="hljs-comment">// Save locally configured functions</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.saveLocalConfig = <span class="hljs-function">(<span class="hljs-params">config</span>) =&gt;</span> {
<span class="hljs-built_in">console</span>.log(config)
}
}
<span class="hljs-built_in">window</span>.onload = <span class="hljs-keyword">async</span> () =&gt; {
<span class="hljs-keyword">if</span> (!<span class="hljs-built_in">window</span>.takeOverApp) <span class="hljs-keyword">return</span>
<span class="hljs-comment">// request data</span>
<span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> getDataFromBackend()
<span class="hljs-comment">// Method for setting global</span>
setTakeOverAppMethods(data)
<span class="hljs-comment">// Mind Map Instance Creation Completion Event</span>
<span class="hljs-built_in">window</span>.$bus.$on(<span class="hljs-string">&#x27;app_inited&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">mindMap</span>) =&gt;</span> {
<span class="hljs-built_in">console</span>.log(mindMap)
})
<span class="hljs-comment">// You can use window$ Bus$ On() to listen for some events in the application</span>
<span class="hljs-comment">// Instantiate Page</span>
<span class="hljs-built_in">window</span>.initApp()
}
&lt;/script&gt;
</code></pre>
<p>As shown above, when you set the 'window.takeOverApp=true' flag, the application will no longer actively instantiate, but will expose the instantiated methods for you to call. You can first request the data of the mind map from the backend, and then register the relevant methods. The application will call internally at the appropriate time to achieve the purpose of echo and save.</p>
<p>The advantage of doing this is that whenever the code in this repository is updated, you can simply copy the packaged files to your own server. With a slight modification of the 'index. html' page, you can achieve synchronous updates and use your own storage service.</p>
<h2>Modifying Static Resource Paths</h2>
<p>If you want to maintain synchronous updates with the code in this repository as in the previous section, but also want to modify the storage location of static resources, for example, the default hierarchical relationship is:</p>
<pre class="hljs"><code>-dist
--css
--fonts
--img
--js
-logo.ico
-index.html
</code></pre>
<p>And you want to adjust it to this:</p>
<pre class="hljs"><code>-assets
--dist
---css
---fonts
---img
---js
-logo.ico
-index.html
</code></pre>
<p>So you can configure the 'window.externalPublicPath' in 'index.html' as the default <code>./dist/</code> is modified to:</p>
<pre class="hljs"><code><span class="hljs-built_in">window</span>.externalPublicPath = <span class="hljs-string">&#x27;./assets/dist/&#x27;</span>
</code></pre>
<p>At the same time, the paths of the inline '.ico', '.js', and '.css' resources in 'index.html' need to be manually modified by you.</p>
<p>It should be noted that it is best not to adjust the directory hierarchy within the 'dist' directory, otherwise exceptions may occur.</p>
<p>If you want to replace some of the static resources, such as the theme image and structure image, with your own designed image, you can directly overwrite it with the same name.</p>
</div>
</template>

View File

@@ -8,21 +8,16 @@
## Features
- [x] Plugin architecture. In addition to core functions, other functions are provided as plugins, which can be used as needed to reduce the overall volume
- [x] Supports six types of structures: logical structure diagrams, mind maps,
organizational structure diagrams, directory organization diagrams, timeline, and fishbone diagrams
- [x] Built-in multiple themes and allows for highly customized styles, and support register new themes
- [x] Supports shortcuts
- [x] Node content supports images, icons, hyperlinks, notes, tags, and
summaries
- [x] Supports forward and backward navigation
- [x] Supports dragging and scaling
- [x] Supports right-click and Ctrl + left-click to select multiple items
- [x] Supports free dragging and dragging to adjust nodes
- [x] Supports various node shapes
- [x] Supports export to json, png, svg, pdf markdown, and import from json, xmind, markdown
- [x] Supports mini map、support watermark
- [x] Supports associative lines
- [x] Pluggable architecture, in addition to core functions, other functions are provided as plugins, which can be used as needed to reduce packaging volume
- [x] Support logical structure chart, mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures
- [x] Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes
- [x] Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, and summaries
- [x] Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, and fully customize node content using DDM
- [x] Support canvas dragging and scaling
- [x] Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection
- [x] Supoorts to export as `json``png``svg``pdf``markdown``xmind`, support import from `json``xmind``markdown`
- [x] Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, and watermarks
- [x] Provide rich configurations to meet various scenarios and usage habits
## Repository Catalog Introduction

View File

@@ -8,21 +8,16 @@
</blockquote>
<h2>Features</h2>
<ul>
<li><input type="checkbox" id="checkbox18" checked="true" /><label for="checkbox18">Plugin architecture. In addition to core functions, other functions are provided as plugins, which can be used as needed to reduce the overall volume</label></li>
<li><input type="checkbox" id="checkbox19" checked="true" /><label for="checkbox19">Supports six types of structures: logical structure diagrams, mind maps,</label>
organizational structure diagrams, directory organization diagrams, timeline, and fishbone diagrams</li>
<li><input type="checkbox" id="checkbox20" checked="true" /><label for="checkbox20">Built-in multiple themes and allows for highly customized styles, and support register new themes</label></li>
<li><input type="checkbox" id="checkbox21" checked="true" /><label for="checkbox21">Supports shortcuts</label></li>
<li><input type="checkbox" id="checkbox22" checked="true" /><label for="checkbox22">Node content supports images, icons, hyperlinks, notes, tags, and</label>
summaries</li>
<li><input type="checkbox" id="checkbox23" checked="true" /><label for="checkbox23">Supports forward and backward navigation</label></li>
<li><input type="checkbox" id="checkbox24" checked="true" /><label for="checkbox24">Supports dragging and scaling</label></li>
<li><input type="checkbox" id="checkbox25" checked="true" /><label for="checkbox25">Supports right-click and Ctrl + left-click to select multiple items</label></li>
<li><input type="checkbox" id="checkbox26" checked="true" /><label for="checkbox26">Supports free dragging and dragging to adjust nodes</label></li>
<li><input type="checkbox" id="checkbox27" checked="true" /><label for="checkbox27">Supports various node shapes</label></li>
<li><input type="checkbox" id="checkbox28" checked="true" /><label for="checkbox28">Supports export to json, png, svg, pdf markdown, and import from json, xmind, markdown</label></li>
<li><input type="checkbox" id="checkbox29" checked="true" /><label for="checkbox29">Supports mini mapsupport watermark</label></li>
<li><input type="checkbox" id="checkbox30" checked="true" /><label for="checkbox30">Supports associative lines</label></li>
<li><input type="checkbox" id="checkbox30" checked="true" /><label for="checkbox30">Pluggable architecture, in addition to core functions, other functions are provided as plugins, which can be used as needed to reduce packaging volume</label></li>
<li><input type="checkbox" id="checkbox31" checked="true" /><label for="checkbox31">Support logical structure chart, mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures</label></li>
<li><input type="checkbox" id="checkbox32" checked="true" /><label for="checkbox32">Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes</label></li>
<li><input type="checkbox" id="checkbox33" checked="true" /><label for="checkbox33">Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, and summaries</label></li>
<li><input type="checkbox" id="checkbox34" checked="true" /><label for="checkbox34">Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, and fully customize node content using DDM</label></li>
<li><input type="checkbox" id="checkbox35" checked="true" /><label for="checkbox35">Support canvas dragging and scaling</label></li>
<li><input type="checkbox" id="checkbox36" checked="true" /><label for="checkbox36">Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection</label></li>
<li><input type="checkbox" id="checkbox37" checked="true" /><label for="checkbox37">Supoorts to export as </label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code><code>xmind</code>, support import from <code>json</code><code>xmind</code><code>markdown</code></li>
<li><input type="checkbox" id="checkbox38" checked="true" /><label for="checkbox38">Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, and watermarks</label></li>
<li><input type="checkbox" id="checkbox39" checked="true" /><label for="checkbox39">Provide rich configurations to meet various scenarios and usage habits</label></li>
</ul>
<h2>Repository Catalog Introduction</h2>
<p>1.<code>simple-mind-map</code></p>
@@ -32,16 +27,16 @@ frameworks such as Vue and React, or without a framework.</p>
<p>This is an online mind map built using the <code>simple-mind-map</code> library and based
on <code>Vue2.x</code> and <code>ElementUI</code>. Features include:</p>
<ul>
<li><input type="checkbox" id="checkbox31" checked="true" /><label for="checkbox31">Toolbar, which supports inserting and deleting nodes, and editing node</label>
<li><input type="checkbox" id="checkbox40" checked="true" /><label for="checkbox40">Toolbar, which supports inserting and deleting nodes, and editing node</label>
images, icons, hyperlinks, notes, tags, and summaries</li>
<li><input type="checkbox" id="checkbox32" checked="true" /><label for="checkbox32">Sidebar, with panels for basic style settings, node style settings,</label>
<li><input type="checkbox" id="checkbox41" checked="true" /><label for="checkbox41">Sidebar, with panels for basic style settings, node style settings,</label>
outline, theme selection, and structure selection</li>
<li><input type="checkbox" id="checkbox33" checked="true" /><label for="checkbox33">Import and export functionality; data is saved in the browser's local</label>
<li><input type="checkbox" id="checkbox42" checked="true" /><label for="checkbox42">Import and export functionality; data is saved in the browser's local</label>
storage by default, but it also supports creating, opening, and editing
local files on the computer directly</li>
<li><input type="checkbox" id="checkbox34" checked="true" /><label for="checkbox34">Right-click menu, which supports operations such as expanding, collapsing,</label>
<li><input type="checkbox" id="checkbox43" checked="true" /><label for="checkbox43">Right-click menu, which supports operations such as expanding, collapsing,</label>
and organizing layout</li>
<li><input type="checkbox" id="checkbox35" checked="true" /><label for="checkbox35">Bottom bar, which supports node and word count statistics, switching</label>
<li><input type="checkbox" id="checkbox44" checked="true" /><label for="checkbox44">Bottom bar, which supports node and word count statistics, switching</label>
between edit and read-only modes, zooming in and out, and switching to
full screen, support mini map</li>
</ul>

View File

@@ -47,6 +47,15 @@ Small map idea:
1.Prepare a container element `container`, position is not `static`
If using rich text editing mode, it is best to remove the default style from the elements inside the 'container', otherwise there may be text offset issues within nodes:
```css
.container * {
margin: 0;
padding: 0;
}
```
2.In `container`, create a small map container element `miniMapContainer`,
absolute positioning

View File

@@ -34,6 +34,12 @@ MindMap.usePlugin(MiniMap)
</code></pre>
<p>Small map idea:</p>
<p>1.Prepare a container element <code>container</code>, position is not <code>static</code></p>
<p>If using rich text editing mode, it is best to remove the default style from the elements inside the 'container', otherwise there may be text offset issues within nodes:</p>
<pre class="hljs"><code><span class="hljs-selector-class">.container</span> * {
<span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
<span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
}
</code></pre>
<p>2.In <code>container</code>, create a small map container element <code>miniMapContainer</code>,
absolute positioning</p>
<p>3.In <code>container</code>, create a view box element <code>viewBoxContainer</code>, absolute

View File

@@ -220,6 +220,16 @@ Add inline styles to the specified tags in the HTML tag.
Check if a string is a rich text character.
#### isWhite(color)
> v0.6.11+
Determine whether a color is white.
#### isTransparent(color)
Determine whether a color is transparent.
## Simulate CSS background in Canvas
Import:

View File

@@ -154,6 +154,13 @@ and copying the <code>data</code> of the data object, example:</p>
<p>v0.6.10+</p>
</blockquote>
<p>Check if a string is a rich text character.</p>
<h4>isWhite(color)</h4>
<blockquote>
<p>v0.6.11+</p>
</blockquote>
<p>Determine whether a color is white.</p>
<h4>isTransparent(color)</h4>
<p>Determine whether a color is transparent.</p>
<h2>Simulate CSS background in Canvas</h2>
<p>Import:</p>
<pre class="hljs"><code><span class="hljs-keyword">import</span> drawBackgroundImageToCanvas <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map/src/utils/simulateCSSBackgroundInCanvas&#x27;</span>

View File

@@ -1,12 +1,22 @@
# Changelog
## 0.6.11-fix.1
修复1.修复节点文字为白色时编辑的时候看不见的问题。
## 0.6.11
新增1.优化小地图,去除小地图内的节点内容,优化性能。
Demo1.新增主题、主题列表新增tab区分。 2.节点图片上传支持输入网络图片地址。 3.节点图片上传支持输入网络图片。
## 0.6.10
修复1.修复搜索定位到某个节点后删除该节点,再次搜索时搜索结果未更新的问题。 2.修复调整图片大小的按钮在节点操作后没有更新的问题。 3.修复内部数据深拷贝位置不正确的问题。 4.修复富文本节点换行不生效的问题。 5.修复切换主题等场景时节点换行会丢失的问题。
新增1.搜索支持搜索空白字符和替换为空白字符。
Demo1.支持通过图标按钮调出搜索。 2.支持通过图标按钮切换暗黑模式。 3.优化搜索:鼠标不在搜索区域内不聚焦,解决鼠标不在搜索区域内无法删除输入的文字的问题。 4.调整添加节点图标的界面UI新增系列节点图标。 5.新增贴纸列表。 6.修复在搜索框回车后输入框焦点丢失的问题。 7.支持点击节点内的图标显示一个图标快捷替换和删除悬浮面板。
Demo1.支持通过图标按钮调出搜索。 2.支持通过图标按钮切换暗黑模式。 3.优化搜索:鼠标不在搜索区域内不聚焦,解决鼠标不在搜索区域内无法删除输入的文字的问题。 4.调整添加节点图标的界面UI新增系列节点图标。 5.新增贴纸列表。 6.修复在搜索框回车后输入框焦点丢失的问题。 7.支持点击节点内的图标显示一个图标快捷替换和删除悬浮面板。
## 0.6.9-fix.1

View File

@@ -1,6 +1,11 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.6.11-fix.1</h2>
<p>修复1.修复节点文字为白色时编辑的时候看不见的问题</p>
<h2>0.6.11</h2>
<p>新增1.优化小地图,去除小地图内的节点内容,优化性能</p>
<p>Demo1.新增主题主题列表新增tab区分 2.节点图片上传支持输入网络图片地址 3.节点图片上传支持输入网络图片</p>
<h2>0.6.10</h2>
<p>修复1.修复搜索定位到某个节点后删除该节点再次搜索时搜索结果未更新的问题 2.修复调整图片大小的按钮在节点操作后没有更新的问题 3.修复内部数据深拷贝位置不正确的问题 4.修复富文本节点换行不生效的问题 5.修复切换主题等场景时节点换行会丢失的问题</p>
<p>新增1.搜索支持搜索空白字符和替换为空白字符</p>

View File

@@ -40,7 +40,7 @@ npm run build
如果你想修改打包输出的目录,可以修改`web/vue.config.js`文件的`outputDir`配置,改成你想要输出的路径即可。
如果你想修改`index.html`文件引用静态资源的路径的话可以修改`web/vue.config.js`文件的`publicPath`配置。
如果你想修改`index.html`文件引用静态资源的路径的话可以修改`web/vue.config.js`文件的`publicPath`配置。以及`web/public/index.html`文件的`window.externalPublicPath`配置。
另外默认使用的是`hash`路由,也就是路径中会在`#`,如果你想使用`history`路由,可以修改`web/src/router.js`文件,将:
@@ -63,4 +63,165 @@ const router = new VueRouter({
## Docker
编写中。。
> 非常感谢[水车](https://github.com/shuiche-it),本小节由他编写,对应的 Docker 包也由他维护
直接从 Docker hup 中安装:
```
docker run -d -p 8081:8080 shuiche/mind-map:latest
```
mind-map在容器中启动了8080端口作为web服务入口通过docker运行容器时需要指定本地映射端口上面案例中我们通过本地的8081端口映射到容器端口8080。
安装完成后,通过 `docker ps` 查看容器运行状态。
浏览器打开 127.0.0.1:8081 即可使用Web 思维导图功能。
## 对接自己的存储服务
应用数据默认存储在浏览器本地,浏览器本地存储容量是比较小的,所以当在思维导图中插入更多图片后很容易触发限制,所以更好的选择是对接你自己的存储服务,这通常有两种方式:
### 第一种
直接clone本仓库代码然后修改`web/src/api/index.js`内的相关方法即可实现从你的数据库里获取数据,以及存储到你的数据中。
### 第二种
很多时候,你可能想始终使用本仓库的最新代码,那么第一种方式就不太方便,因为你要手动去合并代码,所以提供了第二种方式。
具体操作步骤:
1.复制web应用打包后的资源
包括:`dist`目录和`index.html`文件。
2.修改复制后的`index.html`文件
首先在`head`标签里插入如下代码:
```js
<script>
window.takeOverApp = true
</script>
```
这行代码会提示应用不要初始化应用`即new Vue()`,而是把控制权交给你,接下来再在`body`的最后插入你自己的`js`代码,内联或则外链都可以,内联示例如下:
```js
<script>
// 你自己的请求数据的方法
const getDataFromBackend = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
// 思维导图数据
mindMapData: {
root: {
"data": {
"text": "根节点"
},
"children": []
},
theme: { "template":"avocado","config":{} },
layout: "logicalStructure",
config: {},
view: {}
},
// 页面语言支持中文zh、英文en
lang: 'zh',
// 页面部分配置
localConfig: null
})
}, 200)
})
}
// 注册全局方法
const setTakeOverAppMethods = (data) => {
window.takeOverAppMethods = {}
// 获取思维导图数据的函数
window.takeOverAppMethods.getMindMapData = () => {
return data.mindMapData
}
// 保存思维导图数据的函数
window.takeOverAppMethods.saveMindMapData = (data) => {
console.log(data)
// 该函数触发频率可能会很高,所以你应该做一下节流或防抖
}
// 获取语言的函数
window.takeOverAppMethods.getLanguage = () => {
return data.lang
}
// 保存语言的函数
window.takeOverAppMethods.saveLanguage = (lang) => {
console.log(lang)
}
// 获取本地配置的函数
window.takeOverAppMethods.getLocalConfig = () => {
return data.localConfig
}
// 保存本地配置的函数
window.takeOverAppMethods.saveLocalConfig = (config) => {
console.log(config)
}
}
window.onload = async () => {
if (!window.takeOverApp) return
// 请求数据
const data = await getDataFromBackend()
// 设置全局的方法
setTakeOverAppMethods(data)
// 思维导图实例创建完成事件
window.$bus.$on('app_inited', (mindMap) => {
console.log(mindMap)
})
// 可以通过window.$bus.$on()来监听应用的一些事件
// 实例化页面
window.initApp()
}
</script>
```
如上所示,当你设置了`window.takeOverApp = true`标志,应用不再主动进行实例化,而是会将实例化的方法暴露出来由你调用,那么你可以先从后端请求思维导图的数据,然后再注册相关的方法,应用内部会在合适的时机进行调用,从而达到回显和保存的目的。
这样做的好处是,每当本仓库代码更新了,你可以简单的复制打包后的文件到你自己的服务器,只要稍微修改一下`index.html`页面即可达到同步更新且使用自己的存储服务的目的。
## 修改静态资源路径
如果你想和上一节一样保持和本仓库代码的同步更新,但是又想修改静态资源的存放位置,比如默认的层级关系为:
```
-dist
--css
--fonts
--img
--js
-logo.ico
-index.html
```
而你想调整成这样:
```
-assets
--dist
---css
---fonts
---img
---js
-logo.ico
-index.html
```
那么你可以将`index.html`中的`window.externalPublicPath`配置由默认的`./dist/`修改为:
```js
window.externalPublicPath = './assets/dist/'
```
同时`index.html`中内联的`.ico``.js``.css`资源的路径需要你手动修改。
需要注意的是,`dist`目录内的目录层级关系最好不要调整,否则可能会出现异常。
如果你想替换其中的一些静态资源,比如你想将主题图片和结构的图片替换成你自己设计的图片,那么可以直接同名覆盖。

View File

@@ -25,7 +25,7 @@ npm link simple-mind-map
<p>如果你没有代码修改需求的话直接从本仓库复制这些文件也是可以的</p>
<p>如果你想把<code>index.html</code>也打包进<code>dist</code>目录可以修改<code>web/package.json</code>文件的<code>scripts.build</code>命令<code>vue-cli-service build &amp;&amp; node ../copy.js</code>中的<code> &amp;&amp; node ../copy.js</code>删除即可</p>
<p>如果你想修改打包输出的目录可以修改<code>web/vue.config.js</code>文件的<code>outputDir</code>配置改成你想要输出的路径即可</p>
<p>如果你想修改<code>index.html</code>文件引用静态资源的路径的话可以修改<code>web/vue.config.js</code>文件的<code>publicPath</code>配置</p>
<p>如果你想修改<code>index.html</code>文件引用静态资源的路径的话可以修改<code>web/vue.config.js</code>文件的<code>publicPath</code>配置以及<code>web/public/index.html</code>文件的<code>window.externalPublicPath</code>配置</p>
<p>另外默认使用的是<code>hash</code>路由也就是路径中会在<code>#</code>如果你想使用<code>history</code>路由可以修改<code>web/src/router.js</code>文件</p>
<pre class="hljs"><code><span class="hljs-keyword">const</span> router = <span class="hljs-keyword">new</span> VueRouter({
routes
@@ -39,7 +39,133 @@ npm link simple-mind-map
</code></pre>
<p>不过这需要后台支持因为我们的应用是个单页客户端应用如果后台没有正确的配置当用户在浏览器直接访问子路由时会返回404所以呢你要在服务端增加一个覆盖所有情况的候选资源如果<code>URL</code>匹配不到任何静态资源则应该返回同一个<code>index.html</code>页面</p>
<h2>Docker</h2>
<p>编写中</p>
<blockquote>
<p>非常感谢<a href="https://github.com/shuiche-it">水车</a>本小节由他编写对应的 Docker 包也由他维护</p>
</blockquote>
<p>直接从 Docker hup 中安装</p>
<pre class="hljs"><code>docker run -d -p 8081:8080 shuiche/mind-map:latest
</code></pre>
<p>mind-map在容器中启动了8080端口作为web服务入口通过docker运行容器时需要指定本地映射端口上面案例中我们通过本地的8081端口映射到容器端口8080</p>
<p>安装完成后通过 <code>docker ps</code> 查看容器运行状态</p>
<p>浏览器打开 127.0.0.1:8081 即可使用Web 思维导图功能</p>
<h2>对接自己的存储服务</h2>
<p>应用数据默认存储在浏览器本地浏览器本地存储容量是比较小的所以当在思维导图中插入更多图片后很容易触发限制所以更好的选择是对接你自己的存储服务这通常有两种方式</p>
<h3>第一种</h3>
<p>直接clone本仓库代码然后修改<code>web/src/api/index.js</code>内的相关方法即可实现从你的数据库里获取数据以及存储到你的数据中</p>
<h3>第二种</h3>
<p>很多时候你可能想始终使用本仓库的最新代码那么第一种方式就不太方便因为你要手动去合并代码所以提供了第二种方式</p>
<p>具体操作步骤</p>
<p>1.复制web应用打包后的资源</p>
<p>包括<code>dist</code>目录和<code>index.html</code>文件</p>
<p>2.修改复制后的<code>index.html</code>文件</p>
<p>首先在<code>head</code>标签里插入如下代码</p>
<pre class="hljs"><code>&lt;script&gt;
<span class="hljs-built_in">window</span>.takeOverApp = <span class="hljs-literal">true</span>
&lt;/script&gt;
</code></pre>
<p>这行代码会提示应用不要初始化应用<code>new Vue()</code>而是把控制权交给你接下来再在<code>body</code>的最后插入你自己的<code>js</code>代码内联或则外链都可以内联示例如下</p>
<pre class="hljs"><code>&lt;script&gt;
<span class="hljs-comment">// 你自己的请求数据的方法</span>
<span class="hljs-keyword">const</span> getDataFromBackend = <span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
resolve({
<span class="hljs-comment">// 思维导图数据</span>
<span class="hljs-attr">mindMapData</span>: {
<span class="hljs-attr">root</span>: {
<span class="hljs-string">&quot;data&quot;</span>: {
<span class="hljs-string">&quot;text&quot;</span>: <span class="hljs-string">&quot;根节点&quot;</span>
},
<span class="hljs-string">&quot;children&quot;</span>: []
},
<span class="hljs-attr">theme</span>: { <span class="hljs-string">&quot;template&quot;</span>:<span class="hljs-string">&quot;avocado&quot;</span>,<span class="hljs-string">&quot;config&quot;</span>:{} },
<span class="hljs-attr">layout</span>: <span class="hljs-string">&quot;logicalStructure&quot;</span>,
<span class="hljs-attr">config</span>: {},
<span class="hljs-attr">view</span>: {}
},
<span class="hljs-comment">// 页面语言支持中文zh、英文en</span>
<span class="hljs-attr">lang</span>: <span class="hljs-string">&#x27;zh&#x27;</span>,
<span class="hljs-comment">// 页面部分配置</span>
<span class="hljs-attr">localConfig</span>: <span class="hljs-literal">null</span>
})
}, <span class="hljs-number">200</span>)
})
}
<span class="hljs-comment">// 注册全局方法</span>
<span class="hljs-keyword">const</span> setTakeOverAppMethods = <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
<span class="hljs-built_in">window</span>.takeOverAppMethods = {}
<span class="hljs-comment">// 获取思维导图数据的函数</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.getMindMapData = <span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">return</span> data.mindMapData
}
<span class="hljs-comment">// 保存思维导图数据的函数</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.saveMindMapData = <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
<span class="hljs-built_in">console</span>.log(data)
<span class="hljs-comment">// 该函数触发频率可能会很高,所以你应该做一下节流或防抖</span>
}
<span class="hljs-comment">// 获取语言的函数</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.getLanguage = <span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">return</span> data.lang
}
<span class="hljs-comment">// 保存语言的函数</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.saveLanguage = <span class="hljs-function">(<span class="hljs-params">lang</span>) =&gt;</span> {
<span class="hljs-built_in">console</span>.log(lang)
}
<span class="hljs-comment">// 获取本地配置的函数</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.getLocalConfig = <span class="hljs-function">() =&gt;</span> {
<span class="hljs-keyword">return</span> data.localConfig
}
<span class="hljs-comment">// 保存本地配置的函数</span>
<span class="hljs-built_in">window</span>.takeOverAppMethods.saveLocalConfig = <span class="hljs-function">(<span class="hljs-params">config</span>) =&gt;</span> {
<span class="hljs-built_in">console</span>.log(config)
}
}
<span class="hljs-built_in">window</span>.onload = <span class="hljs-keyword">async</span> () =&gt; {
<span class="hljs-keyword">if</span> (!<span class="hljs-built_in">window</span>.takeOverApp) <span class="hljs-keyword">return</span>
<span class="hljs-comment">// 请求数据</span>
<span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> getDataFromBackend()
<span class="hljs-comment">// 设置全局的方法</span>
setTakeOverAppMethods(data)
<span class="hljs-comment">// 思维导图实例创建完成事件</span>
<span class="hljs-built_in">window</span>.$bus.$on(<span class="hljs-string">&#x27;app_inited&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">mindMap</span>) =&gt;</span> {
<span class="hljs-built_in">console</span>.log(mindMap)
})
<span class="hljs-comment">// 可以通过window.$bus.$on()来监听应用的一些事件</span>
<span class="hljs-comment">// 实例化页面</span>
<span class="hljs-built_in">window</span>.initApp()
}
&lt;/script&gt;
</code></pre>
<p>如上所示当你设置了<code>window.takeOverApp = true</code>标志应用不再主动进行实例化而是会将实例化的方法暴露出来由你调用那么你可以先从后端请求思维导图的数据然后再注册相关的方法应用内部会在合适的时机进行调用从而达到回显和保存的目的</p>
<p>这样做的好处是每当本仓库代码更新了你可以简单的复制打包后的文件到你自己的服务器只要稍微修改一下<code>index.html</code>页面即可达到同步更新且使用自己的存储服务的目的</p>
<h2>修改静态资源路径</h2>
<p>如果你想和上一节一样保持和本仓库代码的同步更新但是又想修改静态资源的存放位置比如默认的层级关系为</p>
<pre class="hljs"><code>-dist
--css
--fonts
--img
--js
-logo.ico
-index.html
</code></pre>
<p>而你想调整成这样</p>
<pre class="hljs"><code>-assets
--dist
---css
---fonts
---img
---js
-logo.ico
-index.html
</code></pre>
<p>那么你可以将<code>index.html</code>中的<code>window.externalPublicPath</code>配置由默认的<code>./dist/</code>修改为</p>
<pre class="hljs"><code><span class="hljs-built_in">window</span>.externalPublicPath = <span class="hljs-string">&#x27;./assets/dist/&#x27;</span>
</code></pre>
<p>同时<code>index.html</code>中内联的<code>.ico</code><code>.js</code><code>.css</code>资源的路径需要你手动修改</p>
<p>需要注意的是<code>dist</code>目录内的目录层级关系最好不要调整否则可能会出现异常</p>
<p>如果你想替换其中的一些静态资源比如你想将主题图片和结构的图片替换成你自己设计的图片那么可以直接同名覆盖</p>
</div>
</template>

View File

@@ -8,19 +8,16 @@
## 特性
- [x] 插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小整体体积
- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图六种结构
- [x] 插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小打包体积
- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴(横向、竖向)、鱼骨图结构
- [x] 内置多种主题,允许高度自定义样式,支持注册新主题
- [x] 支持快捷键
- [x] 节点内容支持图片、图标、超链接、备注、标签、概要
- [x] 支持前进后退
- [x] 支持拖动、缩放
- [x] 支持右键和Ctrl+左键两种多选方式
- [x] 支持节点自由拖拽、拖拽调整
- [x] 支持多种节点形状
- [x] 支持导出为`json``png``svg``pdf``markdown`,支持从`json``xmind``markdown`导入
- [x] 支持小地图、支持水印
- [x] 支持关联线
- [x] 节点内容支持文本(普通文本、富文本)、图片、图标、超链接、备注、标签、概要
- [x] 节点支持拖拽(拖拽移动、自由调整)、多种节点形状,支持使用 DDM 完全自定义节点内容
- [x] 支持画布拖动、缩放
- [x] 支持鼠标按键拖动选择和Ctrl+左键两种多选节点方式
- [x] 支持导出为`json``png``svg``pdf``markdown``xmind`,支持从`json``xmind``markdown`导入
- [x] 支持快捷键、前进后退、关联线、搜索替换、小地图、水印
- [x] 提供丰富的配置,满足各种场景各种使用习惯
## 仓库目录介绍

View File

@@ -8,19 +8,16 @@
</blockquote>
<h2>特性</h2>
<ul>
<li><input type="checkbox" id="checkbox0" checked="true" /><label for="checkbox0">插件化架构除核心功能外其他功能作为插件提供按需使用减小整体体积</label></li>
<li><input type="checkbox" id="checkbox1" checked="true" /><label for="checkbox1">支持逻辑结构图思维导图组织结构图目录组织图时间轴鱼骨图六种结构</label></li>
<li><input type="checkbox" id="checkbox0" checked="true" /><label for="checkbox0">插件化架构除核心功能外其他功能作为插件提供按需使用减小打包体积</label></li>
<li><input type="checkbox" id="checkbox1" checked="true" /><label for="checkbox1">支持逻辑结构图思维导图组织结构图目录组织图时间轴横向竖向鱼骨图结构</label></li>
<li><input type="checkbox" id="checkbox2" checked="true" /><label for="checkbox2">内置多种主题允许高度自定义样式支持注册新主题</label></li>
<li><input type="checkbox" id="checkbox3" checked="true" /><label for="checkbox3">支持快捷键</label></li>
<li><input type="checkbox" id="checkbox4" checked="true" /><label for="checkbox4">节点内容支持图片图标超链接备注标签概要</label></li>
<li><input type="checkbox" id="checkbox5" checked="true" /><label for="checkbox5">支持前进后退</label></li>
<li><input type="checkbox" id="checkbox6" checked="true" /><label for="checkbox6">支持拖动缩放</label></li>
<li><input type="checkbox" id="checkbox7" checked="true" /><label for="checkbox7">支持右键和Ctrl+左键两种多选方式</label></li>
<li><input type="checkbox" id="checkbox8" checked="true" /><label for="checkbox8">支持节点自由拖拽拖拽调整</label></li>
<li><input type="checkbox" id="checkbox9" checked="true" /><label for="checkbox9">支持多种节点形状</label></li>
<li><input type="checkbox" id="checkbox10" checked="true" /><label for="checkbox10">支持导出为</label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code>支持从<code>json</code><code>xmind</code><code>markdown</code>导入</li>
<li><input type="checkbox" id="checkbox11" checked="true" /><label for="checkbox11">支持小地图支持水印</label></li>
<li><input type="checkbox" id="checkbox12" checked="true" /><label for="checkbox12">支持关联线</label></li>
<li><input type="checkbox" id="checkbox3" checked="true" /><label for="checkbox3">节点内容支持文本普通文本富文本图片图标超链接备注标签概要</label></li>
<li><input type="checkbox" id="checkbox4" checked="true" /><label for="checkbox4">节点支持拖拽拖拽移动自由调整多种节点形状支持使用 DDM 完全自定义节点内容</label></li>
<li><input type="checkbox" id="checkbox5" checked="true" /><label for="checkbox5">支持画布拖动缩放</label></li>
<li><input type="checkbox" id="checkbox6" checked="true" /><label for="checkbox6">支持鼠标按键拖动选择和Ctrl+左键两种多选节点方式</label></li>
<li><input type="checkbox" id="checkbox7" checked="true" /><label for="checkbox7">支持导出为</label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code><code>xmind</code>支持从<code>json</code><code>xmind</code><code>markdown</code>导入</li>
<li><input type="checkbox" id="checkbox8" checked="true" /><label for="checkbox8">支持快捷键前进后退关联线搜索替换小地图水印</label></li>
<li><input type="checkbox" id="checkbox9" checked="true" /><label for="checkbox9">提供丰富的配置满足各种场景各种使用习惯</label></li>
</ul>
<h2>仓库目录介绍</h2>
<p>1.<code>simple-mind-map</code></p>
@@ -28,11 +25,11 @@
<p>2.<code>web</code></p>
<p>使用<code>simple-mind-map</code>基于<code>vue2.x</code><code>ElementUI</code>搭建的在线思维导图特性</p>
<ul>
<li><input type="checkbox" id="checkbox13" checked="true" /><label for="checkbox13">工具栏支持插入节点删除节点编辑节点图片图标超链接备注标签概要</label></li>
<li><input type="checkbox" id="checkbox14" checked="true" /><label for="checkbox14">侧边栏基础样式设置面板节点样式设置面板大纲面板主题选择面板结构选择面板</label></li>
<li><input type="checkbox" id="checkbox15" checked="true" /><label for="checkbox15">导入导出功能数据默认保存在浏览器本地存储也支持直接创建打开编辑电脑本地文件</label></li>
<li><input type="checkbox" id="checkbox16" checked="true" /><label for="checkbox16">右键菜单支持展开收起整理布局等操作</label></li>
<li><input type="checkbox" id="checkbox17" checked="true" /><label for="checkbox17">底部栏支持节点数量字数统计支持切换编辑和只读模式支持放大缩小支持全屏切换支持小地图</label></li>
<li><input type="checkbox" id="checkbox10" checked="true" /><label for="checkbox10">工具栏支持插入节点删除节点编辑节点图片图标超链接备注标签概要</label></li>
<li><input type="checkbox" id="checkbox11" checked="true" /><label for="checkbox11">侧边栏基础样式设置面板节点样式设置面板大纲面板主题选择面板结构选择面板</label></li>
<li><input type="checkbox" id="checkbox12" checked="true" /><label for="checkbox12">导入导出功能数据默认保存在浏览器本地存储也支持直接创建打开编辑电脑本地文件</label></li>
<li><input type="checkbox" id="checkbox13" checked="true" /><label for="checkbox13">右键菜单支持展开收起整理布局等操作</label></li>
<li><input type="checkbox" id="checkbox14" checked="true" /><label for="checkbox14">底部栏支持节点数量字数统计支持切换编辑和只读模式支持放大缩小支持全屏切换支持小地图</label></li>
</ul>
<p>提供文档页面服务</p>
<p>3.<code>dist</code></p>

View File

@@ -42,6 +42,15 @@ MindMap.usePlugin(MiniMap)
1.准备一个容器元素`container`,定位不为`static`
如果使用的是富文本编辑模式,那么最好给`container`内部的元素去除一下默认样式,否则可能会出现节点内文本偏移的问题:
```css
.container * {
margin: 0;
padding: 0;
}
```
2.在`container`内创建一个小地图容器元素`miniMapContainer`,绝对定位
3.在`container`内创建一个视口框元素`viewBoxContainer`,绝对定位,设置边框样式,过渡属性(可选)

View File

@@ -29,6 +29,12 @@ MindMap.usePlugin(MiniMap)
</code></pre>
<p>小地图思路</p>
<p>1.准备一个容器元素<code>container</code>定位不为<code>static</code></p>
<p>如果使用的是富文本编辑模式那么最好给<code>container</code>内部的元素去除一下默认样式否则可能会出现节点内文本偏移的问题</p>
<pre class="hljs"><code><span class="hljs-selector-class">.container</span> * {
<span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
<span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
}
</code></pre>
<p>2.<code>container</code>内创建一个小地图容器元素<code>miniMapContainer</code>绝对定位</p>
<p>3.<code>container</code>内创建一个视口框元素<code>viewBoxContainer</code>绝对定位设置边框样式过渡属性可选</p>
<p>4.监听<code>data_change</code><code>view_data_change</code>事件在该事件内调用<code>calculationMiniMap</code>方法获取计算数据然后将<code>svgHTML</code>渲染到<code>miniMapContainer</code>元素内并且设置<code>miniMapContainer</code>元素的样式</p>

View File

@@ -215,6 +215,18 @@ copyNodeTree({}, node)
检查一个字符串是否是富文本字符。
#### isWhite(color)
> v0.6.11+
判断一个颜色是否是白色。
#### isTransparent(color)
判断一个颜色是否是透明。
> v0.6.11+
## 在canvas中模拟css的背景属性
引入:

View File

@@ -149,6 +149,16 @@
<p>v0.6.10+</p>
</blockquote>
<p>检查一个字符串是否是富文本字符</p>
<h4>isWhite(color)</h4>
<blockquote>
<p>v0.6.11+</p>
</blockquote>
<p>判断一个颜色是否是白色</p>
<h4>isTransparent(color)</h4>
<p>判断一个颜色是否是透明</p>
<blockquote>
<p>v0.6.11+</p>
</blockquote>
<h2>在canvas中模拟css的背景属性</h2>
<p>引入</p>
<pre class="hljs"><code><span class="hljs-keyword">import</span> drawBackgroundImageToCanvas <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map/src/utils/simulateCSSBackgroundInCanvas&#x27;</span>

View File

@@ -83,9 +83,9 @@ MindMap
.usePlugin(SearchPlugin)
// 注册自定义主题
// customThemeList.forEach((item) => {
// MindMap.defineTheme(item.value, item.theme)
// })
customThemeList.forEach((item) => {
MindMap.defineTheme(item.value, item.theme)
})
/**
* @Author: 王林
@@ -384,6 +384,10 @@ export default {
// 动态删除指定节点
// this.mindMap.execCommand('REMOVE_NODE', this.mindMap.renderer.root.children[0])
// }, 5000);
// 如果应用被接管,那么抛出事件传递思维导图实例
if (window.takeOverApp) {
this.$bus.$emit('app_inited', this.mindMap)
}
},
/**

View File

@@ -108,7 +108,7 @@ export default {
data() {
return {
langList,
lang: getLang(),
lang: '',
isReadonly: false,
openMiniMap: false
}
@@ -116,6 +116,9 @@ export default {
computed: {
...mapState(['isDark'])
},
created () {
this.lang = getLang()
},
methods: {
...mapMutations(['setIsDark']),

View File

@@ -5,9 +5,16 @@
:visible.sync="dialogVisible"
width="500"
>
<ImgUpload ref="ImgUpload" v-model="img"></ImgUpload>
<div class="imgTitleBox">
<span class="title">{{ $t('nodeImage.imgTitle') }}</span>
<div class="title">方式一</div>
<ImgUpload ref="ImgUpload" v-model="img" style="margin-bottom: 12px;"></ImgUpload>
<div class="title">方式二</div>
<div class="inputBox">
<span class="label">请输入图片地址</span>
<el-input v-model="imgUrl" size="mini" placeholder="http://xxx.com/xx.jpg"></el-input>
</div>
<div class="title">可选</div>
<div class="inputBox">
<span class="label">{{ $t('nodeImage.imgTitle') }}</span>
<el-input v-model="imgTitle" size="mini"></el-input>
</div>
<span slot="footer" class="dialog-footer">
@@ -21,6 +28,7 @@
<script>
import ImgUpload from '@/components/ImgUpload'
import { getImageSize } from 'simple-mind-map/src/utils/index'
/**
* @Author: 王林
@@ -36,6 +44,7 @@ export default {
return {
dialogVisible: false,
img: '',
imgUrl: '',
imgTitle: '',
activeNodes: null
}
@@ -43,43 +52,54 @@ export default {
created() {
this.$bus.$on('node_active', (...args) => {
this.activeNodes = args[1]
if (this.activeNodes.length > 0) {
let firstNode = this.activeNodes[0]
this.img = firstNode.getData('image')
this.imgTitle = firstNode.getData('imageTitle')
} else {
this.img = ''
this.imgTitle = ''
}
})
this.$bus.$on('showNodeImage', () => {
this.reset()
if (this.activeNodes.length > 0) {
let firstNode = this.activeNodes[0]
let img = firstNode.getData('image')
if (img) {
if (/^https?:\/\//.test(img)) {
this.imgUrl = img
} else {
this.img = img
}
}
this.imgTitle = firstNode.getData('imageTitle')
}
this.dialogVisible = true
})
},
methods: {
/**
* @Author: 王林
* @Date: 2021-06-22 22:08:11
* @Desc: 取消
*/
cancel() {
this.dialogVisible = false
this.reset()
},
reset() {
this.img = ''
this.imgTitle = ''
this.imgUrl = ''
},
/**
* @Author: 王林
* @Date: 2021-06-06 22:28:20
* @Desc: 确定
*/
async confirm() {
try {
let { width, height } = await this.$refs.ImgUpload.getSize()
if (!this.img && !this.imgUrl) return
let res = null
let img = ''
if (this.img) {
img = this.img
res = await this.$refs.ImgUpload.getSize()
} else if (this.imgUrl) {
img = this.imgUrl
res = await getImageSize(img)
}
this.activeNodes.forEach(node => {
node.setImage({
url: this.img || 'none',
url: img || 'none',
title: this.imgTitle,
width,
height
width: res.width,
height: res.height
})
})
this.cancel()
@@ -93,13 +113,18 @@ export default {
<style lang="less" scoped>
.nodeDialog {
.imgTitleBox {
.title {
font-size: 18px;
margin-bottom: 12px;
}
.inputBox {
display: flex;
align-items: center;
margin-top: 10px;
margin-bottom: 10px;
.title {
width: 100px;
.label {
width: 150px;
}
}
}

View File

@@ -1,9 +1,12 @@
<template>
<Sidebar ref="sidebar" :title="$t('theme.title')">
<div class="themeList" :class="{ isDark: isDark }">
<el-tabs v-model="activeName">
<el-tab-pane v-for="group in groupList" :key="group.name" :label="group.name" :name="group.name"></el-tab-pane>
</el-tabs>
<div
class="themeItem"
v-for="item in themeList"
v-for="item in currentList"
:key="item.value"
@click="useTheme(item)"
:class="{ active: item.value === theme }"
@@ -42,13 +45,21 @@ export default {
},
data() {
return {
themeList: [...themeList].reverse(), // ...customThemeList
themeList: [...themeList, ...customThemeList].reverse(),
themeMap,
theme: ''
theme: '',
activeName: '',
groupList: []
}
},
computed: {
...mapState(['activeSidebar', 'isDark'])
...mapState(['activeSidebar', 'isDark']),
currentList() {
return this.groupList.find((item) => {
return item.name === this.activeName
}).list
}
},
watch: {
activeSidebar(val) {
@@ -62,12 +73,43 @@ export default {
}
},
created() {
this.initGroup()
this.theme = this.mindMap.getTheme()
this.handleDark()
},
methods: {
...mapMutations(['setIsDark']),
initGroup() {
let baiduThemes = ['default', 'skyGreen', 'classic2', 'classic3', 'classicGreen', 'classicBlue', 'blueSky', 'brainImpairedPink', 'earthYellow', 'freshGreen', 'freshRed', 'romanticPurple', 'pinkGrape', 'mint']
let baiduList = []
let classicsList = []
this.themeList.forEach((item) => {
if (baiduThemes.includes(item.value)) {
baiduList.push(item)
} else if (!item.dark) {
classicsList.push(item)
}
})
this.groupList = [
{
name: '经典',
list: classicsList
},
{
name: '深色',
list: this.themeList.filter((item) => {
return item.dark
})
},
{
name: '朴素',
list: baiduList
}
]
this.activeName = this.groupList[0].name
},
useTheme(theme) {
this.theme = theme.value
this.handleDark()
@@ -102,7 +144,7 @@ export default {
},
handleDark() {
let target = themeList.find(item => {
let target = this.themeList.find(item => {
return item.value === this.theme
})
this.setIsDark(target.dark)
@@ -114,6 +156,7 @@ export default {
<style lang="less" scoped>
.themeList {
padding: 20px;
padding-top: 0;
&.isDark {
.name {

View File

@@ -3,7 +3,6 @@ import VueRouter from 'vue-router'
import EditPage from '@/pages/Edit/Index'
import DocPage from '@/pages/Doc/Index'
import routerList from '@/pages/Doc/routerList'
import IndexPage from '@/pages/Index/Index'
// 处理没有翻译的章节路由
const handleRouterList = () => {
@@ -54,7 +53,7 @@ const routes = [
{
path: '/index',
name: 'Index',
component: IndexPage
component: () => import(`./pages/Index/Index.vue`)
},
{
path: '/',

View File

@@ -1,16 +1,35 @@
const path = require('path');
const path = require('path')
const isDev = process.env.NODE_ENV === 'development'
const WebpackDynamicPublicPathPlugin = require('webpack-dynamic-public-path')
module.exports = {
publicPath: isDev ? '' : './dist',
outputDir: '../dist',
lintOnSave: false,
productionSourceMap: false,
configureWebpack: {
resolve: {
alias: {
'@': path.resolve(__dirname, './src/')
}
}
publicPath: isDev ? '' : './dist',
outputDir: '../dist',
lintOnSave: false,
productionSourceMap: false,
filenameHashing: false,
chainWebpack: config => {
// 移除 preload 插件
config.plugins.delete('preload')
// 移除 prefetch 插件
config.plugins.delete('prefetch')
// 支持运行时设置public path
config
.plugin('dynamicPublicPathPlugin')
.use(WebpackDynamicPublicPathPlugin, [
{ externalPublicPath: 'window.externalPublicPath' }
])
// 给插入html页面内的js和css添加hash参数
config.plugin('html').tap(args => {
args[0].hash = true
return args
})
},
configureWebpack: {
resolve: {
alias: {
'@': path.resolve(__dirname, './src/')
}
}
}
}
}