---
name: lifecycle-reactivity-migration
description: Use when migrating Vue 2 lifecycle hooks and reactivity APIs to Vue 3 equivalents, especially beforeDestroy/destroyed and $set/$delete patterns.
enabled: false
source: github:JuanJoseGonGi/skills
imported-from: github:JuanJoseGonGi/skills
---

# Lifecycle and Reactivity Migration

## Overview

Use this skill for behavior-safe migration of lifecycle hooks and reactivity edge cases.

## Key API Changes

- `beforeDestroy` -> `beforeUnmount`
- `destroyed` -> `unmounted`
- `Vue.set` / `this.$set` removed
- `Vue.delete` / `this.$delete` removed
- instance events (`$on`, `$off`, `$once`) removed

## Workflow

1. Rename lifecycle hooks
   - Keep hook bodies unchanged first.
   - Add tests around cleanup-sensitive logic (timers, listeners, sockets).

2. Replace `$set/$delete`
   - Use direct property assignment and object rest/spread updates.
   - For dynamic structures, ensure the base object/array is reactive.

3. Replace event bus instance APIs
   - Move to explicit emitter libs, Pinia actions, or composables.

4. Verify teardown semantics
   - Check abort controllers, subscriptions, and DOM listeners in unmount paths.

## Safe Rewrite Patterns

```ts
// before
this.$set(this.form, "status", "ready")
this.$delete(this.errors, field)

// after
this.form.status = "ready"
const { [field]: _removed, ...next } = this.errors
this.errors = next
```

## Done Criteria

- No `beforeDestroy`/`destroyed` hooks remain.
- No `$set`/`$delete` usage remains.
- Unmount cleanup behavior matches pre-migration behavior.

## Common Pitfalls

- Changing lifecycle names without validating async cleanup behavior.
- Mutating non-reactive objects after removing `$set`.
- Replacing event bus APIs without preserving delivery order assumptions.
