add vc-tree demo
parent
25631cf541
commit
41a1f85dd5
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import Tabs from '../vc-tabs/src/Tabs'
|
import Tabs from '../vc-tabs/src/Tabs'
|
||||||
import isFlexSupported from '../_util/isFlexSupported'
|
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'
|
import warning from '../_util/warning'
|
||||||
export default {
|
export default {
|
||||||
name: 'ATabs',
|
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 PropTypes from '../../_util/vue-types'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import warning from 'warning'
|
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 { cloneElement } from '../../_util/vnode'
|
||||||
import BaseMixin from '../../_util/BaseMixin'
|
import BaseMixin from '../../_util/BaseMixin'
|
||||||
import {
|
import {
|
||||||
|
@ -162,9 +162,10 @@ const Tree = {
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
...(this.getSyncProps(props) || {}),
|
...this.getSyncProps(props),
|
||||||
dragOverNodeKey: '',
|
dragOverNodeKey: '',
|
||||||
dropPosition: null,
|
dropPosition: null,
|
||||||
|
dragNodesKeys: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
provide () {
|
provide () {
|
||||||
|
@ -203,8 +204,8 @@ const Tree = {
|
||||||
methods: {
|
methods: {
|
||||||
onNodeDragStart (event, node) {
|
onNodeDragStart (event, node) {
|
||||||
const { sExpandedKeys } = this
|
const { sExpandedKeys } = this
|
||||||
const { eventKey, children } = node.props
|
const { eventKey } = node
|
||||||
|
const children = getSlots(node).default
|
||||||
this.dragNode = node
|
this.dragNode = node
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -223,13 +224,13 @@ const Tree = {
|
||||||
*/
|
*/
|
||||||
onNodeDragEnter (event, node) {
|
onNodeDragEnter (event, node) {
|
||||||
const { sExpandedKeys } = this
|
const { sExpandedKeys } = this
|
||||||
const { pos, eventKey } = node.props
|
const { pos, eventKey } = node
|
||||||
|
|
||||||
const dropPosition = calcDropPosition(event, node)
|
const dropPosition = calcDropPosition(event, node)
|
||||||
|
|
||||||
// Skip if drag node is self
|
// Skip if drag node is self
|
||||||
if (
|
if (
|
||||||
this.dragNode.props.eventKey === eventKey &&
|
this.dragNode.eventKey === eventKey &&
|
||||||
dropPosition === 0
|
dropPosition === 0
|
||||||
) {
|
) {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -268,7 +269,7 @@ const Tree = {
|
||||||
}, 0)
|
}, 0)
|
||||||
},
|
},
|
||||||
onNodeDragOver (event, node) {
|
onNodeDragOver (event, node) {
|
||||||
const { eventKey } = node.props
|
const { eventKey } = node
|
||||||
|
|
||||||
// Update drag position
|
// Update drag position
|
||||||
if (this.dragNode && eventKey === this.dragOverNodeKey) {
|
if (this.dragNode && eventKey === this.dragOverNodeKey) {
|
||||||
|
@ -297,7 +298,7 @@ const Tree = {
|
||||||
onNodeDrop (event, node) {
|
onNodeDrop (event, node) {
|
||||||
const { dragNodesKeys, dropPosition } = this
|
const { dragNodesKeys, dropPosition } = this
|
||||||
|
|
||||||
const { eventKey, pos } = node.props
|
const { eventKey, pos } = node
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
dragOverNodeKey: '',
|
dragOverNodeKey: '',
|
||||||
|
@ -509,46 +510,21 @@ const Tree = {
|
||||||
/**
|
/**
|
||||||
* Sync state with props if needed
|
* Sync state with props if needed
|
||||||
*/
|
*/
|
||||||
getSyncProps (props = {}, prevProps) {
|
getSyncProps (props = {}) {
|
||||||
let needSync = false
|
|
||||||
const newState = {}
|
const newState = {}
|
||||||
const myPrevProps = prevProps || {}
|
|
||||||
const children = this.$slots.default
|
const children = this.$slots.default
|
||||||
function checkSync (name) {
|
if (props.selectedKeys !== undefined) {
|
||||||
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')) {
|
|
||||||
newState.sSelectedKeys = calcSelectedKeys(props.selectedKeys, props, children)
|
newState.sSelectedKeys = calcSelectedKeys(props.selectedKeys, props, children)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkSync('checkedKeys')) {
|
if (props.checkedKeys !== undefined) {
|
||||||
const { checkedKeys = [], halfCheckedKeys = [] } =
|
const { checkedKeys = [], halfCheckedKeys = [] } =
|
||||||
calcCheckedKeys(props.checkedKeys, props, children) || {}
|
calcCheckedKeys(props.checkedKeys, props, children) || {}
|
||||||
newState.sCheckedKeys = checkedKeys
|
newState.sCheckedKeys = checkedKeys
|
||||||
newState.sHalfCheckedKeys = halfCheckedKeys
|
newState.sHalfCheckedKeys = halfCheckedKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
return needSync ? newState : null
|
return newState
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -291,11 +291,6 @@ const TreeNode = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Drag usage
|
|
||||||
setSelectHandle (node) {
|
|
||||||
this.selectHandle = node
|
|
||||||
},
|
|
||||||
|
|
||||||
getNodeChildren () {
|
getNodeChildren () {
|
||||||
const { $slots: { default: children }} = this
|
const { $slots: { default: children }} = this
|
||||||
const originList = filterEmpty(children)
|
const originList = filterEmpty(children)
|
||||||
|
@ -497,10 +492,9 @@ const TreeNode = {
|
||||||
)}
|
)}
|
||||||
draggable={(!disabled && draggable) || undefined}
|
draggable={(!disabled && draggable) || undefined}
|
||||||
aria-grabbed={(!disabled && draggable) || undefined}
|
aria-grabbed={(!disabled && draggable) || undefined}
|
||||||
|
|
||||||
onMouseenter={this.onMouseEnter}
|
onMouseenter={this.onMouseEnter}
|
||||||
onMouseleave={this.onMouseLeave}
|
onMouseleave={this.onMouseLeave}
|
||||||
onContexmenu={this.onContextMenu}
|
onContextmenu={this.onContextMenu}
|
||||||
onClick={this.onSelectorClick}
|
onClick={this.onSelectorClick}
|
||||||
onDragstart={this.onDragStart}
|
onDragstart={this.onDragStart}
|
||||||
>
|
>
|
||||||
|
|
|
@ -176,7 +176,7 @@ export function getDragNodesKeys (treeNodes, node) {
|
||||||
|
|
||||||
export function calcDropPosition (event, treeNode) {
|
export function calcDropPosition (event, treeNode) {
|
||||||
const { clientY } = event
|
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)
|
const des = Math.max(height * DRAG_SIDE_RANGE, DRAG_MIN_GAP)
|
||||||
|
|
||||||
if (clientY <= top + des) {
|
if (clientY <= top + des) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Layout from './components/layout.vue'
|
||||||
const AsyncTestComp = () => {
|
const AsyncTestComp = () => {
|
||||||
const d = window.location.hash.replace('#', '')
|
const d = window.location.hash.replace('#', '')
|
||||||
return {
|
return {
|
||||||
component: import(`../components/vc-upload/demo/${d}`),
|
component: import(`../components/vc-tree/demo/${d}`),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue