Skip to content

Instantly share code, notes, and snippets.

@bendytree
Created October 23, 2024 19:09
Show Gist options
  • Save bendytree/af0c88ec4ee55e90d4b91a37be2409ba to your computer and use it in GitHub Desktop.
Save bendytree/af0c88ec4ee55e90d4b91a37be2409ba to your computer and use it in GitHub Desktop.

Migrating from Vue2 to Vue3

Instructions

I'm migrating an old codebase from Vue 2.6 with @vue/composition-api to Vue 3.5.12. I will provide my typescript file below. Please respond with the updated code. DO NOT remove comments! Your response will be saved to replace the old typescript file (so DO NOT include comments or markdown formatting). If you don't make any changes, that's fine - but just repeat back the typescript as-is... don't add comments!

Concerns

The codebase is written in Vue 2 and Typescript 5. If you have concerns during your conversion then include a comment like this:

// TODO: (reason for concern)

reactive(...) objects

In Vue 2 reactive(...) mutates the original object. In Vue 3 reactive(...) returns a new object (so the original object must no longer be used).

If the target object for reactive comes from the same scope then call reactive on the initial declaration.

Important: If the target is from a different scope (such as a prop, function param, etc) then I need to review it SO ADD A // TODO: ... comment!

reactive(this)

This codebase often calls "reactive(this)" in a constructor like this:

class SomeManager {
  constructor (args) {
    this.args = args;
    
    // Doesn't work in Vue 3: The callback references "this" which is not reactive
    setTimeout(() => { this.args.foo = 'bar'; }, 1000);
    
    // Doesn't work in Vue 3: because the constructor does not return the result of reactive(this)
    reactive(this);
  }
  doSomething(){
    // This is ok
    this.args.foo = "buzz";
  }
}

So if we call reactive(this) in Vue 3, then we must make sure to use "self" in the constructor like:

class SomeManager {
  fizz = "fuzz";
  constructor (args) {
    const self = reactive(this);
    self.args = args;
    
    setTimeout(() => { self.args.foo = 'bar'; }, 1000);
    
    return self;
  }
  doSomething(){
    this.args.foo = "buzz";
  }
}

Directives

In Vue 3 the hooks have been renamed:

  • bind → beforeMount
  • inserted → mounted
  • update → updated
  • componentUpdated → updated
  • unbind → unmounted

Vue.set and Vue.delete

Vue.set and Vue.delete no longer exist in Vue 3 so just use the standard JavaScript assignment foo.bar = foobar and delete delete foo.bar.

Internal usage to .$children, .proxy, instance, etc

Vue 2 usages of an instance's $children, proxy, etc need a review from me, so just add a "CONCERN" comment.

Summary

It's very important that you only change Vue 2 code to Vue 3. Everything else should stay exactly the same including imports, exports, types, etc!

To be clear, just respond with the migrated typescript code. DO NOT ADD COMMENTS BEFORE OR AFTER!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment