feat(select): default-value

This commit is contained in:
07akioni 2020-12-09 00:11:06 +08:00
parent af8cccffa8
commit 2f767df423
3 changed files with 27 additions and 15 deletions

View File

@ -24,6 +24,7 @@ fallback-option
|Name|Type|Default|Description|
|-|-|-|-|
|clearable|`boolean`|`false`||
|default-value|`Array<string \| number> \| string \| number \| null`|`null`||
|disabled|`boolean`|`false`||
|fallback-option|`false \| (value: string \| number) => SelectOption`|`value => ({ label: '' + value, value })`|The option to be created according the value which has no corresponding option in the options of the component. If set to `false`, the fallback option won't be created and displayed and the value has no corresponding option will be viewed as a invalid value and it will be removed in the operations of the component.|
|filterable|`boolean`|`false`|Whether it can filter options.|
@ -36,7 +37,7 @@ fallback-option
|size|`'small' \| 'medium' \| 'large'`|`'medium'`||
|tag|`boolean`|`false`|Whether it can create new option, should be used with `filterable`.|
|theme|`'light' \| 'dark' \| string`|`undefined`||
|value|`Array<string \| number> \| string \| number`|`false`||
|value|`Array<string \| number> \| string \| number \| null`|`undefined`||
|on-blur|`() => any`|Selection blur.|
|on-create|`(label: string) => SelectOption`|`label => ({ label, value: label })`|How to create a option when you input a string to create a option. Note that `filter` will be applied to the created option too. And make sure the value of the created option is not the same as any other option.|
|on-focus|`() => any`|Selection focus.|

View File

@ -26,6 +26,7 @@ menu-debug
|名称|类型|默认值|说明|
|-|-|-|-|
|clearable|`boolean`|`false`||
|default-value|`Array<string \| number> \| string \| number \| null`|`null`||
|disabled|`boolean`|`false`||
|fallback-option|`false \| (value: string \| number) => SelectOption`|`value => ({ label: '' + value, value })`|在传入的选项中没有对应当前值的选项时,这个值应该对应的选项。如果设为 `false`,不会为找不到对应选项的值生成回退选项也不会显示它,未在选项中的值会被视为不合法,操作过程中会被组件清除掉|
|filterable|`boolean`|`false`|是否可以过滤|
@ -38,7 +39,7 @@ menu-debug
|size|`'small' \| 'medium' \| 'large'`|`'medium'`||
|tag|`boolean`|`false`|是否可以创建新的选项,需要和 `filterable` 一起使用|
|theme|`'light' \| 'dark' \| string`|`undefined`||
|value|`Array<string \| number> \| string \| number`|`false`||
|value|`Array<string \| number> \| string \| number \| null`|`undefined`||
|on-blur|`() => any`|选择器 Blur 时发出|
|on-create|`(label: string) => SelectOption`|`label => ({ label, value: label })`|在输入内容时如何创建一个选项。注意 `filter` 对这个生成的选项同样会生效。同时确保这个选项和其他选项的 `value` 不要有重复|
|on-focus|`() => any`|选择器 Focus 时发出|

View File

@ -66,7 +66,7 @@
:multiple="multiple"
size="medium"
:filterable="filterable"
:value="value"
:value="mergedValue"
@menu-toggle-option="handleToggleOption"
@scroll="handleMenuScroll"
>
@ -195,10 +195,14 @@ export default {
type: Array,
required: true
},
value: {
defaultValue: {
type: [String, Number, Array],
default: null
},
value: {
type: [String, Number, Array],
default: undefined
},
placeholder: {
type: String,
default: undefined
@ -313,6 +317,9 @@ export default {
}
},
setup (props) {
const uncontrolledValueRef = ref(props.defaultValue)
const controlledValueRef = toRef(props, 'value')
const mergedValueRef = useMergedState(controlledValueRef, uncontrolledValueRef)
const patternRef = ref('')
const filteredOptionsRef = computed(() => filterOptions(
props.options,
@ -354,6 +361,8 @@ export default {
createdOptions: ref([]),
beingCreatedOptions: ref([]),
memoValOptMap: ref(new Map()),
uncontrolledValue: uncontrolledValueRef,
mergedValue: mergedValueRef,
followerRef
}
},
@ -382,7 +391,7 @@ export default {
},
selectedOptions () {
if (this.multiple) {
const { value: values } = this
const { mergedValue: values } = this
if (!Array.isArray(values)) return []
const remote = this.remote
const {
@ -409,17 +418,17 @@ export default {
},
selectedOption () {
if (!this.multiple) {
const { value, valOptMap, wrappedFallbackOption } = this
if (value === null) return null
const { mergedValue, valOptMap, wrappedFallbackOption } = this
if (mergedValue === null) return null
let selectedOption = null
if (valOptMap.has(value)) {
selectedOption = valOptMap.get(value)
if (valOptMap.has(mergedValue)) {
selectedOption = valOptMap.get(mergedValue)
} else if (this.remote) {
selectedOption = this.memoValOptMap.get(value)
selectedOption = this.memoValOptMap.get(mergedValue)
}
return (
selectedOption ||
(wrappedFallbackOption && wrappedFallbackOption(value)) ||
(wrappedFallbackOption && wrappedFallbackOption(mergedValue)) ||
null
)
}
@ -443,7 +452,7 @@ export default {
if (!this.mergedShow) return
this.$nextTick(this.syncPosition)
},
value () {
mergedValue () {
if (!this.mergedShow) return
this.$nextTick(this.syncPosition)
}
@ -461,6 +470,7 @@ export default {
} = this
if (onChange) call(onChange, value)
if (onUpdateValue) call(onUpdateValue, value)
this.uncontrolledValue = value
nTriggerFormChange()
nTriggerFormInput()
},
@ -586,7 +596,7 @@ export default {
this.memoValOptMap.set(option.value, option)
}
if (this.multiple) {
const changedValue = this.createClearedMultipleSelectValue(this.value)
const changedValue = this.createClearedMultipleSelectValue(this.mergedValue)
const index = changedValue.findIndex(value => value === option.value)
if (~index) {
changedValue.splice(index, 1)
@ -620,7 +630,7 @@ export default {
},
handleDeleteLastOption (e) {
if (!this.pattern.length) {
const changedValue = this.createClearedMultipleSelectValue(this.value)
const changedValue = this.createClearedMultipleSelectValue(this.mergedValue)
if (Array.isArray(changedValue)) {
const poppedValue = changedValue.pop()
const createdOptionIndex = this.getCreatedOptionIndex(poppedValue)
@ -636,7 +646,7 @@ export default {
)
},
handlePatternInput (e) {
const value = e.target.value
const { value } = e.target
this.pattern = value
const { onSearch, tag, remote } = this
if (onSearch) {