Skip to content

开源库

vueuse 是一个开源的 实用的 vue 组合式 API 库

倒计时

js
import { isCallable } from "@/tools";
import { ref } from "vue";

// 倒计时
export function useCountDown(initSecs = 5) {
	const seconds = initSecs;
	const countdown = ref(seconds);

	let timer;
	function startCountdown(onEnd) {
		timer && clearTimeout(timer);
		timer = setInterval(() => {
			countdown.value -= 1;
			if (countdown.value <= 0) {
				timer && clearTimeout(timer);
				isCallable(onEnd) && onEnd();
			}
		}, 1000);
	}

	function restartCountdown(onEnd) {
		countdown.value = seconds;
		startCountdown(onEnd);
	}

	return {
		countdown,
		startCountdown,
		restartCountdown,
	};
}
vue
<template>
  <button @click="handleClick">
    <span>发送短信验证码</span>
    <span v-if="isDisabled">({{ countdown }})</span>
  </button>
</template>

<script setup>
import { ref } from "vue";
import { useCountDown } from "@/hooks";

const isDisabled = ref(false);
const { countdown, restartCountdown } = useCountDown(60);

function handleClick() {
  if (isDisabled.value) {
    return;
  }

  isDisabled.value = true;
  restartCountdown(() => {
    isDisabled.value = false;
  });
}
</script>

可重置的响应式对象

js
import { reactive, ref } from "vue";

// 深度克隆
function deepClone(obj) {
	return structuredClone(obj);
}

// 可以重置的 reactive
export function useResettableRective(obj) {
	const initial = deepClone(obj);
	const state = reactive(obj);

	function reset() {
		return Object.assign(state, initial);
	}

	// 可以这样返回, 看编码习惯
	// return { state, reset };
	// return [ state, reset ];

	// 也可以直接这样
	state.$reset = reset;
	return state;
}

// 可以重置的ref
export function useResettableRef(value) {
	const initial = deepClone(value);
	const state = ref(value);

	function reset() {
		state.value = deepClone(initial);
	}

	state.$reset = reset;
	return state;
}
vue
<template>
  <form action="">
    <input type="text" v-model="formData1.email" placeholder="email" />
    <input type="password" v-model="formData1.password" placeholder="password" />
  </form>
  <form action="">
    <input type="text" v-model="formData2.email" placeholder="email" />
    <input type="password" v-model="formData2.password" placeholder="password" />
  </form>
  <button @click="handleClick">reset</button>
</template>

<script setup>
import { useResettableRef, useResettableReactive } from "./hooks";

const formData1 = useResettableReactive({
  email: "",
  password: "",
});

const formData2 = useResettableRef({
  email: "",
  password: "",
});

function handleClick() {
  formData1.$reset();
  formData2.$reset();
}
</script>

Released under the MIT License.