vue-hot-reload-api
vue-hot-reload-api copied to clipboard
TypeError: Cannot read property 'extend' of undefined
This happens every time to me when component is reloaded:
TypeError: Cannot read property 'extend' of undefined
at VM93425 main.js:28952
at Object.reload (VM93425 main.js:28860)
at VM93425 main.js:43826
at Object../src/agilecards/components/edit-settings/TemplateScopeSelector.vue (VM93425 main.js:43831)
at __webpack_require__ (VM93425 main.js:679)
at hotApply (VM93425 main.js:608)
at VM93425 main.js:290
at <anonymous>
Stack trace is not very helpful, but I tracked this exception to line 196:
const newCtor = record.Ctor.super.extend(options)
Looks like super
does not exist in Ctor
(and Ctor
is the Vue constructor function). I'm using Vue 2.5.2.
Please provide a reproduction.
@marszall87 I solved this problem with changing vue's bootstrap, and there seems no problem. my repo
@DanielChan27 thanks! I'll try that, we're bootstraping Vue the same way.
I also have same problem as @marszall87. The solution from @DanielChan27 worked for me
I also have same problem
import App from './app.vue'
import Vue from 'vue'
const app = new Vue(App).$mount('#root')
This way will break
I'm also seeing this issue, and we mount our application pretty much the same way as in @vv314's example above, with the exception that we use the el property in our app component definition.
I also had this issue and it seems like we need to explicitly create the root app instead of creating it directly from our root component.
So instead of this:
import App from './app.vue'
import Vue from 'vue'
const app = new Vue(App).$mount('#root')
I'm using this:
import App from './app.vue'
import Vue from 'vue'
const root= new Vue({
render: createElement => createElement(App)
}).$mount('#root')
Unfortunatelly the proper way of creating the root instance is very unclear in the official documentation.
@ggaborx Passing an el property in the vue opts is an official way of mounting a Vue component if the documentation is to be believed => https://vuejs.org/v2/api/#el
@yyx990803 This definitely seems like a valid bug.
@RobertWHurst you can use the el prop instead of $mount but you will still get an error if you would like to do it with SFC. The documentation is unclear about how to directly mount a component instead of a new Vue instance. After a couple of try and fail I suspect its impossible. BTW, I'm using $mount because I need further configuration before mount but after I have the root component. The example above is simplified.
@ggaborx Sorry, I'm not clear on what you mean by SFC. I'm also not sure what you mean in regards to mounting a component vs a Vue instance. By component, do you mean the Vue constructor options object returned by the vue loader?
Calling $mount, or passing the el property are functionally identical (with the exception that calling $mount yourself means you can do stuff beforehand as in your case). Passing an el property as part of your vue options causes vue to automatically call $mount internally. This can be seen in vue/init => https://github.com/vuejs/vue/blob/dev/src/core/instance/init.js#L68
Based on my reading of the source code this is an entirely valid use case, and thus it's clear to me this is a bug.
@RobertWHurst SFC stands for Single File Component. There is no clear explanation in the documentation how to mount an SFC as the root component. You can set it as the parameter for the Vue constructor: new Vue(myApp). But you cannot define the 'el' prop in this way. So we need to manually call $mount. Basically I don't really need different root component than myApp but I have to create one as the documentation says. Moreover I created a general mount function which allows to configure the root instance after it was created with SFC - so this is the second reason why I call $mount instead of using 'el':
function mount(cmp, configure) {
...
const root = new Vue({
render: createElement => createElement(cmp)
})
if (configure) {
configure(root);
}
root.$mount('#root');
}
BTW I agree. It seems like a bug.
@ggaborx The value returned from the vue-template-compiler when requiring the vue file (SFC) is just a plain object. It has the same properties as the object you export in your script tag with the addition of a render method created from your template tag. You are meant to pass to it to the vue constructor. It is not a vue component until you do so. By calling new Vue
and passing it the object returned from importing/requiring you are creating your root component, not wrapping it. Until you do this it is just a plain object intended to tell Vue how to build your component; it is the options for the vue constructor.
As an aside you can set an el property in your vue file. If you set the value of el to a css selector, $mount will find the first element matching that selector and mount it there. It can also be a dom node if you query for one yourself.
As an additional aside, when you call new Vue({...}) passing just a render function that uses createElement to create your component, you are actually creating two vue components, I wouldn't recommend doing that as it isn't nessisary.
I was getting this error as well in my TypeScript Vue application created with the Vue CLI:
main.ts:
const app = new Vue({
render: (h) => h(App),
}).$mount('#app');
Adding the Component
argument in the import:
import { Vue, Component } from 'vue-property-decorator';
And then putting the @Component
before my class decoration:
@Component
export default class SomeClass extends Vue {
...
}
I had to restart the server serve -s dist
. Fixed the issue for me.