feat: tree-select add tag-render

refactor-cascader
tangjinzhou 2022-01-16 11:13:39 +08:00
parent 646fad2eda
commit d46762c1d6
9 changed files with 212 additions and 101 deletions

View File

@ -27,9 +27,9 @@ Multiple and checkable.
/>
</template>
<script lang="ts">
import { TreeSelect } from 'ant-design-vue';
import type { TreeSelectProps } from 'ant-design-vue';
import { defineComponent, ref, watch } from 'vue';
import { TreeSelect } from 'ant-design-vue';
const SHOW_PARENT = TreeSelect.SHOW_PARENT;
const treeData: TreeSelectProps['treeData'] = [

View File

@ -0,0 +1,93 @@
<docs>
---
order: 24
title:
zh-CN: 自定义选择标签
en-US: Custom Tag Render
---
## zh-CN
允许自定义选择标签的样式仅支持多选模式单选可直接使用 `title` 插槽
## en-US
Allows for custom rendering of tags.
</docs>
<template>
<a-tree-select
v-model:value="value"
show-search
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="Please select"
allow-clear
multiple
:show-checked-strategy="SHOW_ALL"
tree-default-expand-all
:tree-data="treeData"
>
<template #tagRender="{ label, closable, onClose, option }">
<a-tag :closable="closable" :color="option.color" style="margin-right: 3px" @close="onClose">
{{ label }}&nbsp;&nbsp;
</a-tag>
</template>
<template #title="{ value: val, title }">
<b v-if="val === 'parent 1-1'" style="color: #08c">{{ val }}</b>
<template v-else>{{ title }}</template>
</template>
</a-tree-select>
</template>
<script lang="ts">
import type { TreeSelectProps } from 'ant-design-vue';
import { defineComponent, ref, watch } from 'vue';
import { TreeSelect } from 'ant-design-vue';
const SHOW_ALL = TreeSelect.SHOW_ALL;
export default defineComponent({
setup() {
const value = ref<string[]>(['parent 1', 'parent 1-0', 'leaf1']);
const treeData = ref<TreeSelectProps['treeData']>([
{
title: 'parent 1',
value: 'parent 1',
color: 'pink',
children: [
{
title: 'parent 1-0',
value: 'parent 1-0',
color: 'orange',
children: [
{
title: 'my leaf',
value: 'leaf1',
color: 'green',
},
{
title: 'your leaf',
value: 'leaf2',
color: 'cyan',
},
],
},
{
title: 'parent 1-1',
value: 'parent 1-1',
color: 'blue',
},
],
},
]);
watch(value, () => {
console.log('select', value.value);
});
return {
value,
treeData,
SHOW_ALL,
};
},
});
</script>

View File

@ -7,6 +7,9 @@
<suffix />
<async />
<Highlight />
<treeLineVue />
<virtualScrollVue />
<customTagRenderVue />
</demo-sort>
</template>
<script lang="ts">
@ -17,6 +20,9 @@ import Checkable from './checkable.vue';
import Suffix from './suffix.vue';
import Async from './async.vue';
import Highlight from './highlight.vue';
import treeLineVue from './tree-line.vue';
import virtualScrollVue from './virtual-scroll.vue';
import customTagRenderVue from './custom-tag-render.vue';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
import { defineComponent } from 'vue';
@ -32,6 +38,9 @@ export default defineComponent({
Suffix,
Async,
Highlight,
treeLineVue,
virtualScrollVue,
customTagRenderVue,
},
setup() {
return {};

View File

@ -17,6 +17,7 @@ Use `treeLine` to show the line style.
</docs>
<template>
<a-space direction="vertical">
<a-switch
v-model:checked="treeLine"
checked-children="treeLine"
@ -40,6 +41,7 @@ Use `treeLine` to show the line style.
<template v-else>{{ title }}</template>
</template>
</a-tree-select>
</a-space>
</template>
<script lang="ts">
import type { TreeSelectProps } from 'ant-design-vue';

View File

@ -1,74 +0,0 @@
<docs>
---
order: 2
title:
zh-CN: 从数据直接生成
en-US: Generate form tree data
---
## zh-CN
使用 `treeData` JSON 数据直接生成树结构
## en-US
The tree structure can be populated using `treeData` property. This is a quick and easy way to provide the tree content.
</docs>
<template>
<a-tree-select
v-model:value="value"
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
:tree-data="treeData"
placeholder="Please select"
tree-default-expand-all
>
<template #title="{ key, value: val, title }">
<span v-if="key === '0-0-1'" style="color: #08c">Child Node1 {{ val }}</span>
<template v-else>{{ title }}</template>
</template>
</a-tree-select>
</template>
<script lang="ts">
import type { TreeSelectProps } from 'ant-design-vue';
import { defineComponent, ref, watch } from 'vue';
const treeData: TreeSelectProps['treeData'] = [
{
title: 'Node1',
value: '0-0',
key: '0-0',
children: [
{
value: '0-0-1',
key: '0-0-1',
},
{
title: 'Child Node2',
value: '0-0-2',
key: '0-0-2',
},
],
},
{
title: 'Node2',
value: '0-1',
key: '0-1',
},
];
export default defineComponent({
setup() {
const value = ref<string>();
watch(value, () => {
console.log(value.value);
});
return {
value,
treeData,
};
},
});
</script>

View File

@ -0,0 +1,73 @@
<docs>
---
order: 9
title:
zh-CN: 虚拟滚动
en-US: Virtual scroll
---
## zh-CN
使用 `height` 属性则切换为虚拟滚动
## en-US
Use virtual list through `height` prop.
</docs>
<template>
<a-tree-select
v-model:value="checkedKeys"
style="width: 100%"
tree-checkable
tree-default-expand-all
:show-checked-strategy="SHOW_PARENT"
:height="233"
:tree-data="treeData"
:max-tag-count="10"
>
<template #title="{ title, value }">
<span v-if="value === '0-0-1-0'" style="color: #1890ff">{{ title }}</span>
<template v-else>{{ title }}</template>
</template>
</a-tree-select>
</template>
<script lang="ts">
import type { TreeSelectProps } from 'ant-design-vue';
import { TreeSelect } from 'ant-design-vue';
import { defineComponent, ref, watch } from 'vue';
const SHOW_PARENT = TreeSelect.SHOW_PARENT;
function dig(path = '0', level = 3) {
const list: TreeSelectProps['treeData'] = [];
for (let i = 0; i < 10; i += 1) {
const value = `${path}-${i}`;
const treeNode: TreeSelectProps['treeData'][number] = {
title: value,
value,
};
if (level > 0) {
treeNode.children = dig(value, level - 1);
}
list.push(treeNode);
}
return list;
}
export default defineComponent({
setup() {
const checkedKeys = ref<string[]>(['0-0-0', '0-0-1']);
watch(checkedKeys, () => {
console.log('checkedKeys', checkedKeys);
});
return {
treeData: dig(),
checkedKeys,
SHOW_PARENT,
};
},
});
</script>

View File

@ -10,6 +10,7 @@ import type { VueNode } from '../../_util/type';
import Overflow from '../../vc-overflow';
import type { DisplayValueType, RenderNode, CustomTagProps, RawValueType } from '../BaseSelect';
import type { BaseOptionType } from '../Select';
import useInjectLegacySelectContext from '../../vc-tree-select/LegacyContext';
type SelectorProps = InnerSelectorProps & {
// Icon
@ -79,7 +80,7 @@ const SelectSelector = defineComponent<SelectorProps>({
const measureRef = ref();
const inputWidth = ref(0);
const focused = ref(false);
const legacyTreeSelectContext = useInjectLegacySelectContext();
const selectionPrefixCls = computed(() => `${props.prefixCls}-selection`);
// ===================== Search ======================
@ -147,15 +148,20 @@ const SelectSelector = defineComponent<SelectorProps>({
onPreventMouseDown(e);
props.onToggleOpen(!open);
};
let originData = option;
// For TreeSelect
if (legacyTreeSelectContext.keyEntities) {
originData = legacyTreeSelectContext.keyEntities[value]?.node || {};
}
return (
<span onMousedown={onMouseDown}>
<span key={value} onMousedown={onMouseDown}>
{props.tagRender({
label: content,
value,
disabled: itemDisabled,
closable,
onClose,
option,
option: originData,
})}
</span>
);

View File

@ -109,6 +109,7 @@ const SingleSelector = defineComponent<SelectorProps>({
let titleNode = null;
// custom tree-select title by slot
// For TreeSelect
if (item && legacyTreeSelectContext.customSlots) {
const key = item.key ?? item.value;
const originData = legacyTreeSelectContext.keyEntities[key]?.node || {};

View File

@ -727,6 +727,7 @@ export default defineComponent({
OptionList={OptionList}
emptyOptions={!mergedTreeData.value.length}
onDropdownVisibleChange={onInternalDropdownVisibleChange}
tagRender={props.tagRender || slots.tagRender}
/>
);
};