WillC
WillC

Reputation: 2115

Vue3 Components in a Separate File

I have an app that I am porting from Vue2 to Vue3. I am not using a bundler as Vue is just providing simple interactivity on a page. This is the simplified version in Vue2:

// my-modal.js
var myModal = Vue.component('my-modal',
{
    template:
        `<div id="myModal">
        <button @click.prevent="open=true">Open Modal</button>

        <div v-if="open" class="my-modal">
            <p>Hello from the modal!</p>
            <button @click.prevent="open=false">Close</button>
        </div>
    </div>`,
    data() {
        return {
            open: false
        }
     }
})

In Vue 2 this Works;

<script src="https://unpkg.com/vue@2"></script>

<div id="app">
    <div class="outer">
        <h3>Modal Example - {{ message }}</h3>
        <div>
            <my-modal />
        </div>
    </div>
</div>

<script src="/js/my-modal.js"></script>

<script>
   const app = new Vue(
   {
       el: '#app',
       data() {
           return {
               message: 'Hello Vue!'
           }
       }
   });
</script>

For Vue3, per the documentation at: https://v3-migration.vuejs.org/breaking-changes/global-api.html#a-new-global-api-createapp I switched things over to what I expected would work:

<script src="https://unpkg.com/vue@3"></script>

<div id="app">
    <div class="outer">
        <h3>Modal Example - {{ message }}</h3>
        <div>
            <my-modal />
        </div>
    </div>
</div>

<script src="/js/my-modal.js"></script>

<script>
   Vue.createApp({
      data()
      {
          return {
              message: 'Hello Vue!'
          }
      }
   }).mount('#app')
</script>

and in the my-modal.js file I changed the first few lines to use the Global Vue:

 const { createApp } = Vue;
 const app = createApp({});

 app.component('my-modal', ...

The Vue instance works but the component is not found with the error message: "Failed to resolve component: my-modal". I tried adding a 'components' section to the Vue instance and a few other things with no luck.

Any suggestions?

Upvotes: 0

Views: 1781

Answers (1)

tony19
tony19

Reputation: 138286

Each instance from createApp() is unique. That is, calling createApp() in index.html does not return the same instance from the previous call in my-modal.js.

One solution is to declare the global app instance before importing my-modal.js:

<!-- index.html -->
<script>
window._app = Vue.createApp({⋯})
</script>

<script src="/js/my-modal.js"></script>

<script>
// finally mount
window._app.mount('#app')
</script>
// js/my-modal.js
window._app.component('my-modal', {⋯})

demo

Upvotes: 2

Related Questions