--- title: Avoid Mutating Methods on Arrays in Computed Properties impact: HIGH impactDescription: Array mutating methods in computed modify source data causing unexpected behavior type: capability tags: [vue3, computed, arrays, mutation, sort, reverse] --- # Avoid Mutating Methods on Arrays in Computed Properties **Impact: HIGH** - JavaScript array methods like `reverse()`, `sort()`, `splice()`, `push()`, `pop()`, `shift()`, and `unshift()` mutate the original array. Using them directly on reactive arrays inside computed properties will modify your source data, causing unexpected side effects and bugs. ## Task Checklist - [ ] Always create a copy of arrays before using mutating methods - [ ] Use spread operator `[...array]` or `slice()` to copy arrays - [ ] Prefer non-mutating alternatives when available - [ ] Be aware which array methods mutate vs return new arrays **Incorrect:** ```vue ``` **Correct:** ```vue ``` ## 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 | ## ES2023 Non-Mutating Alternatives Modern JavaScript (ES2023) provides non-mutating versions of common array methods: ```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') ``` ## Deep Copy for Nested Arrays For arrays of objects where you might mutate nested properties: ```javascript const items = ref([{ name: 'A', values: [1, 2, 3] }]) // Shallow copy - nested arrays still shared const copied = computed(() => [...items.value]) // Deep copy if you need to mutate nested structures const deepCopied = computed(() => { 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)