Skip to content

Commit

Permalink
feat: select组件基本功能
Browse files Browse the repository at this point in the history
  • Loading branch information
unfound committed Aug 7, 2021
1 parent 90b5785 commit 6dbe1dd
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 22 deletions.
24 changes: 22 additions & 2 deletions devui/select/demo/demo-basic.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
import { defineComponent } from 'vue'
import { defineComponent, Ref, ref, watch } from 'vue'
import DSelect from '../src/select'

export default defineComponent({
name: 'DSelectDemo',
setup() {
function log (bool: boolean) {
console.log('toggleChange', bool)
}

const value = ref<string | number>(9)
watch(value, () => {
console.log('值改变了!', value.value)
})

const doUpdate = (valueRef: Ref<string | number>, newVal: string | number) => {
valueRef.value = newVal
}
const updateProps = {
'onUpdate:value': (newVal: string | number) => doUpdate(value, newVal)
}
return () => {
return (
<>
<DSelect />
<DSelect
value={ value.value }
onToggleChange = { log }
options={ [1,2,3,'www',9,6,4,5,1,54654,546,'wybhjbxhjabxhjbsajhvbashjcbsahjcbjahbchjasbcsjahbchj'] }
{ ...updateProps }
/>
</>
)
}
Expand Down
63 changes: 62 additions & 1 deletion devui/select/src/select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

.devui-select-dropdown {
position: absolute;
max-height: 200px;
width: calc(100% - 2px);
overflow: auto;
top: 100%;
Expand All @@ -18,4 +17,66 @@
border-radius: 2px;
background: #ffffff;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);
z-index: 999;
}

.devui-select-dropdown-list {
max-height: 300px;
width: 100%;
overflow-y: auto;
}

.devui-select-item {
font-size: var(--devui-font-size, 12px);
display: block;
min-height: 36px;
line-height: 1.5;
width: 100%;
padding: 10px;
clear: both;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
border: 0;
color: $devui-text;

&:hover:not(.active) {
color: $devui-list-item-hover-text;
background-color: $devui-list-item-hover-bg;
}

&.active {
color: $devui-list-item-active-text;
background-color: $devui-list-item-active-bg;
}
}

.devui-scrollbar {
&::-webkit-scrollbar {
width: 8px;
height: 8px;
}

&::-webkit-scrollbar-corner {
background-color: transparent;
}

&::-webkit-scrollbar-thumb {
border-radius: 8px;
background-color: var(--devui-line, #adb0b8);
}

&::-webkit-scrollbar-track {
background-color: transparent;
}
}

.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
97 changes: 78 additions & 19 deletions devui/select/src/select.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,87 @@

import './select.scss'
import { defineComponent } from 'vue'
import { defineComponent, ref, Transition, computed } from 'vue'
import { selectProps, SelectProps, OptionItem } from './use-select'

export default defineComponent({
name: 'DSelect',
setup() {
return () => {
return (
<div class="devui-select">
<div class="devui-select-selection">
<input
{...{dtextinput: true}}
type="text"
class="devui-select-input"
/>
</div>
<div class="devui-select-dropdown">
<ul class="devui-select-dropdown-list">
<li class="devui-select-item">试试</li>
<li class="devui-select-item">试试</li>
props: selectProps,
emits: ['toggleChange', 'valueChange', 'update:value'],
setup (props: SelectProps, ctx) {
const isOpen = ref<boolean>(false)
function toggleChange (bool: boolean) {
isOpen.value = bool
ctx.emit('toggleChange', bool)
}

const inputValue = computed(() => {
return props.value + ''
})
function valueChange (item: OptionItem, index: number) {
const value = typeof item === 'object' ? item.value : item
ctx.emit('update:value', value)
ctx.emit('valueChange', item, index)
toggleChange(false)
}

function getItemClassName (item: OptionItem) {
let classname = 'devui-select-item'
const value = typeof item === 'object' ? item.value : item
if (value === props.value) {
classname = 'devui-select-item active'
}
return classname
}

return {
isOpen,
inputValue,
valueChange,
toggleChange,
getItemClassName,
...props
}
},
render () {
const {
options,
isOpen,
inputValue,
valueChange,
toggleChange,
getItemClassName
} = this

return (
<div class="devui-select">
<div class="devui-select-selection">
<input
{...{dtextinput: true}}
value={ inputValue }
type="text"
class="devui-select-input"
readonly
onClick={ () => toggleChange(true) }
/>
</div>
<Transition name="fade">
<div v-show={ isOpen } class="devui-select-dropdown">
<ul class="devui-select-dropdown-list devui-scrollbar">
{
options.map((item, i) => (
<li
onClick={ () => { valueChange(item, i) } }
class={ getItemClassName(item) }
key={ i }
>
{ typeof item === 'object' ? item.name : item }
</li>
))
}
</ul>
</div>
</div>
)
}
</Transition>
</div>
)
}
})
30 changes: 30 additions & 0 deletions devui/select/src/use-select.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { PropType, ExtractPropTypes } from 'vue'

export interface OptionObjectItem {
name: string
value: string | number
[key: string]: any
}
export type OptionItem = number | string | OptionObjectItem
export type Options = Array<OptionItem>

export const selectProps = {
value: {
type: [String, Number] as PropType<string | number>,
default: ''
},
'onUpdate:value': {
type: Function as PropType<(val: string | number) => void>,
default: undefined
},
options: {
type: Array as PropType<Options>,
default: () => []
},
onToggleChange: {
type: Function as PropType<(bool: boolean) => void>,
default: undefined
}
} as const

export type SelectProps = ExtractPropTypes<typeof selectProps>

0 comments on commit 6dbe1dd

Please sign in to comment.