|
@ -1,8 +1,10 @@ |
|
|
<template> |
|
|
<template> |
|
|
<div class="ps-tree component"> |
|
|
<div class="ps-tree component" draggable="true" :class="{ aaa: isDrag }" @dragover.prevent="onDragover2" |
|
|
|
|
|
@dragleave.stop="onDragleave2" @drop.stop="onDrop2"> |
|
|
<template v-for="(item, index) in sortedList" :key="item.key"> |
|
|
<template v-for="(item, index) in sortedList" :key="item.key"> |
|
|
<node @onDragstart="onDragstart" @expand="onExpand" @onDragEnd="onDragEnd" @onDrop="onDrop" :data-source-key="dataSourceKey" |
|
|
<node @onDragstart="onDragstart" @expand="onExpand" @onDragEnd="onDragEnd" @onDrop="onDrop" |
|
|
:data="item" :list="sortedList" :level="level" @click="(item) => clickNode(item)"> |
|
|
:data-source-key="dataSourceKey" :data="item" :list="sortedList" :level="level" |
|
|
|
|
|
@click="(item) => clickNode(item)"> |
|
|
<template |
|
|
<template |
|
|
#default="{ data, deep, dataSourceKey, status }: { data: INiuTreeData, deep: number, dataSourceKey: INiuTreeKey, status: ENiuTreeStatus }"> |
|
|
#default="{ data, deep, dataSourceKey, status }: { data: INiuTreeData, deep: number, dataSourceKey: INiuTreeKey, status: ENiuTreeStatus }"> |
|
|
<slot :data="data" :deep="deep" :dataSourceKey="dataSourceKey" :status="status"></slot> |
|
|
<slot :data="data" :deep="deep" :dataSourceKey="dataSourceKey" :status="status"></slot> |
|
@ -18,18 +20,20 @@ import type { INiuTreeData, INiuTreeKey } from './type' |
|
|
import { ENiuTreeStatus } from './type' |
|
|
import { ENiuTreeStatus } from './type' |
|
|
import { |
|
|
import { |
|
|
findByKey, |
|
|
findByKey, |
|
|
|
|
|
findByKeyParent, |
|
|
forEachTree, |
|
|
forEachTree, |
|
|
insertAfterByKey, |
|
|
insertAfterByKey, |
|
|
insertBeforeByKey, |
|
|
insertBeforeByKey, |
|
|
|
|
|
isChild, |
|
|
isChildOf, |
|
|
isChildOf, |
|
|
removeByKey, |
|
|
removeByKey, |
|
|
} from './util' |
|
|
} from './util' |
|
|
|
|
|
|
|
|
import {betterDirectorySort} from "./better-directory-sort" |
|
|
import { betterDirectorySort } from "./better-directory-sort" |
|
|
import { computed } from "@vue/reactivity" |
|
|
import { computed } from "@vue/reactivity" |
|
|
|
|
|
|
|
|
const sortedList = computed(()=>{ |
|
|
const sortedList = computed(() => { |
|
|
if(props.sort){ |
|
|
if (props.sort) { |
|
|
return props.list.sort((a, b) => { |
|
|
return props.list.sort((a, b) => { |
|
|
return betterDirectorySort( |
|
|
return betterDirectorySort( |
|
|
{ name: a.title, isDirectory: a.isFolder }, |
|
|
{ name: a.title, isDirectory: a.isFolder }, |
|
@ -40,6 +44,39 @@ const sortedList = computed(()=>{ |
|
|
return props.list |
|
|
return props.list |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const isDrag = ref(false) |
|
|
|
|
|
function onDragover2() { |
|
|
|
|
|
if (!props.sort) return |
|
|
|
|
|
if (!dataSourceKey.value) return |
|
|
|
|
|
if (!isChild(dataSourceKey.value, props.list)) { |
|
|
|
|
|
isDrag.value = true |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
function onDragleave2() { |
|
|
|
|
|
if (!props.sort) return |
|
|
|
|
|
isDrag.value = false |
|
|
|
|
|
} |
|
|
|
|
|
async function onDrop2(ev) { |
|
|
|
|
|
if (!props.sort) return |
|
|
|
|
|
if (!dataSourceKey.value) return |
|
|
|
|
|
if (!isDrag.value) return |
|
|
|
|
|
isDrag.value = false |
|
|
|
|
|
let data = findByKey(dataSourceKey.value, props.list) |
|
|
|
|
|
const sourceKey = dataSourceKey.value; |
|
|
|
|
|
dataSourceKey.value = undefined |
|
|
|
|
|
if ( |
|
|
|
|
|
data |
|
|
|
|
|
) { |
|
|
|
|
|
const isSuccess = (await props.dropFn?.(ENiuTreeStatus.DragIn, data, props.list)) |
|
|
|
|
|
if (isSuccess == undefined || isSuccess) { |
|
|
|
|
|
removeByKey(sourceKey, props.list) |
|
|
|
|
|
props.list.push(data) |
|
|
|
|
|
emit("change") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const props = withDefaults( |
|
|
const props = withDefaults( |
|
|
defineProps<{ |
|
|
defineProps<{ |
|
|
list: INiuTreeData[] |
|
|
list: INiuTreeData[] |
|
@ -48,7 +85,7 @@ const props = withDefaults( |
|
|
justOpenOne?: boolean |
|
|
justOpenOne?: boolean |
|
|
sort?: boolean |
|
|
sort?: boolean |
|
|
level?: number |
|
|
level?: number |
|
|
dropFn?(status: ENiuTreeStatus, data: INiuTreeData, targetData: INiuTreeData): boolean | Promise<boolean> |
|
|
dropFn?(status: ENiuTreeStatus, data: INiuTreeData, targetDataList: INiuTreeData[]): boolean | Promise<boolean> |
|
|
}>(), |
|
|
}>(), |
|
|
{ |
|
|
{ |
|
|
justOpenOne: false, |
|
|
justOpenOne: false, |
|
@ -101,6 +138,29 @@ async function onDrop(key: INiuTreeKey, status?: ENiuTreeStatus) { |
|
|
const sourceKey = dataSourceKey.value; |
|
|
const sourceKey = dataSourceKey.value; |
|
|
dataSourceKey.value = undefined |
|
|
dataSourceKey.value = undefined |
|
|
switch (status) { |
|
|
switch (status) { |
|
|
|
|
|
case ENiuTreeStatus.DragInner: |
|
|
|
|
|
const parentData = findByKeyParent(key, props.list) |
|
|
|
|
|
if ( |
|
|
|
|
|
data && |
|
|
|
|
|
targetData && |
|
|
|
|
|
sourceKey != key && |
|
|
|
|
|
!isChildOf(key, sourceKey, props.list) |
|
|
|
|
|
) { |
|
|
|
|
|
const isSuccess = (await props.dropFn?.(status, data, parentData?.children ?? props.list)) |
|
|
|
|
|
if (isSuccess == undefined || isSuccess) { |
|
|
|
|
|
removeByKey(sourceKey, props.list) |
|
|
|
|
|
if(parentData){ |
|
|
|
|
|
parentData.children.push(data) |
|
|
|
|
|
if (props.autoExpand) { |
|
|
|
|
|
parentData.isExpand = true |
|
|
|
|
|
} |
|
|
|
|
|
}else{ |
|
|
|
|
|
props.list.push(data) |
|
|
|
|
|
} |
|
|
|
|
|
emit("change") |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
break |
|
|
case ENiuTreeStatus.DragIn: |
|
|
case ENiuTreeStatus.DragIn: |
|
|
if ( |
|
|
if ( |
|
|
data && |
|
|
data && |
|
@ -109,7 +169,7 @@ async function onDrop(key: INiuTreeKey, status?: ENiuTreeStatus) { |
|
|
!isChildOf(key, sourceKey, props.list) && |
|
|
!isChildOf(key, sourceKey, props.list) && |
|
|
targetData.children |
|
|
targetData.children |
|
|
) { |
|
|
) { |
|
|
const isSuccess = (await props.dropFn?.(status, data, targetData)) |
|
|
const isSuccess = (await props.dropFn?.(status, data, targetData.children)) |
|
|
if (isSuccess == undefined || isSuccess) { |
|
|
if (isSuccess == undefined || isSuccess) { |
|
|
removeByKey(sourceKey, props.list) |
|
|
removeByKey(sourceKey, props.list) |
|
|
targetData.children.push(data) |
|
|
targetData.children.push(data) |
|
@ -128,7 +188,7 @@ async function onDrop(key: INiuTreeKey, status?: ENiuTreeStatus) { |
|
|
sourceKey != key && |
|
|
sourceKey != key && |
|
|
!isChildOf(key, sourceKey, props.list) |
|
|
!isChildOf(key, sourceKey, props.list) |
|
|
) { |
|
|
) { |
|
|
const isSuccess = (await props.dropFn?.(status, data, targetData)) |
|
|
const isSuccess = (await props.dropFn?.(status, data, targetData.children)) |
|
|
if (isSuccess == undefined || isSuccess) { |
|
|
if (isSuccess == undefined || isSuccess) { |
|
|
removeByKey(sourceKey, props.list) |
|
|
removeByKey(sourceKey, props.list) |
|
|
insertAfterByKey(key, data, props.list) |
|
|
insertAfterByKey(key, data, props.list) |
|
@ -144,7 +204,7 @@ async function onDrop(key: INiuTreeKey, status?: ENiuTreeStatus) { |
|
|
sourceKey != key && |
|
|
sourceKey != key && |
|
|
!isChildOf(key, sourceKey, props.list) |
|
|
!isChildOf(key, sourceKey, props.list) |
|
|
) { |
|
|
) { |
|
|
const isSuccess = (await props.dropFn?.(status, data, targetData)) |
|
|
const isSuccess = (await props.dropFn?.(status, data, targetData.children)) |
|
|
if (isSuccess == undefined || isSuccess) { |
|
|
if (isSuccess == undefined || isSuccess) { |
|
|
removeByKey(sourceKey, props.list) |
|
|
removeByKey(sourceKey, props.list) |
|
|
insertBeforeByKey(key, data, props.list) |
|
|
insertBeforeByKey(key, data, props.list) |
|
|