Skip to content

Commit

Permalink
feat: select提供选项定制和回显内容定制 (#69)
Browse files Browse the repository at this point in the history
* feat: select提供选项定制和回显内容定制

* fix: 修复bug

* doc: 更新文档

* fix: 降低点速速
  • Loading branch information
wanchun committed Mar 14, 2022
1 parent 941ce15 commit cbc9c45
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 40 deletions.
22 changes: 16 additions & 6 deletions components/select-tree/selectTree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,22 @@ export default defineComponent({
};
const selectedOptions = computed(() =>
Object.values(nodeList.value).filter((option) => {
if (props.multiple) {
return currentValue.value.includes(option.value);
}
return [currentValue.value].includes(option.value);
}),
Object.values(nodeList.value)
.filter((option) => {
if (props.multiple) {
return currentValue.value.includes(option.value);
}
return [currentValue.value].includes(option.value);
})
.map((option) => {
if (props.optionLabelField) {
return {
...option,
label: option[props.optionLabelField],
};
}
return option;
}),
);
const focus = (e: Event) => {
Expand Down
4 changes: 4 additions & 0 deletions components/select/optionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const optionListProps = {
type: Boolean,
},
emptyText: String,
renderOption: Function
} as const;

export default defineComponent({
Expand All @@ -46,6 +47,9 @@ export default defineComponent({
if ((option as any).slots?.default) {
return (option as any).slots.default({ isSelected });
}
if (props.renderOption) {
return props.renderOption({...option, isSelected});
}
if (option.label) {
return (
<>
Expand Down
1 change: 1 addition & 0 deletions components/select/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const selectProps = {
type: String,
default: 'label',
},
optionLabelField: String,
} as const;

export const selectPropsDefaultValue = extractPropsDefaultValue(selectProps);
Expand Down
22 changes: 18 additions & 4 deletions components/select/select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
:onSelect="onSelect"
:isLimit="isLimitRef"
:emptyText="listEmptyText"
:renderOption="$slots.option"
@scroll="onScroll"
@mousedown.prevent
/>
Expand All @@ -62,6 +63,7 @@ import {
onMounted,
CSSProperties,
defineComponent,
nextTick,
} from 'vue';
import getPrefixCls from '../_util/getPrefixCls';
import { useTheme } from '../_theme/useTheme';
Expand Down Expand Up @@ -197,14 +199,18 @@ export default defineComponent({
const onSelect = (value: SelectValue) => {
if (props.disabled) return;
filterText.value = '';
if (props.multiple) {
filterText.value = '';
if (isSelect(value)) {
emit('removeTag', value);
} else {
if (isLimitRef.value) return;
}
} else {
// 体验更好
setTimeout(() => {
filterText.value = '';
}, 400);
isOpenedRef.value = false;
}
updateCurrentValue(unref(value));
Expand All @@ -219,9 +225,17 @@ export default defineComponent({
const getOption = (val: SelectValue) => {
let cacheOption;
if (newOptions && newOptions.length) {
cacheOption = newOptions.find(
(option) => option.value === val,
);
cacheOption = newOptions
.map((option) => {
if (props.optionLabelField) {
return {
...option,
label: option[props.optionLabelField],
};
}
return option;
})
.find((option) => option.value === val);
if (cacheOption) {
return cacheOption;
}
Expand Down
1 change: 1 addition & 0 deletions components/tree/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface TreeOption {
isLeaf?: boolean;
prefix?: string | (() => VNodeChild);
suffix?: string | (() => VNodeChild);
[key: string]: any;
}

export interface InnerTreeOption extends TreeOption {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
<template>
<FSelect>
<FOption
v-for="(item, index) in optionList"
:key="index"
:value="item.value"
:label="item.label"
>
<FEllipsis>{{ item.label }}</FEllipsis>
<span>{{ item.value }}</span>
</FOption>
</FSelect>
<FSpace>
<FSelect>
<FOption
v-for="(item, index) in optionList"
:key="index"
:value="item.value"
:label="item.label"
>
<FEllipsis>{{ item.label }}</FEllipsis>
<span>{{ item.value }}</span>
</FOption>
</FSelect>

<FSelect :options="optionList">
<template #option="{ label, value }">
{{ value }} - {{ label.slice(0, 2) }}
</template>
</FSelect>
</FSpace>
</template>
<script>
import { reactive } from 'vue';
Expand Down
45 changes: 26 additions & 19 deletions docs/.vitepress/components/select/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ app.use(FSelect);

--COMMON

### 配置方式

通过配置`options`直接生成选项,当数据量大于 `50` 时使用 `VirtualList`组件实现虚拟列表,性能更优。

--OPTIONS

### 自定义模板

可以自定义备选项模板,`FOption`子组件是针对每一项单独配置,而 `slots.option` 插槽则是通用配置。

--CUSTOMOPTION

### 可清空

包含清空按钮,可将选择器清空为初始状态

--CLEARABLE

### 禁用选项

禁止选择某一项
Expand All @@ -36,12 +54,6 @@ app.use(FSelect);

--LIMIT

### 自定义模板

可以自定义备选项模板

--LABEL

### 可过滤

可以利用搜索功能快速查找选项
Expand All @@ -52,31 +64,25 @@ app.use(FSelect);

--REMOTE

### 可清空

包含清空按钮,可将选择器清空为初始状态

--CLEARABLE

### 禁用状态

选择器不可用状态

--DISABLED

### 无数据

### 配置方式

通过配置`options`直接生成选项,当数据量大于 `50` 时使用 `VirtualList`组件实现虚拟列表,性能更优。
--NODATA

--OPTIONS

### 无数据
### 控制回填内容

--NODATA
--LABELFIELD

--CODE



## Select Props

| 属性 | 说明 | 类型 | 默认值 |
Expand All @@ -97,7 +103,7 @@ app.use(FSelect);
| options | 选项配置 | array\<Option\> | `[]` |
| valueField | 替代 `Option` 中的 `value` 字段名 | string | `value` |
| labelField | 替代 `Option` 中的 `label` 字段名 | string | `label` |

| optionLabelField | 配置选中选项显示的字段名,不传时跟`labelField`一致 | string | - |

## Select Events

Expand All @@ -118,6 +124,7 @@ app.use(FSelect);
| ------- | --------------- |
| default | option 组件列表 |
| empty | 无选项的内容 |
| option | 自定义 `Option` 内容 |

## Select Methods

Expand Down
47 changes: 47 additions & 0 deletions docs/.vitepress/components/select/labelField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<FSelect :options="optionList" optionLabelField="x"></FSelect>
</template>
<script>
import { reactive } from 'vue';
export default {
setup() {
const optionList = reactive([
{
value: 'HuNan',
label: '湖南',
x: 'HuNan-湖南',
},
{
value: 'HuBei',
label: '湖北',
disabled: true,
x: 'HuBei-湖北',
},
{
value: 'ZheJiang',
label: '浙江',
x: 'ZheJiang-浙江',
},
{
value: 'GuangDong',
label: '广东',
x: 'GuangDong-广东',
},
{
value: 'JiangSu',
label: '江苏',
x: 'JiangSu-江苏',
},
]);
return {
optionList,
};
},
};
</script>
<style scoped>
.fes-select {
width: 200px;
}
</style>
4 changes: 4 additions & 0 deletions docs/.vitepress/components/selectTree/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ app.use(FSelectTree);
设置`virtualList`属性,处理大数据。
--VIRTUALLIST

### 控制回填内容

--LABELFIELD

### 无数据

Expand Down Expand Up @@ -80,6 +83,7 @@ app.use(FSelectTree);
| childrenField | 替代 `TreeOption` 中的 `children` 字段名 | string | `children` |
| valueField | 替代 `TreeOption` 中的 `value` 字段名 | string | `value` |
| labelField | 替代 `TreeOption` 中的 `label` 字段名 | string | `label` |
| optionLabelField | 配置选中选项显示的字段名,不传时跟`labelField`一致 | string | - |
| remote | 是否异步获取选项,和 `onLoad` 配合 | boolean | `false` |
| loadData | 异步加载数据的回调函数 | (node: TreeOption) => Promise\<void\> | `null` |
| inline | 底层节点是否横向排列 | boolean | `false` |
Expand Down
42 changes: 42 additions & 0 deletions docs/.vitepress/components/selectTree/labelField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<template>
<FSelectTree :data="data" optionLabelField="x"></FSelectTree>
</template>
<script>
import { reactive } from 'vue';
function createData(level = 1, baseKey = '', prefix = null, suffix = null) {
if (!level) return undefined;
return Array.apply(null, { length: 2 }).map((_, index) => {
const key = '' + baseKey + level + index;
return {
label: createLabel(level),
value: key,
children: createData(level - 1, key, prefix, suffix),
x: `${key}-${createLabel(level)}`,
prefix: prefix ? () => h(PictureOutlined) : null,
suffix: suffix ? () => h(PlusCircleOutlined) : null,
};
});
}
function createLabel(level) {
if (level === 4) return '道生一';
if (level === 3) return '一生二';
if (level === 2) return '二生三';
if (level === 1) return '三生万物';
}
export default {
setup() {
const data = reactive(createData(4));
return {
data,
};
},
};
</script>
<style scoped>
.fes-select-tree {
width: 200px;
}
</style>

0 comments on commit cbc9c45

Please sign in to comment.