format: apply repo prettier (3.8.1) to the folded skills tree
963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
This commit is contained in:
+45
-42
@@ -18,25 +18,26 @@ tags: [vue3, computed, arrays, mutation, sort, reverse]
|
||||
- [ ] Be aware which array methods mutate vs return new arrays
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, computed } from 'vue';
|
||||
|
||||
const items = ref([3, 1, 4, 1, 5, 9, 2, 6])
|
||||
const items = ref([3, 1, 4, 1, 5, 9, 2, 6]);
|
||||
const users = ref([
|
||||
{ name: 'Alice', age: 30 },
|
||||
{ name: 'Bob', age: 25 }
|
||||
])
|
||||
{ name: 'Bob', age: 25 },
|
||||
]);
|
||||
|
||||
// BAD: sort() mutates the original array!
|
||||
const sortedItems = computed(() => {
|
||||
return items.value.sort((a, b) => a - b)
|
||||
})
|
||||
return items.value.sort((a, b) => a - b);
|
||||
});
|
||||
|
||||
// BAD: reverse() mutates the original array!
|
||||
const reversedItems = computed(() => {
|
||||
return items.value.reverse()
|
||||
})
|
||||
return items.value.reverse();
|
||||
});
|
||||
|
||||
// BAD: Both arrays now point to the same mutated data
|
||||
// items.value and sortedItems.value are the SAME array
|
||||
@@ -44,8 +45,8 @@ const reversedItems = computed(() => {
|
||||
|
||||
// BAD: Chained mutations
|
||||
const sortedUsers = computed(() => {
|
||||
return users.value.sort((a, b) => a.age - b.age)
|
||||
})
|
||||
return users.value.sort((a, b) => a.age - b.age);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -56,40 +57,41 @@ const sortedUsers = computed(() => {
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, computed } from 'vue';
|
||||
|
||||
const items = ref([3, 1, 4, 1, 5, 9, 2, 6])
|
||||
const items = ref([3, 1, 4, 1, 5, 9, 2, 6]);
|
||||
const users = ref([
|
||||
{ name: 'Alice', age: 30 },
|
||||
{ name: 'Bob', age: 25 }
|
||||
])
|
||||
{ name: 'Bob', age: 25 },
|
||||
]);
|
||||
|
||||
// GOOD: Spread operator creates a copy first
|
||||
const sortedItems = computed(() => {
|
||||
return [...items.value].sort((a, b) => a - b)
|
||||
})
|
||||
return [...items.value].sort((a, b) => a - b);
|
||||
});
|
||||
|
||||
// GOOD: slice() also creates a copy
|
||||
const reversedItems = computed(() => {
|
||||
return items.value.slice().reverse()
|
||||
})
|
||||
return items.value.slice().reverse();
|
||||
});
|
||||
|
||||
// GOOD: Copy before sorting objects
|
||||
const sortedUsers = computed(() => {
|
||||
return [...users.value].sort((a, b) => a.age - b.age)
|
||||
})
|
||||
return [...users.value].sort((a, b) => a.age - b.age);
|
||||
});
|
||||
|
||||
// GOOD: Use toSorted() (ES2023) - non-mutating
|
||||
const sortedItemsModern = computed(() => {
|
||||
return items.value.toSorted((a, b) => a - b)
|
||||
})
|
||||
return items.value.toSorted((a, b) => a - b);
|
||||
});
|
||||
|
||||
// GOOD: Use toReversed() (ES2023) - non-mutating
|
||||
const reversedItemsModern = computed(() => {
|
||||
return items.value.toReversed()
|
||||
})
|
||||
return items.value.toReversed();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -102,16 +104,16 @@ const reversedItemsModern = computed(() => {
|
||||
|
||||
## Mutating vs Non-Mutating Array Methods
|
||||
|
||||
| Mutating (Avoid in Computed) | Non-Mutating (Safe) |
|
||||
|------------------------------|---------------------|
|
||||
| `sort()` | `toSorted()` (ES2023) |
|
||||
| `reverse()` | `toReversed()` (ES2023) |
|
||||
| `splice()` | `toSpliced()` (ES2023) |
|
||||
| `push()` | `concat()` |
|
||||
| `pop()` | `slice(0, -1)` |
|
||||
| `shift()` | `slice(1)` |
|
||||
| `unshift()` | `[item, ...array]` |
|
||||
| `fill()` | `map()` with new values |
|
||||
| Mutating (Avoid in Computed) | Non-Mutating (Safe) |
|
||||
| ---------------------------- | ----------------------- |
|
||||
| `sort()` | `toSorted()` (ES2023) |
|
||||
| `reverse()` | `toReversed()` (ES2023) |
|
||||
| `splice()` | `toSpliced()` (ES2023) |
|
||||
| `push()` | `concat()` |
|
||||
| `pop()` | `slice(0, -1)` |
|
||||
| `shift()` | `slice(1)` |
|
||||
| `unshift()` | `[item, ...array]` |
|
||||
| `fill()` | `map()` with new values |
|
||||
|
||||
## ES2023 Non-Mutating Alternatives
|
||||
|
||||
@@ -119,10 +121,10 @@ Modern JavaScript (ES2023) provides non-mutating versions of common array method
|
||||
|
||||
```javascript
|
||||
// These return NEW arrays, safe for computed properties
|
||||
const sorted = array.toSorted((a, b) => a - b)
|
||||
const reversed = array.toReversed()
|
||||
const spliced = array.toSpliced(1, 2, 'new')
|
||||
const withReplaced = array.with(0, 'newFirst')
|
||||
const sorted = array.toSorted((a, b) => a - b);
|
||||
const reversed = array.toReversed();
|
||||
const spliced = array.toSpliced(1, 2, 'new');
|
||||
const withReplaced = array.with(0, 'newFirst');
|
||||
```
|
||||
|
||||
## Deep Copy for Nested Arrays
|
||||
@@ -130,19 +132,20 @@ const withReplaced = array.with(0, 'newFirst')
|
||||
For arrays of objects where you might mutate nested properties:
|
||||
|
||||
```javascript
|
||||
const items = ref([{ name: 'A', values: [1, 2, 3] }])
|
||||
const items = ref([{ name: 'A', values: [1, 2, 3] }]);
|
||||
|
||||
// Shallow copy - nested arrays still shared
|
||||
const copied = computed(() => [...items.value])
|
||||
const copied = computed(() => [...items.value]);
|
||||
|
||||
// Deep copy if you need to mutate nested structures
|
||||
const deepCopied = computed(() => {
|
||||
return JSON.parse(JSON.stringify(items.value))
|
||||
return JSON.parse(JSON.stringify(items.value));
|
||||
// Or use structuredClone():
|
||||
// return structuredClone(items.value)
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
- [Vue.js Computed Properties - Avoid Mutating Computed Value](https://vuejs.org/guide/essentials/computed.html#avoid-mutating-computed-value)
|
||||
- [MDN Array Methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
|
||||
|
||||
Reference in New Issue
Block a user