Skip to content

Commit a681c77

Browse files
authored
feat: add use-set-state (#33)
1 parent 563eb8d commit a681c77

File tree

5 files changed

+103
-0
lines changed

5 files changed

+103
-0
lines changed

packages/hooks/docs/.vitepress/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ function getHooksSidebar() {
183183
{ text: 'useSessionStorageState', link: '/useSessionStorageState/' },
184184
{ text: 'useMap', link: '/useMap/' },
185185
{ text: 'useSet', link: '/useSet/' },
186+
{ text: 'useSetState', link: '/useSetState/' },
186187
],
187188
},
188189

packages/hooks/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import useMedia from './useMedia'
2929
import useNetwork from './useNetwork'
3030
import useSessionStorageState from './useSessionStorageState'
3131
import useSet from './useSet'
32+
import useSetState from './useSetState'
3233
import useSize from './useSize'
3334
import useScroll from './useScroll'
3435
import useToggle from './useToggle'
@@ -76,6 +77,7 @@ export {
7677
usePreview,
7778
useSessionStorageState,
7879
useSet,
80+
useSetState,
7981
useSize,
8082
useScroll,
8183
useToggle,
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<template>
2+
<div>{{ JSON.stringify(state) }}</div>
3+
<div class="contain">
4+
<vhp-button @click="initAge()">
5+
add age
6+
</vhp-button>
7+
8+
<vhp-button @click="updateAge()">
9+
update age
10+
</vhp-button>
11+
12+
<vhp-button @click="addTag()">
13+
add tag
14+
</vhp-button>
15+
</div>
16+
</template>
17+
18+
<script lang="ts" setup>
19+
import { useSetState } from 'vue-hooks-plus'
20+
21+
const [state, setState] = useSetState({ name: 'vue-hooks-plus' })
22+
23+
const initAge = () => {
24+
setState({
25+
age: 1,
26+
})
27+
}
28+
29+
const addTag = () => {
30+
setState({
31+
...state.value,
32+
age: 3,
33+
tag: 'nice',
34+
})
35+
}
36+
37+
const updateAge = () => {
38+
setState({
39+
age: 2,
40+
})
41+
}
42+
</script>
43+
44+
<style scoped lang="less">
45+
.contain {
46+
button {
47+
margin-right: 8px;
48+
}
49+
}
50+
</style>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
map:
3+
# 映射到docs的路径
4+
path: /useSetState
5+
---
6+
7+
# useSetState
8+
9+
管理 object 类型 响应式 的 Hooks,支持解构赋值,更方便维护。
10+
11+
## 代码演示
12+
13+
### 基础用法
14+
15+
<demo src="./demo/demo.vue"
16+
language="vue"
17+
title="基本用法"
18+
desc=""> </demo>
19+
20+
## API
21+
22+
```typescript
23+
const [state, setState] = useSetState<S extends Record<string, any>>
24+
(initialState: StateType<S>)
25+
:[
26+
[S] extends [Ref<any>] ? S : Ref<UnwrapRef<S>>,
27+
(patch: Record<string, any>) => void
28+
]
29+
```
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ref, Ref, unref, UnwrapRef } from 'vue'
2+
import { merge } from 'lodash'
3+
4+
type StateType<S> = S | (() => S) | Ref<S> | (() => Ref<S>)
5+
6+
function useSetState<S extends Record<string, any>>(
7+
initialState: StateType<S>,
8+
): [[S] extends [Ref<any>] ? S : Ref<UnwrapRef<S>>, (patch: Record<string, any>) => void] {
9+
const getInitialState = () => unref(initialState)
10+
11+
const state = ref<S>(getInitialState() as S)
12+
13+
const setMergeState = (patch: Record<string, any>) => {
14+
const newState = unref(patch)
15+
state.value = newState ? merge(state.value, newState) : state.value
16+
}
17+
18+
return [state, setMergeState]
19+
}
20+
21+
export default useSetState

0 commit comments

Comments
 (0)