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.
ant-design-vue/components/transfer/demo/tree-transfer.vue

129 lines
2.9 KiB

<docs>
---
order: 7
title:
zh-CN: 树穿梭框
en-US: Tree Transfer
---
## zh-CN
使用 Tree 组件作为自定义渲染列表
## en-US
Customize render list with Tree component.
</docs>
<template>
<div>
<a-transfer
v-model:target-keys="targetKeys"
class="tree-transfer"
:data-source="dataSource"
:render="item => item.title"
:show-select-all="false"
>
<template #children="{ direction, selectedKeys, onItemSelect }">
<a-tree
v-if="direction === 'left'"
block-node
checkable
check-strictly
default-expand-all
:checked-keys="[...selectedKeys, ...targetKeys]"
:tree-data="treeData"
@check="
(_, props) => {
onChecked(_, props, [...selectedKeys, ...targetKeys], onItemSelect);
}
"
@select="
(_, props) => {
onChecked(_, props, [...selectedKeys, ...targetKeys], onItemSelect);
}
"
/>
</template>
</a-transfer>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
import type { TreeProps } from 'ant-design-vue';
import type { AntTreeNodeCheckedEvent } from 'ant-design-vue/es/tree';
const tData: TreeProps['treeData'] = [
{ key: '0-0', title: '0-0' },
{
key: '0-1',
title: '0-1',
children: [
{ key: '0-1-0', title: '0-1-0' },
{ key: '0-1-1', title: '0-1-1' },
],
},
{ key: '0-2', title: '0-3' },
];
const transferDataSource: TreeProps['treeData'] = [];
function flatten(list: TreeProps['treeData'] = []) {
list.forEach(item => {
transferDataSource.push(item);
flatten(item.children);
});
}
flatten(JSON.parse(JSON.stringify(tData)));
function isChecked(selectedKeys: (string | number)[], eventKey: string | number) {
return selectedKeys.indexOf(eventKey) !== -1;
}
function handleTreeData(
data: TreeProps['treeData'],
targetKeys: string[] = [],
): TreeProps['treeData'] {
data.forEach(item => {
item['disabled'] = targetKeys.includes(item.key as any);
if (item.children) {
handleTreeData(item.children, targetKeys);
}
});
return data;
}
export default defineComponent({
setup() {
const targetKeys = ref<string[]>([]);
const dataSource = ref<TreeProps['treeData']>(transferDataSource);
const treeData = computed<TreeProps['treeData']>(() => {
return handleTreeData(tData, targetKeys.value);
});
const onChecked = (
_: Record<string, string[]>,
e: AntTreeNodeCheckedEvent,
checkedKeys: string[],
onItemSelect: (n: any, c: boolean) => void,
) => {
const { eventKey } = e.node;
onItemSelect(eventKey, !isChecked(checkedKeys, eventKey));
};
return {
targetKeys,
dataSource,
treeData,
onChecked,
};
},
});
</script>
<style scoped>
.tree-transfer .ant-transfer-list:first-child {
width: 50%;
flex: none;
}
</style>