Skip to content

Commit

Permalink
feat: 多选初步完成;多选demo;点击select外边隐藏下拉
Browse files Browse the repository at this point in the history
  • Loading branch information
unfound committed Aug 13, 2021
1 parent 371d0ea commit 66c19c0
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 9 deletions.
34 changes: 34 additions & 0 deletions devui/select/hooks/use-select-outside-click.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Ref, onMounted, onBeforeUnmount } from 'vue';

export default function (
refs: Ref[],
isOpen: Ref<boolean>,
toggleChange: (isOpen: boolean) => void
): void {
function onGlobalMouseDown(e: MouseEvent) {
let target = e.target as HTMLElement;

/**
* TODO: 需要去了解下shadow DOM
*/
if (target.shadowRoot && e.composed) {
target = (e.composedPath()[0] || target) as HTMLElement;
}

const element = [refs[0]?.value, refs[1]?.value];
if (
isOpen.value &&
element.every((el) => el && !el.contains(target) && el !== target)
) {
toggleChange(false);
}
}

onMounted(() => {
document.body.addEventListener('mousedown', onGlobalMouseDown, false);
});

onBeforeUnmount(() => {
document.body.addEventListener('mousedown', onGlobalMouseDown, false);
});
}
30 changes: 22 additions & 8 deletions devui/select/src/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,22 @@ import { Icon } from '../../icon';
import { Checkbox } from '../../checkbox';
import { className } from './utils';
import useCacheOptions from '../hooks/use-cache-options';
import useSelectOutsideClick from '../hooks/use-select-outside-click';
import './select.scss';

export default defineComponent({
name: 'DSelect',
props: selectProps,
emits: ['toggleChange', 'valueChange', 'update:modelValue'],
setup(props: SelectProps, ctx) {
const containerRef = ref(null)
const dropdownRef = ref(null)
const isOpen = ref<boolean>(false);
function toggleChange(bool: boolean) {
isOpen.value = bool;
ctx.emit('toggleChange', bool);
}
useSelectOutsideClick([containerRef, dropdownRef], isOpen, toggleChange)

const mergeOptions = computed(() => {
return props.options.map((item) => {
Expand Down Expand Up @@ -56,9 +60,16 @@ export default defineComponent({
});

function valueChange(item: OptionObjectItem, index: number) {
ctx.emit('update:modelValue', item.value);
ctx.emit('valueChange', props.options[index], index);
toggleChange(false);
let { modelValue } = props
if (props.multiple) {
item.checked = !item.checked
modelValue = mergeOptions.value.filter(item => item.checked).map(item => item.value)
ctx.emit('update:modelValue', modelValue);
} else {
ctx.emit('update:modelValue', item.value);
toggleChange(false);
}
ctx.emit('valueChange', item, index);
}

function getItemClassName(item: OptionObjectItem) {
Expand All @@ -70,6 +81,8 @@ export default defineComponent({
return {
...toRefs(props),
isOpen,
containerRef,
dropdownRef,
inputValue,
mergeOptions,
valueChange,
Expand Down Expand Up @@ -105,7 +118,7 @@ export default defineComponent({
});

return (
<div class={selectClassName}>
<div class={selectClassName} ref="containerRef">
<div class="devui-select-selection">
<input
value={inputValue}
Expand All @@ -114,25 +127,26 @@ export default defineComponent({
placeholder={placeholder}
readonly
onClick={() => toggleChange(!isOpen)}
// onBlur={() => toggleChange(false)}
/>
<span class="devui-select-arrow">
<Icon name="select-arrow" />
</span>
</div>
<Transition name="fade">
<Transition name="fade" ref="dropdownRef">
<div v-show={isOpen} class="devui-select-dropdown">
<ul class="devui-select-dropdown-list devui-scrollbar">
{mergeOptions.map((item, i) => (
<li
onClick={() => {
onClick={(e: MouseEvent) => {
e.preventDefault()
e.stopPropagation()
valueChange(item, i);
}}
class={getItemClassName(item)}
key={i}
>
{multiple ? (
<Checkbox v-model={item.checked} label={item.name} />
<Checkbox modelValue={item.checked} label={item.name}/>
) : (
item.name
)}
Expand Down
2 changes: 1 addition & 1 deletion devui/select/src/use-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const selectProps = {
default: '',
},
'onUpdate:modelValue': {
type: Function as PropType<(val: string | number) => void>,
type: Function as PropType<(val: ModelValue) => void>,
default: undefined,
},
options: {
Expand Down
10 changes: 10 additions & 0 deletions sites/components/select/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
<d-select v-model="selectValue4" :options="selectOptions4" size="lg" overview="underlined"></d-select>
<br/>

#### Mutiple

<br/>
<MutipleSelectDemo/>
<br/>

```html
<d-select v-model="baseSelectValue" :options="baseSelectOptions" size="lg"></d-select>

Expand All @@ -44,8 +50,12 @@

<script lang="ts">
import { defineComponent, ref, reactive } from 'vue'
import MutipleSelectDemo from './mutiple-select-demo.vue'

export default defineComponent({
components: {
MutipleSelectDemo
},
setup() {
const selectValue1 = ref('')
const selectValue2 = ref('')
Expand Down
19 changes: 19 additions & 0 deletions sites/components/select/mutiple-select-demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<d-select v-model="value" :options="options" :multiple="true" />
</template>

<script lang="ts">
import { defineComponent, reactive, ref } from 'vue'
export default defineComponent({
setup () {
const value = ref([])
const options = reactive([1,2,3])
return {
value,
options
}
},
})
</script>

0 comments on commit 66c19c0

Please sign in to comment.