Reputation: 456
I'm migrating from Vue 2 to Vue 3. In Vue 2, it's possible to register a component globally like this: main.js
new Vue({
el: '#app'
})
A global registration of a component: my-component.js
Vue.component('my-component', {
template: '<div>Hi!</div>'
})
I'm using Webpack for import Single File Components in other components, and then i'm bundling it in one file. With Vue 2, that was easy because Vue instance was globally registered. Now with Vue 3, that doesn't work any more because of Vue.createApp({}).mount('#app')
. I was trying to do something like this: main.js
const app = createApp({});
export const app;
And in: my-component.js
import { app } from './main.js';
app.component('my-component', {
template: '<div>Hi!</div>'
})
And at the end: close-app.js
import { app } from './main.js';
app.mount('#app');
And in: index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.5/vue.global.js"></script>
<script type="application/javascript" src="my-component.js"></script>
<div id="app">
<my-component></my-component>
</div>
<script type="application/javascript" src="close-app.js"></script>
I'm importing the app
because of Webpack. Webpack is bundling it in self-invoking functions, but that doesn't work. I know there is a way to declare it globally like this: window.app = app;
, but that's not a good idea. Can someone help me with that?
Upvotes: 2
Views: 6295
Reputation: 138196
Since Vue 3 component registration has to be invoked on an app instance, and you're importing each component Webpack individually, I don't think you can avoid globals. Using a global app
instance (window.app
) in your components might be the easiest solution, especially if you want to minimize the changes.
Alternatively, you could build the components as UMD modules, where the component definition is exported as a global, import the UMD module with the <script>
tag (as you're already doing), and call app.component()
for each of them:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.5/vue.global.js"></script>
<!-- sets MyComponent global -->
<script type="application/javascript" src="./my-component.umd.js"></script>
<div id="app">
<my-component></my-component>
</div>
<script>
const app = Vue.createApp({})
app.component(MyComponent.name, MyComponent)
app.mount('#app')
</script>
In main.js
, use createApp
from the global Vue
that you've imported in the <script>
tag:
export const app = Vue.createApp({})
Then import your scripts as modules with <script type="module">
:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.5/vue.global.js"></script>
<script type="module" src="./my-component.js"></script>
<div id="app">
<my-component></my-component>
</div>
<script type="module" src="./close-app.js"></script>
Upvotes: 4