feat(lite): new useArrayRemovedItemsHistory composable (#6546)

This commit is contained in:
Thierry Goettelmann
2022-12-16 11:43:50 +01:00
committed by GitHub
parent 3921401e96
commit 113235aec3
2 changed files with 71 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
# useArrayRemovedItemsHistory composable
This composable allows you to keep a history of each removed item of an array.
## Usage
```typescript
const myArray = ref([]);
const history = useArrayRemovedItemsHistory(myArray)
myArray.push('A'); // myArray = ['A']; history = []
myArray.push('B'); // myArray = ['A', 'B']; history = []
myArray.shift(); // myArray = ['B']; history = ['A']
```
You can limit the number of items to keep in history:
```typescript
const myArray = ref([]);
const history = useArrayRemovedItemsHistory(myArray, 30);
```
Be careful when using an array of objects which is likely to be replaced (instead of being altered):
```typescript
const myArray = ref([]);
const history = useArrayRemovedItemsHistory(myArray);
myArray.value = [{ id: 'foo' }, { id: 'bar' }];
myArray.value = [{ id: 'bar' }, { id: 'baz' }]; // history = [{ id: 'foo' }, { id: 'bar' }]
```
In this case, `{ id: 'bar' }` is detected as removed since in JavaScript `{ id: 'bar' } !== { id: 'bar' }`.
You must therefore use an identity function as third parameter to return the value to be used to detect deletion:
```typescript
const myArray = ref<{ id: string }[]>([]);
const history = useArrayRemovedItemsHistory(myArray, undefined, (item) => item.id);
myArray.value = [{ id: 'foo' }, { id: 'bar' }];
myArray.value = [{ id: 'bar' }, { id: 'baz' }]; // history = [{ id: 'foo' }]
```

View File

@@ -0,0 +1,30 @@
import { differenceBy } from "lodash-es";
import { type Ref, ref, unref, watch } from "vue";
export default function useArrayRemovedItemsHistory<T>(
list: Ref<T[]>,
limit = Infinity,
iteratee: (item: T) => unknown = (item) => item
) {
const currentList: Ref<T[]> = ref([]);
const history: Ref<T[]> = ref([]);
watch(
list,
(updatedList) => {
currentList.value = [...updatedList];
},
{ deep: true }
);
watch(currentList, (nextList, previousList) => {
const removedItems = differenceBy(previousList, nextList, iteratee);
history.value.push(...removedItems);
const currentLimit = unref(limit);
if (history.value.length > currentLimit) {
history.value.slice(-currentLimit);
}
});
return history;
}