diff --git a/README.md b/README.md index e9f53bd6b..a99a103e7 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,11 @@ vue-pure-admin is a free and open source middle and back-end template. Using the Click to log in without password

- VbenAdmin Logo - VbenAdmin Logo - VbenAdmin Logo - VbenAdmin Logo - VbenAdmin Logo + PureAdmin Logo + PureAdmin Logo + PureAdmin Logo + PureAdmin Logo + PureAdmin Logo

### Use Gitpod diff --git a/README.zh-CN.md b/README.zh-CN.md index d1162cb22..9f6413c6f 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -16,11 +16,11 @@ vue-pure-admin 是一个免费开源的中后台模版。使用了最新的`vue3 点击免密登录

- VbenAdmin Logo - VbenAdmin Logo - VbenAdmin Logo - VbenAdmin Logo - VbenAdmin Logo + PureAdmin Logo + PureAdmin Logo + PureAdmin Logo + PureAdmin Logo + PureAdmin Logo

### 使用 Gitpod diff --git a/src/components/countTo/index.ts b/src/components/countTo/index.ts new file mode 100644 index 000000000..1a6a2c36e --- /dev/null +++ b/src/components/countTo/index.ts @@ -0,0 +1,10 @@ +import { App } from "vue" +import countTo from "./src/countTo" + +export const CountTo = Object.assign(countTo, { + install(app: App) { + app.component(countTo.name, countTo) + } +}) + +export default CountTo \ No newline at end of file diff --git a/src/components/countTo/src/countTo.tsx b/src/components/countTo/src/countTo.tsx new file mode 100644 index 000000000..4a4eb2ffa --- /dev/null +++ b/src/components/countTo/src/countTo.tsx @@ -0,0 +1,173 @@ +import { + defineComponent, + reactive, + computed, + watch, + onMounted, + unref, + toRef +} from "vue" +import { countToProps } from "./props" +import { isNumber } from "/@/utils/is" + +export default defineComponent({ + name: "CountTo", + props: countToProps, + emits: ["mounted", "callback"], + setup(props, { emit }) { + const state = reactive<{ + localStartVal: number + printVal: number | null + displayValue: string + paused: boolean + localDuration: number | null + startTime: number | null + timestamp: number | null + rAF: any + remaining: number | null + color: any + fontSize: string + }>({ + localStartVal: props.startVal, + displayValue: formatNumber(props.startVal), + printVal: null, + paused: false, + localDuration: props.duration, + startTime: null, + timestamp: null, + remaining: null, + rAF: null, + color: null, + fontSize: "16px" + }) + + const getCountDown = computed(() => { + return props.startVal > props.endVal + }) + + watch([() => props.startVal, () => props.endVal], () => { + if (props.autoplay) { + start() + } + }) + + function start() { + const { startVal, duration, color, fontSize } = props + state.localStartVal = startVal + state.startTime = null + state.localDuration = duration + state.paused = false + state.color = color + state.fontSize = fontSize + state.rAF = requestAnimationFrame(count) + } + + function pauseResume() { + if (state.paused) { + resume() + state.paused = false + } else { + pause() + state.paused = true + } + } + + function pause() { + cancelAnimationFrame(state.rAF) + } + + function resume() { + state.startTime = null + state.localDuration = +(state.remaining as number) + state.localStartVal = +(state.printVal as number) + requestAnimationFrame(count) + } + + function reset() { + state.startTime = null + cancelAnimationFrame(state.rAF) + state.displayValue = formatNumber(props.startVal) + } + + function count(timestamp: number) { + const { useEasing, easingFn, endVal } = props + if (!state.startTime) state.startTime = timestamp + state.timestamp = timestamp + const progress = timestamp - state.startTime + state.remaining = (state.localDuration as number) - progress + if (useEasing) { + if (unref(getCountDown)) { + state.printVal = + state.localStartVal - + easingFn( + progress, + 0, + state.localStartVal - endVal, + state.localDuration as number + ) + } else { + state.printVal = easingFn( + progress, + state.localStartVal, + endVal - state.localStartVal, + state.localDuration as number + ) + } + } else { + if (unref(getCountDown)) { + state.printVal = + state.localStartVal - + (state.localStartVal - endVal) * + (progress / (state.localDuration as number)) + } else { + state.printVal = + state.localStartVal + + (endVal - state.localStartVal) * + (progress / (state.localDuration as number)) + } + } + if (unref(getCountDown)) { + state.printVal = state.printVal < endVal ? endVal : state.printVal + } else { + state.printVal = state.printVal > endVal ? endVal : state.printVal + } + state.displayValue = formatNumber(state.printVal) + if (progress < (state.localDuration as number)) { + state.rAF = requestAnimationFrame(count) + } else { + emit("callback") + } + } + + function formatNumber(num: number | string) { + const { decimals, decimal, separator, suffix, prefix } = props + num = Number(num).toFixed(decimals) + num += "" + const x = num.split(".") + let x1 = x[0] + const x2 = x.length > 1 ? decimal + x[1] : "" + const rgx = /(\d+)(\d{3})/ + if (separator && !isNumber(separator)) { + while (rgx.test(x1)) { + x1 = x1.replace(rgx, "$1" + separator + "$2") + } + } + return prefix + x1 + x2 + suffix + } + + onMounted(() => { + if (props.autoplay) { + start() + } + emit("mounted") + }) + + return () => ( + <> + {state.displayValue} + + ) + } +}) diff --git a/src/components/countTo/src/index.vue b/src/components/countTo/src/index.ts similarity index 94% rename from src/components/countTo/src/index.vue rename to src/components/countTo/src/index.ts index 4f6675f2d..9c2f2786c 100644 --- a/src/components/countTo/src/index.vue +++ b/src/components/countTo/src/index.ts @@ -1,5 +1,6 @@ +/** +*/ \ No newline at end of file diff --git a/src/components/countTo/src/props.ts b/src/components/countTo/src/props.ts index 709f084a0..858a9b48c 100644 --- a/src/components/countTo/src/props.ts +++ b/src/components/countTo/src/props.ts @@ -1,4 +1,3 @@ -import { strict } from 'assert' import { PropType } from 'vue' import { propTypes } from '/@/utils/propTypes' export const countToProps = { @@ -18,6 +17,10 @@ export const countToProps = { type: String as PropType, require: false }, + fontSize: { + type: String as PropType, + require: false + }, decimal: propTypes.string.def('.'), separator: propTypes.string.def(','), prefix: propTypes.string.def(''), diff --git a/src/components/selector/src/selector.tsx b/src/components/selector/src/selector.tsx index 3a0773300..0b085928c 100644 --- a/src/components/selector/src/selector.tsx +++ b/src/components/selector/src/selector.tsx @@ -282,22 +282,22 @@ export default defineComponent({ { props.max.map((item, key) => { - return setCurrentValue(key)} - onMouseleave={() => resetCurrentValue(key)} - onClick={() => selectValue(key, item)} - style={{ - cursor: unref(rateDisabled) ? 'auto' : 'pointer', textAlign: 'center' - }} - key={key} - > -
- {item} -
- + return setCurrentValue(key)} + onMouseleave={() => resetCurrentValue(key)} + onClick={() => selectValue(key, item)} + style={{ + cursor: unref(rateDisabled) ? 'auto' : 'pointer', textAlign: 'center' + }} + key={key} + > +
+ {item} +
+ }) } @@ -305,5 +305,5 @@ export default defineComponent({ ) - }, + } }) \ No newline at end of file diff --git a/src/views/components/countTo/index.vue b/src/views/components/countTo/index.vue index 4439bf389..d6f6fe3f9 100644 --- a/src/views/components/countTo/index.vue +++ b/src/views/components/countTo/index.vue @@ -3,12 +3,26 @@ - + - + @@ -16,7 +30,7 @@