-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: new hook package: @utopia-utils/vueuse
- Loading branch information
Showing
12 changed files
with
226 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
{ | ||
"cSpell.words": [ | ||
"deepmerge" | ||
"deepmerge", | ||
"typecheck" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,26 @@ | ||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { RouterLink, RouterView } from 'vue-router' | ||
import HelloWorld from './components/HelloWorld.vue' | ||
import { loadScript } from '@utopia-utils/core' | ||
import { useSmsCountdown } from '@utopia-utils/vueuse' | ||
let unload_ | ||
let able = ref(false) | ||
const foo = () => { | ||
console.log('[9]-App.vue', unload_) | ||
unload_() | ||
} | ||
const loadScript_ = () => { | ||
const { unload } = loadScript('https://unpkg.com/browse/[email protected]/index.js', { | ||
appendPosition: 'body', | ||
onStatusChange: (status) => { | ||
console.log(status) | ||
}, | ||
}) | ||
unload_ = unload | ||
} | ||
const { counts, startCountdown, text, canSend, stopCountdown } = useSmsCountdown({ | ||
sendAble: able, | ||
startText: 'send', | ||
durationText: 'x秒重取' | ||
}) | ||
</script> | ||
|
||
<template> | ||
<header> | ||
<button @click="loadScript_">load</button> | ||
<button @click="foo">unload</button> | ||
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" /> | ||
|
||
<button @click="able = !able">Toggle {{ able }}</button> | ||
<h1>{{ counts }}{{ canSend }}</h1> | ||
<button @click="stopCountdown">stop</button> | ||
<button @click="() => startCountdown()">{{ text }}</button> | ||
<div class="wrapper"> | ||
<HelloWorld msg="You did it!" /> | ||
|
||
<nav> | ||
<RouterLink to="/">Home</RouterLink> | ||
</nav> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
"name": "@utopia-utils/vueuse", | ||
"type": "module", | ||
"version": "0.3.23", | ||
"description": "Collection of common vue hooks", | ||
"author": "Utopia <https://github.com/GreatAuk>", | ||
"license": "MIT", | ||
"homepage": "https://github.com/GreatAuk/utopia-utils#readme", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/GreatAuk/utopia-utils.git", | ||
"directory": "packages/vueuse" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/GreatAuk/utopia-utils/issues" | ||
}, | ||
"keywords": [ | ||
"utils", | ||
"vue hooks", | ||
"vueuse" | ||
], | ||
"sideEffects": false, | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"require": "./dist/index.cjs", | ||
"import": "./dist/index.js" | ||
} | ||
}, | ||
"main": "./dist/index.cjs", | ||
"module": "./dist/index.js", | ||
"types": "./dist/index.d.ts", | ||
"scripts": { | ||
"build": "tsup", | ||
"dev": "tsup --watch", | ||
"lint": "eslint .", | ||
"start": "tsx src/index.ts", | ||
"test": "vitest", | ||
"typecheck": "tsc --noEmit" | ||
}, | ||
"peerDependencies": { | ||
"vue": "^3.2.47" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"vue": "^3.2.47" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './useSmsCountdown' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import type { Ref } from 'vue' | ||
|
||
/** | ||
* Maybe it's a ref, or a plain value | ||
* | ||
* ```ts | ||
* type MaybeRef<T> = T | Ref<T> | ||
* ``` | ||
*/ | ||
export type MaybeRef<T> = T | Ref<T> | ||
|
||
/** | ||
* Maybe it's a ref, or a plain value, or a getter function | ||
* | ||
* ```ts | ||
* type MaybeRefOrGetter<T> = (() => T) | T | Ref<T> | ComputedRef<T> | ||
* ``` | ||
*/ | ||
export type MaybeRefOrGetter<T> = MaybeRef<T> | (() => T) | ||
|
||
/** | ||
* Void function | ||
*/ | ||
export type Fn = () => void | ||
|
||
/** | ||
* Any function | ||
*/ | ||
export type AnyFn = (...args: any[]) => any |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { computed, ref } from 'vue' | ||
|
||
import type { MaybeRef } from '../types' | ||
import { toValue, tryOnScopeDispose } from '../utils' | ||
|
||
export interface UseSmsCountdownOptions { | ||
/** | ||
* 倒计时总共的时间(s) | ||
* @default 60s | ||
*/ | ||
totalSecond?: number | ||
/** 是否可发送 | ||
* @default true | ||
*/ | ||
sendAble?: MaybeRef<boolean> | ||
/** | ||
* 开始倒计时的文本 | ||
* @default '获取验证码' | ||
*/ | ||
startText?: string | ||
/** | ||
* 倒计时期间的提示语,必须带有字符 "%s",这里的 "%s",将会被倒计的秒数替代 | ||
* @default '%s秒后重发' | ||
*/ | ||
durationText?: string | ||
} | ||
|
||
export function useSmsCountdown(options?: UseSmsCountdownOptions) { | ||
const { totalSecond = 60, sendAble = true, startText = '获取验证码', durationText = 'x秒后重发' } = options || {} | ||
|
||
if (totalSecond <= 0 && totalSecond % 1 !== 0) | ||
throw new Error('倒计时的时间应该为一个正整数!') | ||
|
||
const counts = ref(totalSecond) | ||
|
||
/** 是否可以发送验证码,由外部转入的 sendAble 和当前的秒数共同确定 */ | ||
const canSend = computed(() => { | ||
return toValue(sendAble) && counts.value === totalSecond | ||
}) | ||
|
||
const text = computed(() => { | ||
if (counts.value === totalSecond) | ||
return startText | ||
|
||
return durationText.replace(/%s/i, counts.value.toString()) | ||
}) | ||
|
||
let intervalId: ReturnType<typeof setInterval> | null = null | ||
|
||
function startCountdown() { | ||
if (!canSend.value) | ||
return | ||
|
||
counts.value-- | ||
intervalId = setInterval(() => { | ||
counts.value-- | ||
if (counts.value <= 0) { | ||
counts.value = totalSecond | ||
clearInterval(intervalId!) | ||
} | ||
}, 1000) | ||
} | ||
|
||
/** | ||
* 停止计时 | ||
*/ | ||
function stopCountdown() { | ||
intervalId && clearInterval(intervalId) | ||
intervalId = null | ||
counts.value = totalSecond | ||
} | ||
tryOnScopeDispose(stopCountdown) | ||
|
||
return { | ||
counts, | ||
canSend, | ||
text, | ||
startCountdown, | ||
stopCountdown, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './tryOnScopeDispose' | ||
export * from './toValue' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { unref } from 'vue' | ||
import type { AnyFn, MaybeRefOrGetter } from '../../types' | ||
|
||
/** | ||
* Get the value of value/ref/getter. | ||
*/ | ||
export function toValue<T>(r: MaybeRefOrGetter<T>): T { | ||
return typeof r === 'function' | ||
? (r as AnyFn)() | ||
: unref(r) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { getCurrentScope, onScopeDispose } from 'vue' | ||
import type { Fn } from '../../types' | ||
|
||
/** | ||
* Call onScopeDispose() if it's inside an effect scope lifecycle, if not, do nothing | ||
* | ||
* @param fn | ||
*/ | ||
export function tryOnScopeDispose(fn: Fn) { | ||
if (getCurrentScope()) { | ||
onScopeDispose(fn) | ||
return true | ||
} | ||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { defineConfig } from 'tsup' | ||
|
||
export default defineConfig((options) => { // The options here is derived from CLI flags. | ||
return { | ||
entry: { | ||
index: 'src/index.ts', | ||
}, | ||
sourcemap: true, | ||
clean: true, | ||
dts: true, | ||
format: ['cjs', 'esm'], | ||
minify: !options.watch, | ||
} | ||
}) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.