Skip to content

Commit dc4fb4b

Browse files
committed
feat: usePrevious
1 parent d4a74f7 commit dc4fb4b

File tree

7 files changed

+177
-0
lines changed

7 files changed

+177
-0
lines changed

packages/hooks/docs/.vitepress/router.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const Router = [
1313
{ text: 'useSessionStorageState', link: '/useSessionStorageState/' },
1414
{ text: 'useMap', link: '/useMap/' },
1515
{ text: 'useSet', link: '/useSet/' },
16+
{ text: 'usePrevious', link: '/usePrevious/' },
1617
{ text: 'useSetState', link: '/useSetState/' },
1718
],
1819
},

packages/hooks/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import useFetchs from './useFetchs'
1818
import useFullscreen from './useFullscreen'
1919
import useHover from './useHover'
2020
import usePreview from './usePreview'
21+
import usePrevious from './usePrevious'
2122
import useInterval from './useInterval'
2223
import useInfiniteScroll from './useInfiniteScroll'
2324
import useInViewport from './useInViewport'
@@ -78,6 +79,7 @@ export {
7879
useMouse,
7980
useNetwork,
8081
usePreview,
82+
usePrevious,
8183
useSessionStorageState,
8284
useSet,
8385
useSetState,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<template>
2+
<div>
3+
<p>counter current value:{{ counter }}</p>
4+
<p>counter previous value:{{ prevCounter }}</p>
5+
<vhp-button @click="inc()">increase</vhp-button>
6+
<vhp-button @click="dec()" style="margin-left: 8px;">decrease</vhp-button>
7+
</div>
8+
</template>
9+
10+
<script lang="ts" setup>
11+
import { usePrevious, useCounter } from 'vue-hooks-plus'
12+
const [counter, { inc, dec }] = useCounter(0)
13+
const prevCounter = usePrevious(counter)
14+
</script>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<template>
2+
<div style="border: 1px solid rgba(100, 126, 255, 0.7);border-radius: 12px; padding: 6px;">
3+
<p>current name: {{ currentName }}</p>
4+
<p>current age: {{ currentAge }}</p>
5+
</div>
6+
<br>
7+
<div style="border: 1px solid rgba(59, 206, 128, 0.7);border-radius: 12px; padding: 6px;">
8+
<p>previous name: {{ previousName }}</p>
9+
<p>previous age: {{ previousage }}</p>
10+
</div>
11+
<br>
12+
<div>
13+
<input v-model="currentNameInput" placeholder="Input Name">
14+
<vhp-button @click="handleUpdateName" style="margin-left: 8px;">Update</vhp-button>
15+
</div>
16+
17+
<br>
18+
<div>
19+
<input v-model="currentAgeInput" placeholder="Input Age">
20+
<vhp-button @click="handleUpdateAge" style="margin-left: 8px;">Update</vhp-button>
21+
</div>
22+
</template>
23+
24+
<script lang="ts" setup>
25+
import { ref } from 'vue'
26+
import { usePrevious } from 'vue-hooks-plus'
27+
28+
const currentNameInput = ref('')
29+
const currentName = ref('')
30+
const currentAgeInput = ref()
31+
const currentAge = ref()
32+
33+
const nameCompareFunction = (prev: string | undefined, next: string) => {
34+
if (!prev) {
35+
return true
36+
}
37+
if (prev !== next) {
38+
return true
39+
}
40+
return false
41+
}
42+
43+
const ageCompareFunction = (prev: number | undefined, next: number) => {
44+
if (!prev) {
45+
return true
46+
}
47+
if (prev !== next) {
48+
return true
49+
}
50+
return false
51+
}
52+
53+
const previousName = usePrevious(currentName, nameCompareFunction)
54+
const previousage = usePrevious(currentAge, ageCompareFunction)
55+
56+
const handleUpdateName = () => {
57+
currentName.value = currentNameInput.value
58+
}
59+
60+
const handleUpdateAge = () => {
61+
currentAge.value = currentAgeInput.value
62+
}
63+
</script>
64+
65+
<style scoped lang="less"></style>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
map:
3+
# 映射到docs的路径
4+
path: /usePrevious
5+
---
6+
7+
# usePrevious
8+
9+
A Hook to return the previous state.
10+
11+
## Basic usage
12+
13+
<demo src="./demo/demo.vue"
14+
language="vue"
15+
title="Basic usage"
16+
desc="Record the previous value."> </demo>
17+
18+
## Custom shouldUpdate function
19+
20+
<demo src="./demo/demo1.vue"
21+
language="vue"
22+
title="Custom shouldUpdate function"
23+
desc="Previous value update only when the shouldUpdate function return true."> </demo>
24+
25+
## Result
26+
27+
| Property | Description | Type |
28+
| ----------- | ------------------ | -------- |
29+
| previousRef | The previous value | `Ref<T>` |
30+
31+
## Params
32+
33+
| Property | Description | Type | Default Value |
34+
| --- | --- | --- | --- |
35+
| currentRef | The state that needs to be tracked | `Ref<T>` \| `ComputedRef<T>` | - |
36+
| shouldUpdate | Optional. Customize whether the state value should be updated | `(prev: T \| undefined, next: T) => boolean` | `(a, b) => a !== b` |
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ComputedRef, Ref, ref, watchEffect } from 'vue'
2+
3+
export type ShouldUpdateFunc<T> = (prev: T | undefined, next: T) => boolean
4+
const defaultShouldUpdate = <T>(a?: T, b?: T) => !Object.is(a, b)
5+
6+
function usePrevious<T>(
7+
state: Ref<T> | ComputedRef<T>,
8+
shouldUpdate: ShouldUpdateFunc<T> = defaultShouldUpdate,
9+
) {
10+
const prevRef = ref<T>()
11+
const curRef = ref<T>()
12+
13+
watchEffect(() => {
14+
if (shouldUpdate(curRef.value, state.value)) {
15+
prevRef.value = curRef.value
16+
curRef.value = state.value
17+
}
18+
})
19+
20+
return prevRef
21+
}
22+
23+
export default usePrevious
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
map:
3+
# 映射到docs的路径
4+
path: /usePrevious
5+
---
6+
7+
# usePrevious
8+
9+
保存上一次状态的 Hook。
10+
11+
## 基础用法
12+
13+
<demo src="./demo/demo.vue"
14+
language="vue"
15+
title="基本用法"
16+
desc="记录上次的 count 值"> </demo>
17+
18+
## 自定义 shouldUpdate 函数
19+
20+
<demo src="./demo/demo1.vue"
21+
language="vue"
22+
title="自定义 shouldUpdate 函数"
23+
desc="只有 shouldUpdate function 返回 true 时,才会记录值的变化。"> </demo>
24+
25+
## Result
26+
27+
| 参数 | 说明 | 类型 |
28+
| ----------- | --------------- | -------- |
29+
| previousRef | 上次 state 的值 | `Ref<T>` |
30+
31+
## Params
32+
33+
| 参数 | 说明 | 类型 | 默认值 |
34+
| --- | --- | --- | --- |
35+
| currentRef | 需要记录变化的值 | `Ref<T>` \| `ComputedRef<T>` | - |
36+
| shouldUpdate | 可选,自定义判断值是否变化 | `(prev: T \| undefined, next: T) => boolean` | `(a, b) => a !== b` |

0 commit comments

Comments
 (0)