mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
perf(components): [rate] optimize mousemove and keydown logic (#21847)
refactor(components): [rate] optimaze `mousemove` and `keydown` logic
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
@click="selectValue(item)"
|
||||
>
|
||||
<el-icon
|
||||
ref="iconRefs"
|
||||
:class="[
|
||||
ns.e('icon'),
|
||||
{ hover: hoverIndex === item },
|
||||
@@ -32,9 +33,9 @@
|
||||
>
|
||||
<template v-if="!showDecimalIcon(item)">
|
||||
<component :is="activeComponent" v-show="item <= currentValue" />
|
||||
<component :is="voidComponent" v-show="!(item <= currentValue)" />
|
||||
<component :is="voidComponent" v-show="item > currentValue" />
|
||||
</template>
|
||||
<template v-if="showDecimalIcon(item)">
|
||||
<template v-else>
|
||||
<component :is="voidComponent" :class="[ns.em('decimal', 'box')]" />
|
||||
<el-icon
|
||||
:style="decimalStyle"
|
||||
@@ -57,12 +58,13 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject, markRaw, ref, watch } from 'vue'
|
||||
import { clamp } from 'lodash-unified'
|
||||
import {
|
||||
CHANGE_EVENT,
|
||||
EVENT_CODE,
|
||||
UPDATE_MODEL_EVENT,
|
||||
} from '@element-plus/constants'
|
||||
import { hasClass, isArray, isObject, isString } from '@element-plus/utils'
|
||||
import { isArray, isObject, isString } from '@element-plus/utils'
|
||||
import {
|
||||
formContextKey,
|
||||
formItemContextKey,
|
||||
@@ -74,6 +76,7 @@ import { useNamespace } from '@element-plus/hooks'
|
||||
import { rateEmits, rateProps } from './rate'
|
||||
|
||||
import type { CSSProperties, Component } from 'vue'
|
||||
import type { IconInstance } from '@element-plus/components/icon'
|
||||
|
||||
function getValueFromMap<T>(
|
||||
value: number,
|
||||
@@ -114,6 +117,10 @@ const currentValue = ref(props.modelValue)
|
||||
const hoverIndex = ref(-1)
|
||||
const pointerAtLeftHalf = ref(true)
|
||||
|
||||
const iconRefs = ref<IconInstance[]>([])
|
||||
const iconClientWidths = computed<number[]>(() =>
|
||||
iconRefs.value.map((icon) => icon.$el.clientWidth)
|
||||
)
|
||||
const rateClasses = computed(() => [ns.b(), ns.m(rateSize.value)])
|
||||
const rateDisabled = computed(() => props.disabled || formContext?.disabled)
|
||||
const rateStyles = computed(() => {
|
||||
@@ -238,27 +245,23 @@ function handleKey(e: KeyboardEvent) {
|
||||
if (rateDisabled.value) {
|
||||
return
|
||||
}
|
||||
let _currentValue = currentValue.value
|
||||
const code = e.code
|
||||
const step = props.allowHalf ? 0.5 : 1
|
||||
let _currentValue = currentValue.value
|
||||
|
||||
if (code === EVENT_CODE.up || code === EVENT_CODE.right) {
|
||||
if (props.allowHalf) {
|
||||
_currentValue += 0.5
|
||||
} else {
|
||||
_currentValue += 1
|
||||
}
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
_currentValue += step
|
||||
} else if (code === EVENT_CODE.left || code === EVENT_CODE.down) {
|
||||
if (props.allowHalf) {
|
||||
_currentValue -= 0.5
|
||||
} else {
|
||||
_currentValue -= 1
|
||||
}
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
_currentValue -= step
|
||||
}
|
||||
_currentValue = _currentValue < 0 ? 0 : _currentValue
|
||||
_currentValue = _currentValue > props.max ? props.max : _currentValue
|
||||
_currentValue = clamp(_currentValue, 0, props.max)
|
||||
|
||||
if (_currentValue === currentValue.value) {
|
||||
return
|
||||
}
|
||||
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
emit(UPDATE_MODEL_EVENT, _currentValue)
|
||||
emit(CHANGE_EVENT, _currentValue)
|
||||
return _currentValue
|
||||
@@ -269,15 +272,8 @@ function setCurrentValue(value: number, event?: MouseEvent) {
|
||||
return
|
||||
}
|
||||
if (props.allowHalf && event) {
|
||||
// TODO: use cache via computed https://github.com/element-plus/element-plus/pull/5456#discussion_r786472092
|
||||
let target = event.target as HTMLElement
|
||||
if (hasClass(target, ns.e('item'))) {
|
||||
target = target.querySelector(`.${ns.e('icon')}`)!
|
||||
}
|
||||
if (target.clientWidth === 0 || hasClass(target, ns.e('decimal'))) {
|
||||
target = target.parentNode as HTMLElement
|
||||
}
|
||||
pointerAtLeftHalf.value = event.offsetX * 2 <= target.clientWidth
|
||||
pointerAtLeftHalf.value =
|
||||
event.offsetX * 2 <= iconClientWidths.value[value - 1]
|
||||
currentValue.value = pointerAtLeftHalf.value ? value - 0.5 : value
|
||||
} else {
|
||||
currentValue.value = value
|
||||
|
||||
Reference in New Issue
Block a user