refactor: rate

pull/4165/head
tanjinzhou 2021-06-02 11:40:33 +08:00
parent 836ae6d5fe
commit bc85604d94
6 changed files with 47 additions and 58 deletions

View File

@ -1,14 +1,14 @@
import { onBeforeUpdate, readonly, ref, DeepReadonly, UnwrapRef } from 'vue'; import { onBeforeUpdate, ref, Ref } from 'vue';
export type UseRef = [(el: any) => void, DeepReadonly<UnwrapRef<any[]>>]; export type UseRef = [(el: any, key: string | number) => void, Ref<any>];
export const useRef = (): UseRef => { export const useRef = (): UseRef => {
const refs = ref<any>([]); const refs = ref<any>({});
const setRef = (el: any) => { const setRef = (el: any, key: string | number) => {
refs.value.push(el); refs.value[key] = el;
}; };
onBeforeUpdate(() => { onBeforeUpdate(() => {
refs.value = []; refs.value = {};
}); });
return [setRef, readonly(refs)]; return [setRef, refs];
}; };

View File

@ -390,7 +390,7 @@ function isValidElement(element) {
} }
function getPropsSlot(slots, props, prop = 'default') { function getPropsSlot(slots, props, prop = 'default') {
return slots[prop]?.() ?? props[prop]; return props[prop] ?? slots[prop]?.();
} }
export { export {

View File

@ -12,7 +12,6 @@ export const starProps = {
characterRender: PropTypes.func, characterRender: PropTypes.func,
focused: PropTypes.looseBool, focused: PropTypes.looseBool,
count: PropTypes.number, count: PropTypes.number,
onClick: PropTypes.func, onClick: PropTypes.func,
onHover: PropTypes.func, onHover: PropTypes.func,
}; };
@ -23,23 +22,24 @@ export default defineComponent({
name: 'Star', name: 'Star',
inheritAttrs: false, inheritAttrs: false,
props: starProps, props: starProps,
emits: ['hover', 'click'],
setup(props, { slots, emit }) { setup(props, { slots, emit }) {
const onHover = e => { const onHover = (e: MouseEvent) => {
const { index } = props; const { index } = props;
emit('hover', e, index); emit('hover', e, index);
}; };
const onClick = e => { const onClick = (e: MouseEvent) => {
const { index } = props; const { index } = props;
emit('click', e, index); emit('click', e, index);
}; };
const onKeyDown = e => { const onKeyDown = (e: KeyboardEvent) => {
const { index } = props; const { index } = props;
if (e.keyCode === 13) { if (e.keyCode === 13) {
emit('click', e, index); emit('click', e, index);
} }
}; };
const getClassName = computed(() => { const cls = computed(() => {
const { prefixCls, index, value, allowHalf, focused } = props; const { prefixCls, index, value, allowHalf, focused } = props;
const starValue = index + 1; const starValue = index + 1;
let className = prefixCls; let className = prefixCls;
@ -59,12 +59,11 @@ export default defineComponent({
return className; return className;
}); });
const character = getPropsSlot(slots, props, 'character');
return () => { return () => {
const { disabled, prefixCls, characterRender, index, count, value } = props; const { disabled, prefixCls, characterRender, index, count, value } = props;
const character = getPropsSlot(slots, props, 'character');
let star = ( let star = (
<li class={getClassName.value}> <li class={cls.value}>
<div <div
onClick={disabled ? null : onClick} onClick={disabled ? null : onClick}
onKeydown={disabled ? null : onKeyDown} onKeydown={disabled ? null : onKeyDown}

View File

@ -1,13 +1,4 @@
import { import { defineComponent, ExtractPropTypes, ref, reactive, VNode, onMounted } from 'vue';
defineComponent,
ExtractPropTypes,
ref,
reactive,
VNode,
onUpdated,
onBeforeUpdate,
onMounted,
} from 'vue';
import { initDefaultProps, getPropsSlot, findDOMNode } from '../_util/props-util'; import { initDefaultProps, getPropsSlot, findDOMNode } from '../_util/props-util';
import { withInstall } from '../_util/type'; import { withInstall } from '../_util/type';
import { getOffsetLeft } from './util'; import { getOffsetLeft } from './util';
@ -39,6 +30,7 @@ export type RateProps = Partial<ExtractPropTypes<typeof rateProps>>;
const Rate = defineComponent({ const Rate = defineComponent({
name: 'ARate', name: 'ARate',
inheritAttrs: false,
props: initDefaultProps(rateProps, { props: initDefaultProps(rateProps, {
value: 0, value: 0,
count: 5, count: 5,
@ -55,16 +47,16 @@ const Rate = defineComponent({
const rateRef = ref(); const rateRef = ref();
const [setRef, starRefs] = useRef(); const [setRef, starRefs] = useRef();
const state = reactive({ const state = reactive({
sValue: props.value, value: props.value,
focused: false, focused: false,
cleanedValue: null, cleanedValue: null,
hoverValue: undefined, hoverValue: undefined,
}); });
const getStarDOM = index => { const getStarDOM = (index: number) => {
return findDOMNode(starRefs[index]); return findDOMNode(starRefs.value[index]);
}; };
const getStarValue = (index, x) => { const getStarValue = (index: number, x: number) => {
const reverse = direction.value === 'rtl'; const reverse = direction.value === 'rtl';
let value = index + 1; let value = index + 1;
if (props.allowHalf) { if (props.allowHalf) {
@ -80,12 +72,12 @@ const Rate = defineComponent({
return value; return value;
}; };
const changeValue = (value: number) => { const changeValue = (value: number) => {
state.sValue = value; state.value = value;
emit('update:value', value); emit('update:value', value);
emit('change', value); emit('change', value);
}; };
const onHover = (e: MouseEvent, index) => { const onHover = (e: MouseEvent, index: number) => {
const hoverValue = getStarValue(index, e.pageX); const hoverValue = getStarValue(index, e.pageX);
if (hoverValue !== state.cleanedValue) { if (hoverValue !== state.cleanedValue) {
state.hoverValue = hoverValue; state.hoverValue = hoverValue;
@ -98,12 +90,12 @@ const Rate = defineComponent({
state.cleanedValue = null; state.cleanedValue = null;
emit('hoverChange', undefined); emit('hoverChange', undefined);
}; };
const onClick = (event: MouseEvent, index) => { const onClick = (event: MouseEvent, index: number) => {
const { allowClear } = props; const { allowClear } = props;
const newValue = getStarValue(index, event.pageX); const newValue = getStarValue(index, event.pageX);
let isReset = false; let isReset = false;
if (allowClear) { if (allowClear) {
isReset = newValue === state.sValue; isReset = newValue === state.value;
} }
onMouseLeave(); onMouseLeave();
changeValue(isReset ? 0 : newValue); changeValue(isReset ? 0 : newValue);
@ -117,41 +109,41 @@ const Rate = defineComponent({
state.focused = false; state.focused = false;
emit('blur'); emit('blur');
}; };
const onKeyDown = event => { const onKeyDown = (event: KeyboardEvent) => {
const { keyCode } = event; const { keyCode } = event;
const { count, allowHalf } = props; const { count, allowHalf } = props;
const reverse = direction.value === 'rtl'; const reverse = direction.value === 'rtl';
if (keyCode === KeyCode.RIGHT && state.sValue < count && !reverse) { if (keyCode === KeyCode.RIGHT && state.value < count && !reverse) {
if (allowHalf) { if (allowHalf) {
state.sValue += 0.5; state.value += 0.5;
} else { } else {
state.sValue += 1; state.value += 1;
} }
changeValue(state.sValue); changeValue(state.value);
event.preventDefault(); event.preventDefault();
} else if (keyCode === KeyCode.LEFT && state.sValue > 0 && !reverse) { } else if (keyCode === KeyCode.LEFT && state.value > 0 && !reverse) {
if (allowHalf) { if (allowHalf) {
state.sValue -= 0.5; state.value -= 0.5;
} else { } else {
state.sValue -= 1; state.value -= 1;
} }
changeValue(state.sValue); changeValue(state.value);
event.preventDefault(); event.preventDefault();
} else if (keyCode === KeyCode.RIGHT && state.sValue > 0 && reverse) { } else if (keyCode === KeyCode.RIGHT && state.value > 0 && reverse) {
if (allowHalf) { if (allowHalf) {
state.sValue -= 0.5; state.value -= 0.5;
} else { } else {
state.sValue -= 1; state.value -= 1;
} }
changeValue(state.sValue); changeValue(state.value);
event.preventDefault(); event.preventDefault();
} else if (keyCode === KeyCode.LEFT && state.sValue < count && reverse) { } else if (keyCode === KeyCode.LEFT && state.value < count && reverse) {
if (allowHalf) { if (allowHalf) {
state.sValue += 0.5; state.value += 0.5;
} else { } else {
state.sValue += 1; state.value += 1;
} }
changeValue(state.sValue); changeValue(state.value);
event.preventDefault(); event.preventDefault();
} }
emit('keydown', event); emit('keydown', event);
@ -174,8 +166,8 @@ const Rate = defineComponent({
}); });
onMounted(() => { onMounted(() => {
const { autoFocus, disabled } = props; const { autofocus, disabled } = props;
if (autoFocus && !disabled) { if (autofocus && !disabled) {
focus(); focus();
} }
}); });
@ -195,14 +187,14 @@ const Rate = defineComponent({
for (let index = 0; index < count; index++) { for (let index = 0; index < count; index++) {
stars.push( stars.push(
<Star <Star
ref={setRef} ref={(r: any) => setRef(r, index)}
key={index} key={index}
index={index} index={index}
count={count} count={count}
disabled={disabled} disabled={disabled}
prefixCls={`${prefixCls.value}-star`} prefixCls={`${prefixCls.value}-star`}
allowHalf={allowHalf} allowHalf={allowHalf}
value={state.hoverValue === undefined ? state.sValue : state.hoverValue} value={state.hoverValue === undefined ? state.value : state.hoverValue}
onClick={onClick} onClick={onClick}
onHover={onHover} onHover={onHover}
character={character} character={character}

View File

@ -1,5 +1,3 @@
/* eslint-disable import/prefer-default-export */
function getScroll(w: Window) { function getScroll(w: Window) {
let ret = w.pageXOffset; let ret = w.pageXOffset;
const method = 'scrollLeft'; const method = 'scrollLeft';

2
v2-doc

@ -1 +1 @@
Subproject commit 0f6d531d088d5283250c8cec1c7e8be0e0d36a36 Subproject commit 001bf204ea9b389f1ab7ec1ce23cd6243db64251