add vc-tree demo
parent
25631cf541
commit
41a1f85dd5
|
@ -1,7 +1,7 @@
|
|||
|
||||
import Tabs from '../vc-tabs/src/Tabs'
|
||||
import isFlexSupported from '../_util/isFlexSupported'
|
||||
import { hasProp, getComponentFromProp, getComponentName, isEmptyElement, getSlotOptions } from '../_util/props-util'
|
||||
import { hasProp, getComponentFromProp, isEmptyElement, getSlotOptions } from '../_util/props-util'
|
||||
import warning from '../_util/warning'
|
||||
export default {
|
||||
name: 'ATabs',
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
@contextmenuPrefixCls: rc-tree-contextmenu;
|
||||
.@{contextmenuPrefixCls} {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
top: -9999px;
|
||||
z-index: 1070;
|
||||
display: block;
|
||||
background-color: #fff;
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-inner {
|
||||
border: 1px solid #ddd;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
<script>
|
||||
/* eslint no-console:0 */
|
||||
import Tree, { TreeNode } from '../index'
|
||||
import '../assets/index.less'
|
||||
import './contextmenu.less'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
selectedKeys: ['0-1', '0-1-1'],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSelect (selectedKeys) {
|
||||
this.selectedKeys = selectedKeys
|
||||
},
|
||||
onRightClick (info) {
|
||||
console.log('right click', info)
|
||||
this.selectedKeys = [info.node.eventKey]
|
||||
},
|
||||
onMouseEnter (info) {
|
||||
console.log('enter', info)
|
||||
},
|
||||
onMouseLeave (info) {
|
||||
console.log('leave', info)
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<h2>right click contextmenu</h2>
|
||||
<Tree
|
||||
onRightClick={this.onRightClick}
|
||||
onSelect={this.onSelect}
|
||||
selectedKeys={this.selectedKeys}
|
||||
multiple
|
||||
defaultExpandAll
|
||||
showLine
|
||||
showIcon={false}
|
||||
>
|
||||
<TreeNode title='parent 1' key='0-1'>
|
||||
<TreeNode title='parent 1-0' key='0-1-1'>
|
||||
<TreeNode title='leaf0' isLeaf />
|
||||
<TreeNode title='leaf1' isLeaf />
|
||||
<TreeNode title='leaf2' isLeaf />
|
||||
</TreeNode>
|
||||
<TreeNode title='parent 1-1'>
|
||||
<TreeNode title='leaf' isLeaf />
|
||||
</TreeNode>
|
||||
</TreeNode>
|
||||
</Tree>
|
||||
<h2>hover popup contextmenu</h2>
|
||||
<Tree
|
||||
onMouseenter={this.onMouseEnter} onMouseleave={this.onMouseLeave}
|
||||
onSelect={this.onSelect}
|
||||
multiple defaultExpandAll showLine
|
||||
>
|
||||
<TreeNode title='parent 1' key='0-1'>
|
||||
<TreeNode title='parent 1-0' key='0-1-1'>
|
||||
<TreeNode title='leaf' isLeaf />
|
||||
<TreeNode title='leaf' />
|
||||
</TreeNode>
|
||||
<TreeNode title='parent 1-1'>
|
||||
<TreeNode title='leaf' />
|
||||
</TreeNode>
|
||||
</TreeNode>
|
||||
</Tree>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
.draggable-demo{
|
||||
padding: 0 20px;
|
||||
.draggable-container {
|
||||
margin: 10px 30px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<script>
|
||||
/* eslint no-console:0 */
|
||||
import './draggable.less'
|
||||
import Tree, { TreeNode } from '../index'
|
||||
import '../assets/index.less'
|
||||
import { gData } from './util'
|
||||
import BaseMixin from '../../_util/BaseMixin'
|
||||
|
||||
export default {
|
||||
mixins: [BaseMixin],
|
||||
data () {
|
||||
return {
|
||||
gData,
|
||||
autoExpandParent: true,
|
||||
expandedKeys: ['0-0-key', '0-0-0-key', '0-0-0-0-key'],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onDragStart (info) {
|
||||
console.log('start', info)
|
||||
},
|
||||
onDragEnter (info) {
|
||||
console.log('enter', info)
|
||||
this.setState({
|
||||
expandedKeys: info.expandedKeys,
|
||||
})
|
||||
},
|
||||
onDrop (info) {
|
||||
console.log('drop', info)
|
||||
const dropKey = info.node.eventKey
|
||||
const dragKey = info.dragNode.eventKey
|
||||
const dropPos = info.node.pos.split('-')
|
||||
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
|
||||
// const dragNodesKeys = info.dragNodesKeys;
|
||||
const loop = (data, key, callback) => {
|
||||
data.forEach((item, index, arr) => {
|
||||
if (item.key === key) {
|
||||
return callback(item, index, arr)
|
||||
}
|
||||
if (item.children) {
|
||||
return loop(item.children, key, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
const data = [...this.gData]
|
||||
let dragObj
|
||||
loop(data, dragKey, (item, index, arr) => {
|
||||
arr.splice(index, 1)
|
||||
dragObj = item
|
||||
})
|
||||
if (info.dropToGap) {
|
||||
let ar
|
||||
let i
|
||||
loop(data, dropKey, (item, index, arr) => {
|
||||
ar = arr
|
||||
i = index
|
||||
})
|
||||
if (dropPosition === -1) {
|
||||
ar.splice(i, 0, dragObj)
|
||||
} else {
|
||||
ar.splice(i + 1, 0, dragObj)
|
||||
}
|
||||
} else {
|
||||
loop(data, dropKey, (item) => {
|
||||
item.children = item.children || []
|
||||
// where to insert 示例添加到尾部,可以是随意位置
|
||||
item.children.push(dragObj)
|
||||
})
|
||||
}
|
||||
this.setState({
|
||||
gData: data,
|
||||
})
|
||||
},
|
||||
onExpand (expandedKeys) {
|
||||
console.log('onExpand', arguments)
|
||||
this.setState({
|
||||
expandedKeys,
|
||||
autoExpandParent: false,
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const loop = data => {
|
||||
return data.map((item) => {
|
||||
if (item.children && item.children.length) {
|
||||
return <TreeNode key={item.key} title={item.title}>{loop(item.children)}</TreeNode>
|
||||
}
|
||||
return <TreeNode key={item.key} title={item.title} />
|
||||
})
|
||||
}
|
||||
return (<div class='draggable-demo'>
|
||||
<h2>draggable</h2>
|
||||
<p>drag a node into another node</p>
|
||||
<div class='draggable-container'>
|
||||
<Tree
|
||||
expandedKeys={this.expandedKeys}
|
||||
onExpand={this.onExpand} autoExpandParent={this.autoExpandParent}
|
||||
draggable
|
||||
onDragstart={this.onDragStart}
|
||||
onDragenter={this.onDragEnter}
|
||||
onDrop={this.onDrop}
|
||||
>
|
||||
{loop(this.gData)}
|
||||
</Tree>
|
||||
</div>
|
||||
</div>)
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
|
@ -1,7 +1,7 @@
|
|||
import PropTypes from '../../_util/vue-types'
|
||||
import classNames from 'classnames'
|
||||
import warning from 'warning'
|
||||
import { initDefaultProps, getOptionProps } from '../../_util/props-util'
|
||||
import { initDefaultProps, getOptionProps, getSlots } from '../../_util/props-util'
|
||||
import { cloneElement } from '../../_util/vnode'
|
||||
import BaseMixin from '../../_util/BaseMixin'
|
||||
import {
|
||||
|
@ -162,9 +162,10 @@ const Tree = {
|
|||
}
|
||||
return {
|
||||
...state,
|
||||
...(this.getSyncProps(props) || {}),
|
||||
...this.getSyncProps(props),
|
||||
dragOverNodeKey: '',
|
||||
dropPosition: null,
|
||||
dragNodesKeys: [],
|
||||
}
|
||||
},
|
||||
provide () {
|
||||
|
@ -203,8 +204,8 @@ const Tree = {
|
|||
methods: {
|
||||
onNodeDragStart (event, node) {
|
||||
const { sExpandedKeys } = this
|
||||
const { eventKey, children } = node.props
|
||||
|
||||
const { eventKey } = node
|
||||
const children = getSlots(node).default
|
||||
this.dragNode = node
|
||||
|
||||
this.setState({
|
||||
|
@ -223,13 +224,13 @@ const Tree = {
|
|||
*/
|
||||
onNodeDragEnter (event, node) {
|
||||
const { sExpandedKeys } = this
|
||||
const { pos, eventKey } = node.props
|
||||
const { pos, eventKey } = node
|
||||
|
||||
const dropPosition = calcDropPosition(event, node)
|
||||
|
||||
// Skip if drag node is self
|
||||
if (
|
||||
this.dragNode.props.eventKey === eventKey &&
|
||||
this.dragNode.eventKey === eventKey &&
|
||||
dropPosition === 0
|
||||
) {
|
||||
this.setState({
|
||||
|
@ -268,7 +269,7 @@ const Tree = {
|
|||
}, 0)
|
||||
},
|
||||
onNodeDragOver (event, node) {
|
||||
const { eventKey } = node.props
|
||||
const { eventKey } = node
|
||||
|
||||
// Update drag position
|
||||
if (this.dragNode && eventKey === this.dragOverNodeKey) {
|
||||
|
@ -297,7 +298,7 @@ const Tree = {
|
|||
onNodeDrop (event, node) {
|
||||
const { dragNodesKeys, dropPosition } = this
|
||||
|
||||
const { eventKey, pos } = node.props
|
||||
const { eventKey, pos } = node
|
||||
|
||||
this.setState({
|
||||
dragOverNodeKey: '',
|
||||
|
@ -509,46 +510,21 @@ const Tree = {
|
|||
/**
|
||||
* Sync state with props if needed
|
||||
*/
|
||||
getSyncProps (props = {}, prevProps) {
|
||||
let needSync = false
|
||||
getSyncProps (props = {}) {
|
||||
const newState = {}
|
||||
const myPrevProps = prevProps || {}
|
||||
const children = this.$slots.default
|
||||
function checkSync (name) {
|
||||
if (props[name] !== myPrevProps[name]) {
|
||||
needSync = true
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Children change will affect check box status.
|
||||
// And no need to check when prev props not provided
|
||||
if (prevProps && checkSync('children')) {
|
||||
const { checkedKeys = [], halfCheckedKeys = [] } =
|
||||
calcCheckedKeys(props.checkedKeys || this.sCheckedKeys, props, children) || {}
|
||||
newState.sCheckedKeys = checkedKeys
|
||||
newState.sHalfCheckedKeys = halfCheckedKeys
|
||||
}
|
||||
|
||||
// Re-calculate when autoExpandParent or expandedKeys changed
|
||||
if (prevProps && (checkSync('autoExpandParent') || checkSync('expandedKeys'))) {
|
||||
newState.sExpandedKeys = props.autoExpandParent
|
||||
? calcExpandedKeys(props.expandedKeys, props, children) : props.expandedKeys
|
||||
}
|
||||
|
||||
if (checkSync('selectedKeys')) {
|
||||
if (props.selectedKeys !== undefined) {
|
||||
newState.sSelectedKeys = calcSelectedKeys(props.selectedKeys, props, children)
|
||||
}
|
||||
|
||||
if (checkSync('checkedKeys')) {
|
||||
if (props.checkedKeys !== undefined) {
|
||||
const { checkedKeys = [], halfCheckedKeys = [] } =
|
||||
calcCheckedKeys(props.checkedKeys, props, children) || {}
|
||||
newState.sCheckedKeys = checkedKeys
|
||||
newState.sHalfCheckedKeys = halfCheckedKeys
|
||||
}
|
||||
|
||||
return needSync ? newState : null
|
||||
return newState
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -291,11 +291,6 @@ const TreeNode = {
|
|||
}
|
||||
},
|
||||
|
||||
// Drag usage
|
||||
setSelectHandle (node) {
|
||||
this.selectHandle = node
|
||||
},
|
||||
|
||||
getNodeChildren () {
|
||||
const { $slots: { default: children }} = this
|
||||
const originList = filterEmpty(children)
|
||||
|
@ -497,10 +492,9 @@ const TreeNode = {
|
|||
)}
|
||||
draggable={(!disabled && draggable) || undefined}
|
||||
aria-grabbed={(!disabled && draggable) || undefined}
|
||||
|
||||
onMouseenter={this.onMouseEnter}
|
||||
onMouseleave={this.onMouseLeave}
|
||||
onContexmenu={this.onContextMenu}
|
||||
onContextmenu={this.onContextMenu}
|
||||
onClick={this.onSelectorClick}
|
||||
onDragstart={this.onDragStart}
|
||||
>
|
||||
|
|
|
@ -176,7 +176,7 @@ export function getDragNodesKeys (treeNodes, node) {
|
|||
|
||||
export function calcDropPosition (event, treeNode) {
|
||||
const { clientY } = event
|
||||
const { top, bottom, height } = treeNode.selectHandle.getBoundingClientRect()
|
||||
const { top, bottom, height } = treeNode.$refs.selectHandle.getBoundingClientRect()
|
||||
const des = Math.max(height * DRAG_SIDE_RANGE, DRAG_MIN_GAP)
|
||||
|
||||
if (clientY <= top + des) {
|
||||
|
|
|
@ -3,7 +3,7 @@ import Layout from './components/layout.vue'
|
|||
const AsyncTestComp = () => {
|
||||
const d = window.location.hash.replace('#', '')
|
||||
return {
|
||||
component: import(`../components/vc-upload/demo/${d}`),
|
||||
component: import(`../components/vc-tree/demo/${d}`),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue