Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component extends another component lost its extended methods after hot reload #68

Open
hjkcai opened this issue Jun 3, 2018 · 5 comments

Comments

@hjkcai
Copy link

hjkcai commented Jun 3, 2018

Description

Component A is defined in a .vue file, and component B is defined in a .js file that extends A. After changing the <script> section of A, B is reloaded but it lost what is extended (for the example below, test() will be gone).

import Vue from 'vue'
import component from './component'

export default Vue.extend({
  extends: component,
  methods: {
    test () {           // test will be lost!
      alert('test!')
    }
  }
})

What is expected

Component B is correctly reloaded.

Reproduction repo

https://github.com/hjkcai/vue-hot-reload-api-issue

Reproduction steps

Edit changeThis() method or any part of the <script> section in component.vue. The console will show the error after hot reload.

What I have found

I tried to step into vue-hot-reload-api to find out this question. It seems that component A and B share the same entry in the map object, which means they have the same data ID (data-v-xxxxxx). After hot reload, the constructor of B is recreated with the options of A. Maybe that is why component B is reloaded without its own methods?

@mikerockett
Copy link

Hi all – has anyone had a chance to look into this yet?

@scq
Copy link

scq commented May 21, 2019

It looks like this is happening because the hook inserted in makeOptionsHot() is not recording the right record.Ctor value for the parent component.

injectHook(options, initHookName, function() {
const record = map[id]
if (!record.Ctor) {
record.Ctor = this.constructor
}
record.instances.push(this)
})

If you have component B that extends from component A, this records the wrong record.Ctor value for component A as this.constructor will be pointing to component B's constructor.

I implemented a hacky fix for this by replacing that line with

record.Ctor = options._Ctor ? options._Ctor[0] : undefined;

However this doesn't fully fix the issue as after doing that the component is losing data inherited from the parent component. Possibly the same issue as #67 - I didn't have time to look into this further.

@silverprize
Copy link

@scq Thank you!!
I've fixed some problem in your code. record.Ctor is not Array that is Object.
Works fine below code. Thanks again.

        var ctor
        if (options._Ctor) {
          var key = Object.keys(options._Ctor)[0]
          if (key) {
            ctor = options._Ctor[key]
          }
        }
        if (!ctor) {
          ctor = this.constructor
        }
        record.Ctor = ctor

@mikerockett
Copy link

I tried the suggestion(s) above a little while ago, to no avail. Not sure how else to fix the issue with the limited knowledge I have in regards to how the cogs work internally.

Pinging @yyx990803 – I know your focus is currently on a bunch of other things, and I also know that not many others are bringing this issue up, but is there any chance you could take a look at it? Thanks!

@nemoDreamer
Copy link

Any movement on this? It's stopping us from using extends altogether, because it makes the Storybook dev workflow so broken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants