mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
* feat(components): collapse use provide/inject instead of mitt events # Conflicts: # packages/components/collapse/src/collapse-item.vue # packages/components/collapse/src/collapse.vue * feat(components): menu use provide/inject instead of mitt events # Conflicts: # packages/components/menu/src/menu.ts * feat(components): form use provide/inject instead of mitt events # Conflicts: # packages/components/checkbox/src/checkbox-group.vue # packages/components/checkbox/src/useCheckbox.ts # packages/components/form/src/form-item.vue # packages/components/form/src/form.vue # packages/components/input/src/index.vue # packages/components/radio/src/radio-group.vue # packages/components/select/src/useSelect.ts # packages/components/slider/src/index.vue # packages/components/time-picker/src/common/picker.vue # packages/components/transfer/src/index.vue # packages/tokens/form.ts * feat(components): tree use provide/inject instead of mitt events # Conflicts: # packages/components/tree/src/model/useDragNode.ts # packages/components/tree/src/tree-node.vue * feat(components): select use provide/inject instead of mitt events # Conflicts: # packages/components/select/src/option-group.vue # packages/components/select/src/select.vue # packages/components/select/src/useOption.ts # packages/components/select/src/useSelect.ts * feat: remove mitt from packages dependencies # Conflicts: # packages/components/package.json # packages/element-plus/package.json # packages/tokens/package.json * feat: remove mitt from webpack.config.js * refactor: change imports order * refactor: import types separately * fix: revert removing mitt from webpack.config.js This config is not related to the build so no need to remove mitt here
140 lines
3.3 KiB
TypeScript
140 lines
3.3 KiB
TypeScript
import { inject, computed, getCurrentInstance, watch, toRaw, unref } from 'vue'
|
|
import { getValueByPath, escapeRegexpString } from '@element-plus/utils/util'
|
|
import { selectKey, selectGroupKey } from './token'
|
|
|
|
import type { Ref } from 'vue'
|
|
import type { QueryChangeCtx } from './token'
|
|
|
|
export function useOption(props, states) {
|
|
// inject
|
|
const select = inject(selectKey)
|
|
const selectGroup = inject(selectGroupKey, { disabled: false })
|
|
|
|
// computed
|
|
const isObject = computed(() => {
|
|
return (
|
|
Object.prototype.toString.call(props.value).toLowerCase() ===
|
|
'[object object]'
|
|
)
|
|
})
|
|
|
|
const itemSelected = computed(() => {
|
|
if (!select.props.multiple) {
|
|
return isEqual(props.value, select.props.modelValue)
|
|
} else {
|
|
return contains(select.props.modelValue as unknown[], props.value)
|
|
}
|
|
})
|
|
|
|
const limitReached = computed(() => {
|
|
if (select.props.multiple) {
|
|
const modelValue = (select.props.modelValue || []) as unknown[]
|
|
return (
|
|
!itemSelected.value &&
|
|
modelValue.length >= select.props.multipleLimit &&
|
|
select.props.multipleLimit > 0
|
|
)
|
|
} else {
|
|
return false
|
|
}
|
|
})
|
|
|
|
const currentLabel = computed(() => {
|
|
return props.label || (isObject.value ? '' : props.value)
|
|
})
|
|
|
|
const currentValue = computed(() => {
|
|
return props.value || props.label || ''
|
|
})
|
|
|
|
const isDisabled = computed(() => {
|
|
return props.disabled || states.groupDisabled || limitReached.value
|
|
})
|
|
|
|
const instance = getCurrentInstance()
|
|
|
|
const contains = (arr = [], target) => {
|
|
if (!isObject.value) {
|
|
return arr && arr.indexOf(target) > -1
|
|
} else {
|
|
const valueKey = select.props.valueKey
|
|
return (
|
|
arr &&
|
|
arr.some((item) => {
|
|
return (
|
|
getValueByPath(item, valueKey) === getValueByPath(target, valueKey)
|
|
)
|
|
})
|
|
)
|
|
}
|
|
}
|
|
|
|
const isEqual = (a: unknown, b: unknown) => {
|
|
if (!isObject.value) {
|
|
return a === b
|
|
} else {
|
|
const { valueKey } = select.props
|
|
return getValueByPath(a, valueKey) === getValueByPath(b, valueKey)
|
|
}
|
|
}
|
|
|
|
const hoverItem = () => {
|
|
if (!props.disabled && !selectGroup.disabled) {
|
|
select.hoverIndex = select.optionsArray.indexOf(instance)
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => currentLabel.value,
|
|
() => {
|
|
if (!props.created && !select.props.remote) select.setSelected()
|
|
}
|
|
)
|
|
|
|
watch(
|
|
() => props.value,
|
|
(val, oldVal) => {
|
|
const { remote, valueKey } = select.props
|
|
if (!props.created && !remote) {
|
|
if (
|
|
valueKey &&
|
|
typeof val === 'object' &&
|
|
typeof oldVal === 'object' &&
|
|
val[valueKey] === oldVal[valueKey]
|
|
) {
|
|
return
|
|
}
|
|
select.setSelected()
|
|
}
|
|
}
|
|
)
|
|
|
|
watch(
|
|
() => selectGroup.disabled,
|
|
() => {
|
|
states.groupDisabled = selectGroup.disabled
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
const { queryChange } = toRaw(select)
|
|
watch(queryChange, (changes: Ref<QueryChangeCtx>) => {
|
|
const { query } = unref(changes)
|
|
|
|
const regexp = new RegExp(escapeRegexpString(query), 'i')
|
|
states.visible = regexp.test(currentLabel.value) || props.created
|
|
if (!states.visible) {
|
|
select.filteredOptionsCount--
|
|
}
|
|
})
|
|
|
|
return {
|
|
select,
|
|
currentLabel,
|
|
currentValue,
|
|
itemSelected,
|
|
isDisabled,
|
|
hoverItem,
|
|
}
|
|
}
|