Skip to content

Commit

Permalink
feat(reactivePick): new function (#424)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 8, 2021
1 parent 715d5b5 commit db65464
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -7,7 +7,7 @@ Collection of essential Vue Composition Utilities
<a href="https://www.npmjs.com/package/@vueuse/core" target="__blank"><img src="https://img.shields.io/npm/v/@vueuse/core?color=a1b858&label=" alt="NPM version"></a>
<a href="https://www.npmjs.com/package/@vueuse/core" target="__blank"><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/@vueuse/core?color=50a36f&label="></a>
<a href="https://vueuse.org" target="__blank"><img src="https://img.shields.io/static/v1?label=&message=docs%20%26%20demos&color=1e8a7a" alt="Docs & Demos"></a>
<img alt="Function Count" src="https://img.shields.io/badge/-112%20functions-13708a">
<img alt="Function Count" src="https://img.shields.io/badge/-113%20functions-13708a">
<br>
<a href="https://github.com/vueuse/vueuse" target="__blank"><img alt="GitHub stars" src="https://img.shields.io/github/stars/vueuse/vueuse?style=social"></a>
</p>
Expand Down
7 changes: 7 additions & 0 deletions indexes.json
Expand Up @@ -174,6 +174,13 @@
"category": "Utilities",
"description": "apply `reactify` to an object"
},
{
"name": "reactivePick",
"package": "shared",
"docs": "https://vueuse.org/shared/reactivePick/",
"category": "Utilities",
"description": "reactively pick fields from a reactive object"
},
{
"name": "set",
"package": "shared",
Expand Down
1 change: 1 addition & 0 deletions packages/functions.md
Expand Up @@ -101,6 +101,7 @@
- [`makeDestructurable`](https://vueuse.org/shared/makeDestructurable/) — make isomorphic destructurable for object and array at the same time
- [`reactify`](https://vueuse.org/shared/reactify/) — converts plain functions into reactive functions
- [`reactifyObject`](https://vueuse.org/shared/reactifyObject/) — apply `reactify` to an object
- [`reactivePick`](https://vueuse.org/shared/reactivePick/) — reactively pick fields from a reactive object
- [`set`](https://vueuse.org/shared/set/) — shorthand for `ref.value = x`
- [`syncRef`](https://vueuse.org/shared/syncRef/) — keep target refs in sync with a source ref
- [`useAsyncState`](https://vueuse.org/core/useAsyncState/) — reactive async state
Expand Down
1 change: 1 addition & 0 deletions packages/shared/index.ts
Expand Up @@ -9,6 +9,7 @@ export * from './makeDestructurable'
export * from './pausableWatch'
export * from './reactify'
export * from './reactifyObject'
export * from './reactivePick'
export * from './set'
export * from './syncRef'
export * from './throttledWatch'
Expand Down
98 changes: 98 additions & 0 deletions packages/shared/reactivePick/index.md
@@ -0,0 +1,98 @@
---
category: Utilities
---

# reactivePick

Reactively pick fields from a reactive object.

## Usage

```js
import { reactivePick } from '@vueuse/core'

const obj = reactive({
x: 0,
y: 0,
elementX: 0,
elementY: 0,
})

const picked = reactivePick(obj, 'x', 'elementX') // { x: number, elementX: number }
```

### Scenarios

#### Selectively passing props to child

```html
<script setup>
import { defineProps } from 'vue'
import { reactivePick } from '@vueuse/core'
const props = defineProps({
value: {
default: 'value',
},
color: {
type: String,
},
font: {
type: String,
}
})
const childProps = reactivePick(props, 'color', 'font')
</script>

<template>
<div>
<!-- only passes "color" and "font" props to child -->
<ChildComp v-bind="childProps" />
</div>
</template>
```

#### Selectively wrap reactive object

Instead of doing this

```ts
import { reactive } from 'vue'
import { useElementBounding } from '@vueuse/core'

const { height, width } = useElementBounding() // object of refs
const size = reactive({ height, width })
```

Now we can just have this

```ts
import { reactivePick, useElementBounding } from '@vueuse/core'

const size = reactivePick(useElementBounding(), 'height', 'width')
```

<!--FOOTER_STARTS-->
## Type Declarations

```typescript
/**
* Reactively pick fields from a reactive object
*
* @link https://vueuse.js.org/reactivePick
*/
export declare function reactivePick<T extends object, K extends keyof T>(
obj: T,
...keys: K[]
): {
[S in K]: UnwrapRef<T[S]>
}
```

## Source

[Source](https://github.com/vueuse/vueuse/blob/main/packages/shared/reactivePick/index.ts)[Docs](https://github.com/vueuse/vueuse/blob/main/packages/shared/reactivePick/index.md)


<!--FOOTER_ENDS-->
13 changes: 13 additions & 0 deletions packages/shared/reactivePick/index.ts
@@ -0,0 +1,13 @@
import { reactive, toRef, UnwrapRef } from 'vue-demi'

/**
* Reactively pick fields from a reactive object
*
* @link https://vueuse.js.org/reactivePick
*/
export function reactivePick<T extends object, K extends keyof T>(
obj: T,
...keys: K[]
): { [S in K]: UnwrapRef<T[S]> } {
return reactive(Object.fromEntries(keys.map(k => [k, toRef(obj, k)]))) as any
}

0 comments on commit db65464

Please sign in to comment.