Demo:大纲不再使用节点默认样式
This commit is contained in:
parent
e345037f9b
commit
27885aabe7
@ -539,4 +539,59 @@ export const getVisibleColorFromTheme = (themeConfig) => {
|
|||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将<p><span></span><p>形式的节点富文本内容转换成<br>换行的文本
|
||||||
|
let nodeRichTextToTextWithWrapEl = null
|
||||||
|
export const nodeRichTextToTextWithWrap = (html) => {
|
||||||
|
if (!nodeRichTextToTextWithWrapEl) {
|
||||||
|
nodeRichTextToTextWithWrapEl = document.createElement('div')
|
||||||
|
}
|
||||||
|
nodeRichTextToTextWithWrapEl.innerHTML = html
|
||||||
|
const childNodes = nodeRichTextToTextWithWrapEl.childNodes
|
||||||
|
let res = ''
|
||||||
|
for(let i = 0; i < childNodes.length; i++) {
|
||||||
|
const node = childNodes[i]
|
||||||
|
if (node.nodeType === 1) {// 元素节点
|
||||||
|
if (node.tagName.toLowerCase() === 'p') {
|
||||||
|
res += node.textContent + '\n'
|
||||||
|
} else {
|
||||||
|
res += node.textContent
|
||||||
|
}
|
||||||
|
} else if (node.nodeType === 3) {// 文本节点
|
||||||
|
res += node.nodeValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.replace(/\n$/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将<br>换行的文本转换成<p><span></span><p>形式的节点富文本内容
|
||||||
|
let textToNodeRichTextWithWrapEl = null
|
||||||
|
export const textToNodeRichTextWithWrap = (html) => {
|
||||||
|
if (!textToNodeRichTextWithWrapEl) {
|
||||||
|
textToNodeRichTextWithWrapEl = document.createElement('div')
|
||||||
|
}
|
||||||
|
textToNodeRichTextWithWrapEl.innerHTML = html
|
||||||
|
const childNodes = textToNodeRichTextWithWrapEl.childNodes
|
||||||
|
let list = []
|
||||||
|
let str = ''
|
||||||
|
for(let i = 0; i < childNodes.length; i++) {
|
||||||
|
const node = childNodes[i]
|
||||||
|
if (node.nodeType === 1) {// 元素节点
|
||||||
|
if (node.tagName.toLowerCase() === 'br') {
|
||||||
|
list.push(str)
|
||||||
|
str = ''
|
||||||
|
} else {
|
||||||
|
str += node.textContent
|
||||||
|
}
|
||||||
|
} else if (node.nodeType === 3) {// 文本节点
|
||||||
|
str += node.nodeValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (str) {
|
||||||
|
list.push(str)
|
||||||
|
}
|
||||||
|
return list.map((item) => {
|
||||||
|
return `<p><span>${item}</span></p>`
|
||||||
|
}).join('')
|
||||||
}
|
}
|
||||||
@ -8,7 +8,11 @@
|
|||||||
:expand-on-click-node="false"
|
:expand-on-click-node="false"
|
||||||
default-expand-all
|
default-expand-all
|
||||||
>
|
>
|
||||||
<span class="customNode" slot-scope="{ node, data }" @click="onClick($event, node)">
|
<span
|
||||||
|
class="customNode"
|
||||||
|
slot-scope="{ node, data }"
|
||||||
|
@click="onClick($event, node)"
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
class="nodeEdit"
|
class="nodeEdit"
|
||||||
:key="getKey()"
|
:key="getKey()"
|
||||||
@ -16,6 +20,7 @@
|
|||||||
@keydown.stop="onKeydown($event, node)"
|
@keydown.stop="onKeydown($event, node)"
|
||||||
@keyup.stop
|
@keyup.stop
|
||||||
@blur="onBlur($event, node)"
|
@blur="onBlur($event, node)"
|
||||||
|
@paste="onPaste($event, node)"
|
||||||
v-html="node.label"
|
v-html="node.label"
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
@ -26,6 +31,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import Sidebar from './Sidebar'
|
import Sidebar from './Sidebar'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
import {
|
||||||
|
nodeRichTextToTextWithWrap,
|
||||||
|
textToNodeRichTextWithWrap,
|
||||||
|
getTextFromHtml
|
||||||
|
} from 'simple-mind-map/src/utils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
@ -47,7 +57,12 @@ export default {
|
|||||||
data: [],
|
data: [],
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
label(data) {
|
label(data) {
|
||||||
return data.data.richText ? data.data.text : data.data.text.replaceAll(/\n/g, '</br>')
|
const text = (data.data.richText
|
||||||
|
? nodeRichTextToTextWithWrap(data.data.text)
|
||||||
|
: data.data.text
|
||||||
|
).replaceAll(/\n/g, '<br>')
|
||||||
|
data.data.textCache = text
|
||||||
|
return text
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
notHandleDataChange: false
|
notHandleDataChange: false
|
||||||
@ -77,12 +92,33 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onBlur(e, node) {
|
onBlur(e, node) {
|
||||||
const richText = node.data.data.richText
|
if (node.data.data.textCache === e.target.innerHTML) {
|
||||||
if (richText) {
|
return
|
||||||
node.data._node.setText(e.target.innerHTML, true)
|
|
||||||
} else {
|
|
||||||
node.data._node.setText(e.target.innerText)
|
|
||||||
}
|
}
|
||||||
|
delete node.data.data.textCache
|
||||||
|
const richText = node.data.data.richText
|
||||||
|
const text = richText ? e.target.innerHTML : e.target.innerText
|
||||||
|
if (richText) {
|
||||||
|
node.data._node.setText(textToNodeRichTextWithWrap(text), true, true)
|
||||||
|
} else {
|
||||||
|
node.data._node.setText(text)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 拦截粘贴事件
|
||||||
|
onPaste(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
const selection = window.getSelection()
|
||||||
|
if (!selection.rangeCount) return
|
||||||
|
selection.deleteFromDocument()
|
||||||
|
let text = (e.clipboardData || window.clipboardData).getData('text')
|
||||||
|
// 去除格式
|
||||||
|
text = getTextFromHtml(text)
|
||||||
|
// 去除换行
|
||||||
|
text = text.replaceAll(/\n/g, '')
|
||||||
|
const node = document.createTextNode(text)
|
||||||
|
selection.getRangeAt(0).insertNode(node)
|
||||||
|
selection.collapseToEnd()
|
||||||
},
|
},
|
||||||
|
|
||||||
getKey() {
|
getKey() {
|
||||||
@ -121,7 +157,7 @@ export default {
|
|||||||
this.mindMap.execCommand('GO_TARGET_NODE', node.data.data.uid, () => {
|
this.mindMap.execCommand('GO_TARGET_NODE', node.data.data.uid, () => {
|
||||||
this.mindMap.renderer.textEdit.openFocusOnNodeActive()
|
this.mindMap.renderer.textEdit.openFocusOnNodeActive()
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -129,7 +165,8 @@ export default {
|
|||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.customNode {
|
.customNode {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-x: auto;
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
width: 7px;
|
width: 7px;
|
||||||
@ -154,27 +191,36 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.outlineTree {
|
.outlineTree {
|
||||||
|
|
||||||
&.isDark {
|
&.isDark {
|
||||||
background-color: #262a2e;
|
background-color: #262a2e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/deep/ .el-tree-node > .el-tree-node__children {
|
||||||
|
overflow: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
/deep/ .el-tree-node__content {
|
/deep/ .el-tree-node__content {
|
||||||
height: auto;
|
height: auto;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
|
|
||||||
.el-tree-node__expand-icon.is-leaf {
|
.el-tree-node__expand-icon {
|
||||||
position: relative;
|
color: #262a2e;
|
||||||
|
|
||||||
&::after {
|
&.is-leaf {
|
||||||
position: absolute;
|
color: transparent;
|
||||||
content: '';
|
position: relative;
|
||||||
width: 5px;
|
|
||||||
height: 5px;
|
&::after {
|
||||||
border-radius: 50%;
|
background-color: #262a2e;
|
||||||
background-color: #c0c4cc;
|
position: absolute;
|
||||||
left: 10px;
|
content: '';
|
||||||
top: 50%;
|
width: 5px;
|
||||||
transform: translateY(-50%);
|
height: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
left: 10px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user