Skip to content

Commit

Permalink
feat: 更改input值的显示逻辑;更改options的显示逻辑;增加缓存options的功能;增加多选选项但功能未完成
Browse files Browse the repository at this point in the history
  • Loading branch information
unfound committed Aug 12, 2021
1 parent 3b48f50 commit 371d0ea
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 40 deletions.
10 changes: 5 additions & 5 deletions devui/checkbox/src/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { checkboxGroupInjectionKey, checkboxProps, CheckboxProps } from './use-c
export default defineComponent({
name: 'DCheckbox',
props: checkboxProps,
emits: ['change', 'update:checked'],
emits: ['change', 'update:modelValue'],
setup (props: CheckboxProps, ctx) {
const checkboxGroupConf = inject(checkboxGroupInjectionKey, null);
const mergedDisabled = computed(() => {
return checkboxGroupConf?.disabled.value || props.disabled;
});
const mergedChecked = computed(() => {
return checkboxGroupConf ? checkboxGroupConf.isItemChecked(props.value) : props.checked;
return checkboxGroupConf ? checkboxGroupConf.isItemChecked(props.value) : props.modelValue;
});
const mergedIsShowTitle = computed(() => {
return checkboxGroupConf ? checkboxGroupConf.isShowTitle : props.isShowTitle;
Expand Down Expand Up @@ -42,13 +42,13 @@ export default defineComponent({
return Promise.resolve(true);
};
const toggle = () => {
const isChecked = !props.checked;
const isChecked = !props.modelValue;
checkboxGroupConf?.toggleGroupVal(props.value);
ctx.emit('update:checked', isChecked);
ctx.emit('update:modelValue', isChecked);
ctx.emit('change', isChecked);
};
const handleClick = () => {
canChange(!props.checked, props.value).then(res => res && toggle());
canChange(!props.modelValue, props.value).then(res => res && toggle());
};

return {
Expand Down
6 changes: 3 additions & 3 deletions devui/checkbox/src/use-checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ export const checkboxProps = {
type: Boolean,
default: false
},
checked: {
modelValue: {
type: Boolean,
default: false
},
value: {
type: String,
required: true
default: ''
},
label: {
type: String,
Expand All @@ -51,7 +51,7 @@ export const checkboxProps = {
type: String,
default: undefined
},
'onUpdate:checked' : {
'onUpdate:modelValue' : {
type: Function as PropType<(v: boolean) => void>,
default: undefined
},
Expand Down
18 changes: 18 additions & 0 deletions devui/select/hooks/use-cache-options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ComputedRef, computed } from 'vue';
import { OptionObjectItem } from '../src/use-select';
import { KeyType } from '../src/utils';

export default function (mergeOptions: ComputedRef<OptionObjectItem[]>): any {
const cacheOptions = computed(() => {
const map = new Map<KeyType<OptionObjectItem, 'value'>, OptionObjectItem>();
mergeOptions.value.forEach((item) => {
map.set(item.value, item);
});
return map;
});

const getValuesOption = (values: KeyType<OptionObjectItem, 'value'>[]) =>
values.map((value) => cacheOptions.value.get(value));

return getValuesOption;
}
9 changes: 9 additions & 0 deletions devui/select/src/select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ $select-item-min-height: 36px;
}
}

.devui-dropdown-menu-multiple {
.devui-select-item {
&.active {
color: $devui-list-item-active-text;
background-color: transparent;
}
}
}

.devui-select-selection {
position: relative;
}
Expand Down
88 changes: 58 additions & 30 deletions devui/select/src/select.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { defineComponent, ref, Transition, toRefs } from 'vue';
import { selectProps, SelectProps, OptionItem } from './use-select';
import DIcon from '../../icon/src/icon';
import { defineComponent, ref, Transition, toRefs, computed } from 'vue';
import {
selectProps,
SelectProps,
OptionObjectItem,
} from './use-select';
import { Icon } from '../../icon';
import { Checkbox } from '../../checkbox';
import { className } from './utils';
import useCacheOptions from '../hooks/use-cache-options';
import './select.scss';

export default defineComponent({
Expand All @@ -15,52 +21,69 @@ export default defineComponent({
ctx.emit('toggleChange', bool);
}

const inputValue = ref<string>(props.modelValue + '');
initInputValue();

function initInputValue() {
props.options.forEach((item) => {
if (typeof item === 'object' && item.value === props.modelValue) {
inputValue.value = item.name;
const mergeOptions = computed(() => {
return props.options.map((item) => {
let option: OptionObjectItem;
if (typeof item === 'object') {
option = {
name: item.name ? item.name : item.value + '',
value: item.value,
checked: false,
...item,
};
} else {
option = {
name: item + '',
value: item,
checked: false,
};
}

return option;
});
}
});

const getValuesOption = useCacheOptions(mergeOptions);

function valueChange(item: OptionItem, index: number) {
const value = typeof item === 'object' ? item.value : item;
inputValue.value = getInputValue(item);
ctx.emit('update:modelValue', value);
ctx.emit('valueChange', item, index);
const inputValue = computed(() => {
if (props.multiple && Array.isArray(props.modelValue)) {
const selectedOptions = getValuesOption(props.modelValue);
return selectedOptions.map((item) => item.name).join(',');
} else if (!Array.isArray(props.modelValue)) {
return getValuesOption([props.modelValue])[0]?.name || '';
}
return ''
});

function valueChange(item: OptionObjectItem, index: number) {
ctx.emit('update:modelValue', item.value);
ctx.emit('valueChange', props.options[index], index);
toggleChange(false);
}

function getItemClassName(item: OptionItem) {
const value = typeof item === 'object' ? item.value : item;
function getItemClassName(item: OptionObjectItem) {
return className('devui-select-item', {
active: value === props.modelValue,
active: item.value === props.modelValue,
});
}

function getInputValue(item: OptionItem) {
const value = typeof item === 'object' ? item.name : item;
return value + '';
}

return {
...toRefs(props),
isOpen,
inputValue,
mergeOptions,
valueChange,
toggleChange,
getItemClassName,
...toRefs(props),
};
},
render() {
const {
options,
mergeOptions,
isOpen,
inputValue,
size,
multiple,
placeholder,
overview,
valueChange,
Expand All @@ -70,6 +93,7 @@ export default defineComponent({

const selectClassName = className('devui-select', {
'devui-select-open': isOpen,
'devui-dropdown-menu-multiple': multiple,
'devui-select-lg': size === 'lg',
'devui-select-sm': size === 'sm',
'devui-select-underlined': overview === 'underlined',
Expand All @@ -90,24 +114,28 @@ export default defineComponent({
placeholder={placeholder}
readonly
onClick={() => toggleChange(!isOpen)}
onBlur={() => toggleChange(false)}
// onBlur={() => toggleChange(false)}
/>
<span class="devui-select-arrow">
<DIcon name="select-arrow" />
<Icon name="select-arrow" />
</span>
</div>
<Transition name="fade">
<div v-show={isOpen} class="devui-select-dropdown">
<ul class="devui-select-dropdown-list devui-scrollbar">
{options.map((item, i) => (
{mergeOptions.map((item, i) => (
<li
onClick={() => {
valueChange(item, i);
}}
class={getItemClassName(item)}
key={i}
>
{typeof item === 'object' ? item.name : item}
{multiple ? (
<Checkbox v-model={item.checked} label={item.name} />
) : (
item.name
)}
</li>
))}
</ul>
Expand Down
15 changes: 13 additions & 2 deletions devui/select/src/use-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@ import { PropType, ExtractPropTypes } from 'vue';
export interface OptionObjectItem {
name: string
value: string | number
checked: boolean
[key: string]: any
}
export type OptionItem = number | string | OptionObjectItem;

export type OptionItem =
| number
| string
| ({ value: string | number; } & Partial<OptionObjectItem>);
export type Options = Array<OptionItem>;

export type ModelValue = number | string | Array<number | string>;

export const selectProps = {
modelValue: {
type: [String, Number] as PropType<string | number>,
type: [String, Number, Array] as PropType<ModelValue>,
default: '',
},
'onUpdate:modelValue': {
Expand All @@ -33,6 +40,10 @@ export const selectProps = {
type: String,
default: '请选择',
},
multiple: {
type: Boolean,
default: false,
},
onToggleChange: {
type: Function as PropType<(bool: boolean) => void>,
default: undefined,
Expand Down
2 changes: 2 additions & 0 deletions devui/select/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ export function className(

return classname;
}

export type KeyType<T, K extends keyof T> = T[K]

0 comments on commit 371d0ea

Please sign in to comment.