You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
3.7 KiB
126 lines
3.7 KiB
|
6 years ago
|
<script type="text/jsx">
|
||
|
6 years ago
|
// 判断是否叶子节点
|
||
|
|
const isLeaf = (data, prop) => {
|
||
|
6 years ago
|
return !Array.isArray(data[prop]) || data[prop].length === 0
|
||
|
6 years ago
|
}
|
||
|
|
|
||
|
|
// 创建 node 节点
|
||
|
6 years ago
|
const renderNode = (h, data, context) => {
|
||
|
6 years ago
|
const {props} = context
|
||
|
|
const cls = ['org-tree-node']
|
||
|
|
const childNodes = []
|
||
|
|
const children = data[props.props.children]
|
||
|
|
|
||
|
|
if (isLeaf(data, props.props.children)) {
|
||
|
|
cls.push('is-leaf')
|
||
|
|
}
|
||
|
|
else if (props.collapsable && !data[props.props.expand]) {
|
||
|
|
cls.push('collapsed')
|
||
|
|
}
|
||
|
|
|
||
|
|
childNodes.push(renderLabel(h, data, context))
|
||
|
|
|
||
|
|
if (!props.collapsable || data[props.props.expand]) {
|
||
|
|
childNodes.push(renderChildren(h, children, context))
|
||
|
|
}
|
||
|
|
|
||
|
6 years ago
|
return <div class={cls.join(' ')}>{childNodes}</div>
|
||
|
6 years ago
|
}
|
||
|
|
|
||
|
|
// 创建 label 节点
|
||
|
6 years ago
|
const renderLabel = (h, data, context) => {
|
||
|
6 years ago
|
const {props} = context
|
||
|
|
const label = data[props.props.label]
|
||
|
|
const nodeRender = props.nodeRender
|
||
|
|
const clickHandler = context.listeners['on-node-click']
|
||
|
|
const mousedownHandler = e => {
|
||
|
|
e.stopPropagation()
|
||
|
|
if (context.listeners['on-node-mousedown']) {
|
||
|
|
context.listeners['on-node-mousedown'](e, data)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const mouseupHandler = context.listeners['on-node-mouseup']
|
||
|
|
const touchstartHandler = context.listeners['on-node-touchstart']
|
||
|
|
const touchleaveHandler = context.listeners['on-node-touchleave']
|
||
|
|
|
||
|
|
const childNodes = []
|
||
|
|
if (typeof nodeRender === 'function') {
|
||
|
6 years ago
|
childNodes.push(nodeRender(h, data))
|
||
|
6 years ago
|
}
|
||
|
|
else if (context.parent.$scopedSlots.default) {
|
||
|
|
childNodes.push(context.parent.$scopedSlots.default(data))
|
||
|
|
}
|
||
|
|
else childNodes.push(label)
|
||
|
|
|
||
|
|
if (props.collapsable && !isLeaf(data, props.props.children)) {
|
||
|
|
childNodes.push(renderBtn(h, data, context))
|
||
|
|
}
|
||
|
|
|
||
|
|
const cls = ['org-tree-node-label-inner']
|
||
|
|
let {labelWidth, labelClassName} = props
|
||
|
|
if (typeof labelWidth === 'number') {
|
||
|
|
labelWidth += 'px'
|
||
|
|
}
|
||
|
|
if (typeof labelClassName === 'function') {
|
||
|
|
labelClassName = labelClassName(data)
|
||
|
|
}
|
||
|
|
labelClassName && cls.push(labelClassName)
|
||
|
|
|
||
|
6 years ago
|
return (
|
||
|
|
<div
|
||
|
|
class="org-tree-node-label"
|
||
|
|
on-click={e => clickHandler && clickHandler(e, data)}
|
||
|
|
on-mousedown={mousedownHandler}
|
||
|
|
on-mouseup={e => mouseupHandler && mouseupHandler(e, data)}
|
||
|
|
on-touchstart={e => touchstartHandler && touchstartHandler(e, data)}
|
||
|
|
on-touchleave={e => touchleaveHandler && touchleaveHandler(e, data)}
|
||
|
|
>
|
||
|
|
<div class={cls.join(' ')} style={{width: labelWidth}}>
|
||
|
|
{childNodes}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 创建展开折叠按钮
|
||
|
|
const renderBtn = (h, data, context) => {
|
||
|
|
const {props} = context
|
||
|
|
const expandHandler = context.listeners['on-expand']
|
||
|
|
const onClock = e => {
|
||
|
|
e.stopPropagation()
|
||
|
|
expandHandler && expandHandler(data)
|
||
|
|
}
|
||
|
|
const onMousedown = e => e.stopPropagation()
|
||
|
|
const cls = ['org-tree-node-btn']
|
||
|
|
|
||
|
|
data[props.props.expand] && cls.push('expanded')
|
||
|
|
|
||
|
|
return (
|
||
|
|
<span class="org-tree-button-wrapper" on-click={onClock} on-mousedown={onMousedown}>
|
||
|
|
{props.buttonRender ? props.buttonRender(h, data) : <span class={cls.join(' ')}/>}
|
||
|
|
</span>
|
||
|
|
)
|
||
|
6 years ago
|
}
|
||
|
|
|
||
|
|
// 创建 node 子节点
|
||
|
6 years ago
|
const renderChildren = (h, list, context) => {
|
||
|
6 years ago
|
if (Array.isArray(list) && list.length) {
|
||
|
6 years ago
|
return (
|
||
|
|
<div class="org-tree-node-children">
|
||
|
|
{list.map(item => renderNode(h, item, context))}
|
||
|
|
</div>
|
||
|
|
)
|
||
|
6 years ago
|
}
|
||
|
|
}
|
||
|
|
|
||
|
6 years ago
|
export default {
|
||
|
|
name: "OrgTreeNode",
|
||
|
6 years ago
|
|
||
|
6 years ago
|
functional: true,
|
||
|
|
|
||
|
|
render(h, context) {
|
||
|
|
return renderNode(h, context.props.data, context)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|