mirror of
https://gitee.com/xuliangzhan_admin/vxe-table.git
synced 2026-01-21 05:27:57 +08:00
优化下拉框
This commit is contained in:
@@ -5,6 +5,23 @@
|
||||
|
||||
<p>
|
||||
<vxe-select v-model="demo1.value10" placeholder="默认尺寸">
|
||||
<template #header>
|
||||
<div>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
</div>
|
||||
</template>
|
||||
<vxe-option v-for="num in 15" :key="num" :value="num" :label="`选项${num}`"></vxe-option>
|
||||
</vxe-select>
|
||||
<vxe-select v-model="demo1.value11" placeholder="中等尺寸" size="medium">
|
||||
@@ -23,6 +40,23 @@
|
||||
<vxe-option v-for="num in 3" :key="num" :value="num" :label="`选项${num}`"></vxe-option>
|
||||
</vxe-select>
|
||||
<vxe-select v-model="demo1.value21" placeholder="可搜索" filterable clearable>
|
||||
<template #header>
|
||||
<div>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
<vxe-button type="text">按钮</vxe-button>
|
||||
</div>
|
||||
</template>
|
||||
<vxe-option v-for="num in 11" :key="num" :value="num" :label="`选项${num}`"></vxe-option>
|
||||
</vxe-select>
|
||||
<vxe-select v-model="demo1.value24" placeholder="远程搜索" filterable clearable remote :remote-method="remoteMethod24">
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
"sass": "^1.56.1",
|
||||
"sass-loader": "^12.0.0",
|
||||
"typescript": "~4.5.5",
|
||||
"vue": "^3.3.4",
|
||||
"vue": "^3.3.13",
|
||||
"vue-i18n": "^9.1.7",
|
||||
"vue-router": "^4.0.11",
|
||||
"vuex": "^4.0.2"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineComponent, h, Teleport, ref, Ref, onUnmounted, reactive, nextTick, PropType, watch } from 'vue'
|
||||
import { defineComponent, h, Teleport, ref, Ref, onUnmounted, reactive, nextTick, PropType, watch, createCommentVNode } from 'vue'
|
||||
import XEUtils from 'xe-utils'
|
||||
import GlobalConfig from '../../v-x-e-table/src/conf'
|
||||
import { useSize } from '../../hooks/size'
|
||||
@@ -281,6 +281,10 @@ export default defineComponent({
|
||||
const { className, popupClassName, destroyOnClose, transfer, disabled } = props
|
||||
const { inited, isActivated, animatVisible, visiblePanel, panelStyle, panelPlacement } = reactData
|
||||
const vSize = computeSize.value
|
||||
const defaultSlot = slots.default
|
||||
const headerSlot = slots.header
|
||||
const footerSlot = slots.footer
|
||||
const dropdownSlot = slots.dropdown
|
||||
return h('div', {
|
||||
ref: refElem,
|
||||
class: ['vxe-pulldown', className ? (XEUtils.isFunction(className) ? className({ $pulldown: $xepulldown }) : className) : '', {
|
||||
@@ -293,7 +297,7 @@ export default defineComponent({
|
||||
h('div', {
|
||||
ref: refPulldowContent,
|
||||
class: 'vxe-pulldown--content'
|
||||
}, slots.default ? slots.default({ $pulldown: $xepulldown }) : []),
|
||||
}, defaultSlot ? defaultSlot({ $pulldown: $xepulldown }) : []),
|
||||
h(Teleport, {
|
||||
to: 'body',
|
||||
disabled: transfer ? !inited : true
|
||||
@@ -308,10 +312,20 @@ export default defineComponent({
|
||||
}],
|
||||
placement: panelPlacement,
|
||||
style: panelStyle
|
||||
}, slots.dropdown ? [
|
||||
}, dropdownSlot ? [
|
||||
h('div', {
|
||||
class: 'vxe-pulldown--wrapper'
|
||||
}, !inited || (destroyOnClose && !visiblePanel && !animatVisible) ? [] : slots.dropdown({ $pulldown: $xepulldown }))
|
||||
class: 'vxe-pulldown--panel-wrapper'
|
||||
}, !inited || (destroyOnClose && !visiblePanel && !animatVisible) ? [] : [
|
||||
headerSlot ? h('div', {
|
||||
class: 'vxe-pulldown--panel-header'
|
||||
}, headerSlot({ $pulldown: $xepulldown })) : createCommentVNode(),
|
||||
h('div', {
|
||||
class: 'vxe-pulldown--panel-body'
|
||||
}, dropdownSlot({ $pulldown: $xepulldown })),
|
||||
footerSlot ? h('div', {
|
||||
class: 'vxe-pulldown--panel-footer'
|
||||
}, footerSlot({ $pulldown: $xepulldown })) : createCommentVNode()
|
||||
])
|
||||
] : [])
|
||||
])
|
||||
])
|
||||
|
||||
@@ -716,6 +716,7 @@ export default defineComponent({
|
||||
const valueField = computeValueField.value
|
||||
const isGroup = computeIsGroup.value
|
||||
const { useKey } = optionOpts
|
||||
const optionSlot = slots.option
|
||||
return list.map((option, cIndex) => {
|
||||
const { slots, className } = option
|
||||
const optionValue = option[valueField as 'value']
|
||||
@@ -724,9 +725,10 @@ export default defineComponent({
|
||||
const isDisabled = checkOptionDisabled(isSelected, option, group)
|
||||
const optid = getOptid(option)
|
||||
const defaultSlot = slots ? slots.default : null
|
||||
const optParams = { option, group: null, $select: $xeselect }
|
||||
return isVisible ? h('div', {
|
||||
key: useKey || optionKey ? optid : cIndex,
|
||||
class: ['vxe-select-option', className ? (XEUtils.isFunction(className) ? className({ option, $select: $xeselect }) : className) : '', {
|
||||
class: ['vxe-select-option', className ? (XEUtils.isFunction(className) ? className(optParams) : className) : '', {
|
||||
'is--disabled': isDisabled,
|
||||
'is--selected': isSelected,
|
||||
'is--hover': currentValue === optionValue
|
||||
@@ -750,7 +752,7 @@ export default defineComponent({
|
||||
setCurrentOption(option)
|
||||
}
|
||||
}
|
||||
}, defaultSlot ? callSlot(defaultSlot, { option, $select: $xeselect }) : formatText(getFuncText(option[labelField as 'label']))) : null
|
||||
}, optionSlot ? callSlot(optionSlot, optParams) : (defaultSlot ? callSlot(defaultSlot, optParams) : formatText(getFuncText(option[labelField as 'label'])))) : null
|
||||
})
|
||||
}
|
||||
|
||||
@@ -761,14 +763,16 @@ export default defineComponent({
|
||||
const groupLabelField = computeGroupLabelField.value
|
||||
const groupOptionsField = computeGroupOptionsField.value
|
||||
const { useKey } = optionOpts
|
||||
const optionSlot = slots.option
|
||||
return visibleGroupList.map((group, gIndex) => {
|
||||
const { slots, className } = group
|
||||
const optid = getOptid(group)
|
||||
const isGroupDisabled = group.disabled
|
||||
const defaultSlot = slots ? slots.default : null
|
||||
const optParams = { option: group, group, $select: $xeselect }
|
||||
return h('div', {
|
||||
key: useKey || optionKey ? optid : gIndex,
|
||||
class: ['vxe-optgroup', className ? (XEUtils.isFunction(className) ? className({ option: group, $select: $xeselect }) : className) : '', {
|
||||
class: ['vxe-optgroup', className ? (XEUtils.isFunction(className) ? className(optParams) : className) : '', {
|
||||
'is--disabled': isGroupDisabled
|
||||
}],
|
||||
// attrs
|
||||
@@ -776,7 +780,7 @@ export default defineComponent({
|
||||
}, [
|
||||
h('div', {
|
||||
class: 'vxe-optgroup--title'
|
||||
}, defaultSlot ? callSlot(defaultSlot, { option: group, $select: $xeselect }) : getFuncText(group[groupLabelField as 'label'])),
|
||||
}, optionSlot ? callSlot(optionSlot, optParams) : (defaultSlot ? callSlot(defaultSlot, optParams) : getFuncText(group[groupLabelField as 'label']))),
|
||||
h('div', {
|
||||
class: 'vxe-optgroup--wrapper'
|
||||
}, renderOption(group[groupOptionsField as 'options'] || [], group))
|
||||
@@ -912,6 +916,9 @@ export default defineComponent({
|
||||
const { inited, isActivated, visiblePanel } = reactData
|
||||
const vSize = computeSize.value
|
||||
const selectLabel = computeSelectLabel.value
|
||||
const defaultSlot = slots.default
|
||||
const headerSlot = slots.header
|
||||
const footerSlot = slots.footer
|
||||
const prefixSlot = slots.prefix
|
||||
return h('div', {
|
||||
ref: refElem,
|
||||
@@ -927,7 +934,7 @@ export default defineComponent({
|
||||
h('div', {
|
||||
class: 'vxe-select-slots',
|
||||
ref: 'hideOption'
|
||||
}, slots.default ? slots.default({}) : []),
|
||||
}, defaultSlot ? defaultSlot({}) : []),
|
||||
h(VxeInputComponent, {
|
||||
ref: refInput,
|
||||
clearable: props.clearable,
|
||||
@@ -962,11 +969,11 @@ export default defineComponent({
|
||||
style: reactData.panelStyle
|
||||
}, inited ? [
|
||||
filterable ? h('div', {
|
||||
class: 'vxe-select-filter--wrapper'
|
||||
class: 'vxe-select--panel-search'
|
||||
}, [
|
||||
h(VxeInputComponent, {
|
||||
ref: refInpSearch,
|
||||
class: 'vxe-select-filter--input',
|
||||
class: 'vxe-select-search--input',
|
||||
modelValue: reactData.searchValue,
|
||||
clearable: true,
|
||||
placeholder: GlobalConfig.i18n('vxe.select.search'),
|
||||
@@ -979,9 +986,23 @@ export default defineComponent({
|
||||
})
|
||||
]) : createCommentVNode(),
|
||||
h('div', {
|
||||
ref: refOptionWrapper,
|
||||
class: 'vxe-select-option--wrapper'
|
||||
}, renderOpts())
|
||||
class: 'vxe-select--panel-wrapper'
|
||||
}, [
|
||||
headerSlot ? h('div', {
|
||||
class: 'vxe-select--panel-header'
|
||||
}, headerSlot({})) : createCommentVNode(),
|
||||
h('div', {
|
||||
class: 'vxe-select--panel-body'
|
||||
}, [
|
||||
h('div', {
|
||||
ref: refOptionWrapper,
|
||||
class: 'vxe-select-option--wrapper'
|
||||
}, renderOpts())
|
||||
]),
|
||||
footerSlot ? h('div', {
|
||||
class: 'vxe-select--panel-footer'
|
||||
}, footerSlot({})) : createCommentVNode()
|
||||
])
|
||||
] : [])
|
||||
])
|
||||
])
|
||||
|
||||
@@ -14,7 +14,7 @@ const GlobalConfig: VXETableConfigOptions = {
|
||||
showHeader: true,
|
||||
animat: true,
|
||||
delayHover: 250,
|
||||
autoResize: false,
|
||||
autoResize: true,
|
||||
minHeight: 144,
|
||||
// keepSource: false,
|
||||
// showOverflow: null,
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
.vxe-pulldown--wrapper {
|
||||
.vxe-pulldown--panel-wrapper {
|
||||
background-color: var(--vxe-pulldown-panel-background-color);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,23 +79,40 @@
|
||||
}
|
||||
}
|
||||
|
||||
.vxe-select-filter--wrapper {
|
||||
.vxe-select--panel-search {
|
||||
display: block;
|
||||
.vxe-select-filter--input {
|
||||
.vxe-select-search--input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.vxe-select--panel-wrapper {
|
||||
position: relative;
|
||||
border-radius: var(--vxe-border-radius);
|
||||
border: 1px solid var(--vxe-table-popup-border-color);
|
||||
box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);
|
||||
background-color: var(--vxe-select-panel-background-color);
|
||||
}
|
||||
|
||||
.vxe-select--panel-header {
|
||||
border-bottom: 1px solid var(--vxe-table-popup-border-color);
|
||||
}
|
||||
|
||||
.vxe-select--panel-footer {
|
||||
border-top: 1px solid var(--vxe-table-popup-border-color);
|
||||
}
|
||||
|
||||
.vxe-select--panel-header,
|
||||
.vxe-select--panel-footer {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.vxe-select-option--wrapper {
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 4px 0;
|
||||
max-height: 200px;
|
||||
border-radius: var(--vxe-border-radius);
|
||||
border: 1px solid var(--vxe-table-popup-border-color);
|
||||
box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);
|
||||
background-color: var(--vxe-select-panel-background-color);
|
||||
}
|
||||
|
||||
.vxe-optgroup {
|
||||
|
||||
17
types/column.d.ts
vendored
17
types/column.d.ts
vendored
@@ -181,11 +181,11 @@ export namespace VxeColumnPropTypes {
|
||||
/**
|
||||
* 只对 type=radio 有效,自定义单选框模板
|
||||
*/
|
||||
radio?: string | ((params: VxeColumnSlotTypes.DefaultSlotParams<D>) => SlotVNodeType[] | SlotVNodeType) | null
|
||||
radio?: string | ((params: VxeColumnSlotTypes.RadioSlotParams<D>) => SlotVNodeType[] | SlotVNodeType) | null
|
||||
/**
|
||||
* 只对 type=checkbox 有效,自定义复选框模板
|
||||
*/
|
||||
checkbox?: string | ((params: VxeColumnSlotTypes.DefaultSlotParams<D>) => SlotVNodeType[] | SlotVNodeType) | null
|
||||
checkbox?: string | ((params: VxeColumnSlotTypes.CheckboxSlotParams<D>) => SlotVNodeType[] | SlotVNodeType) | null
|
||||
/**
|
||||
* 自定义显示内容模板
|
||||
*/
|
||||
@@ -405,7 +405,7 @@ export namespace VxeColumnSlotTypes {
|
||||
data: D[][]
|
||||
}
|
||||
|
||||
export interface HeaderSlotParams<D = VxeTableDataRow> extends VxeTableDefines.CellRenderHeaderParams<D> { }
|
||||
export interface HeaderSlotParams<D = VxeTableDataRow> extends VxeTableDefines.CellRenderHeaderParams<D> {}
|
||||
|
||||
export interface ContentSlotParams<D = VxeTableDataRow> {
|
||||
column: VxeTableDefines.ColumnInfo<D>
|
||||
@@ -421,6 +421,13 @@ export namespace VxeColumnSlotTypes {
|
||||
|
||||
export interface DefaultSlotParams<D = VxeTableDataRow> extends VxeTableDefines.CellRenderBodyParams<D> { }
|
||||
|
||||
export interface CheckboxSlotParams<D = VxeTableDataRow> extends DefaultSlotParams<D> {
|
||||
checked: boolean
|
||||
indeterminate: boolean
|
||||
}
|
||||
export interface RadioSlotParams<D = VxeTableDataRow> extends DefaultSlotParams<D> {
|
||||
checked: boolean
|
||||
}
|
||||
export interface IconSlotParams<D = VxeTableDataRow> extends DefaultSlotParams<D> { }
|
||||
}
|
||||
|
||||
@@ -444,11 +451,11 @@ export interface VxeColumnSlots<D = VxeTableDataRow> {
|
||||
/**
|
||||
* 只对 type=checkbox 有效,自定义复选框模板
|
||||
*/
|
||||
checkbox: (params: VxeColumnSlotTypes.DefaultSlotParams<D>) => any
|
||||
checkbox: (params: VxeColumnSlotTypes.CheckboxSlotParams<D>) => any
|
||||
/**
|
||||
* 只对 type=radio 有效,自定义单选框模板
|
||||
*/
|
||||
radio: (params: VxeColumnSlotTypes.DefaultSlotParams<D>) => any
|
||||
radio: (params: VxeColumnSlotTypes.RadioSlotParams<D>) => any
|
||||
/**
|
||||
* 只对 type=expand 有效,自定义展开后的内容模板
|
||||
*/
|
||||
|
||||
5
types/grid.d.ts
vendored
5
types/grid.d.ts
vendored
@@ -593,6 +593,11 @@ export interface VxeGridSlots<D = VxeTableDataRow> {
|
||||
$columnIndex: number
|
||||
_columnIndex: number
|
||||
|
||||
checked?: boolean
|
||||
indeterminate?: boolean
|
||||
|
||||
items: D[]
|
||||
|
||||
[key: string]: any
|
||||
}) => any) | undefined
|
||||
}
|
||||
|
||||
12
types/pulldown.d.ts
vendored
12
types/pulldown.d.ts
vendored
@@ -126,12 +126,24 @@ export interface VxePulldownListeners {
|
||||
}
|
||||
|
||||
export interface VxePulldownSlots {
|
||||
/**
|
||||
* 自定义弹窗容器头部模板
|
||||
*/
|
||||
header: (params: {
|
||||
[key: string]: any
|
||||
}) => any
|
||||
/**
|
||||
* 自定义显示的内容
|
||||
*/
|
||||
default: (params: {
|
||||
[key: string]: any
|
||||
}) => any
|
||||
/**
|
||||
* 自定义弹窗容器底部模板
|
||||
*/
|
||||
footer: ((params: {
|
||||
[key: string]: any
|
||||
}) => any) | undefined
|
||||
/**
|
||||
* 自定义下拉面板显示的内容
|
||||
*/
|
||||
|
||||
29
types/select.d.ts
vendored
29
types/select.d.ts
vendored
@@ -232,10 +232,39 @@ export namespace VxeSelectEvents {
|
||||
}
|
||||
|
||||
export interface VxeSelectSlots {
|
||||
/**
|
||||
* 自定义前缀图标模板
|
||||
*/
|
||||
prefix: (params: {
|
||||
[key: string]: any
|
||||
}) => any
|
||||
/**
|
||||
* 自定义弹窗容器头部模板
|
||||
*/
|
||||
header: (params: {
|
||||
[key: string]: any
|
||||
}) => any
|
||||
/**
|
||||
* 自定义弹窗容器选项模板
|
||||
*/
|
||||
option: ((params: {
|
||||
option: any
|
||||
group: any
|
||||
[key: string]: any
|
||||
}) => any) | undefined
|
||||
/**
|
||||
* 自定义弹窗容器底部模板
|
||||
*/
|
||||
footer: ((params: {
|
||||
[key: string]: any
|
||||
}) => any) | undefined
|
||||
|
||||
/**
|
||||
* 自定义插槽模板
|
||||
*/
|
||||
[key: string]: ((params: {
|
||||
option: any
|
||||
group: any
|
||||
[key: string]: any
|
||||
}) => any) | undefined
|
||||
}
|
||||
|
||||
3
types/table.d.ts
vendored
3
types/table.d.ts
vendored
@@ -2892,6 +2892,9 @@ export namespace VxeTableDefines {
|
||||
type: string
|
||||
isHidden: boolean
|
||||
hasFilter: boolean
|
||||
|
||||
checked?: boolean
|
||||
indeterminate?: boolean
|
||||
}
|
||||
|
||||
export interface CellRenderBodyParams<D = VxeTableDataRow> {
|
||||
|
||||
Reference in New Issue
Block a user