0
votes

Vue always renders the last registered component, and only it. Even if I don't use it at all.

//main.ts
import Vue from 'vue';
Vue.component('component-one', require('./components/ComponentOne.vue'));
Vue.component('component-two', require('./components/ComponentTwo.vue'));

const app = new Vue({
    el: '#app1',
    vuetify,
})
//ComponentOne
<template>
  <h2>Component One</h2>
</template>
<script lang="ts">
import Vue from 'vue'
export default class ComponentOne extends Vue{ 
}
</script>
//ComponentTwo
<template>
  <h2>Component Two</h2>
</template>
<script lang="ts">
import Vue from 'vue';
  export default class ComponentTwo extends Vue{
  }
</script>
<body>
   <div id="app1">
      <!-- Whatever I put in here, it won't matter -->
      <!-- I will always get only the content of the last registered component -->
      <h2>Title</h2>
      <component-one></component-one>
      <component-two></component-two>
   </div>
   <script src="/js/app.js"></script>
</body>

What I get is the contents of ComponentTwo rendered on the page. Page screenshot

If I remove the lines that register my components, I'm able to use component libraries like Vuetify inside the div tag, but not if I don't. I expected to be able to use my components and any others any way I wanted inside the div tag.

Edit: Thank you guys for the answers. Is there a way to use these components inside the HTML element as I would in a template? Like so:

<!-- This could be a index.html or, in my case, a Laravel Blade view
<body>
   <div id="app1">
      <component-one></component-one>
      <component-two></component-two>
   </div>
   <script src="/js/app.js"></script>
</body>

Vuetify components works fine this way if I don't register any custom component.

2
Thank you for updating the question, I am going to say this will not work without some configuration on the Laravel side. A quick search leads me to believe it is possible but tricky. I read this post vegibit.com/how-to-use-vuejs-with-laravel-blade - Scornwell
I believe it will demand some configuration from Vue side, it does not matter if I doing this from blade or a HTML file. I've read this post, he used pure javascript, I think that's the reason he didn't have much problem, because it does not force you to have an entry point and use components exclusively from templates (I believe). - Paulo Patez
Yeah, typescript needs to compile first which could be the problem, so switch it over to javascript and see if it runs? - Scornwell
But it is being compiled first, everything is in the resulting app.js. - Paulo Patez
I got a lead! Since I can use Vuetify components the way I desire, I will try to register my components in a plugin and use it, the same way I'm using Vuetify.. - Paulo Patez

2 Answers

0
votes

Why are you using a javascript main.js instead of a main.ts?

below is a standard main.ts app mount function. You would rename #app to #app1

import Vue from 'vue';

new Vue({
    render: (h) => h(App)
}).$mount('#app');

This mounts the main .vue instance at which point will allow the rendering of whatever components you like. A small example below using some of your code and the helper vue-property-decorator which is not required but you may find very helpful when working with Typescript and Vue

<template>
  <div>
   <body>
    <div id="app1">
      <h2>Title</h2>
      <component-one></component-one>
      <component-two></component-two>
     </div>
    </body>
  </div>
</template>


<script lang="ts">
    @Component({
        components: {
            // This is the way to lazy load components, you could also just import them normally above the @component decorator
            'component-one': () => import('@/components/ComponentOne.vue').then(m => m.default),
            'component-two': () => import('@/components/ComponentTwo.vue').then(m => m.default),
        }
    })
    export default class App extends Vue {}
</script>
0
votes

in your main.js file, you need to specify the first component to be rendered, like this:

import Vue from 'vue'
import App from './App.vue'

new Vue({
  el: '#app',
  render: h => h(App),
})

Then, inside this first component (in my example App.vue) , you can import your other components (like ComponentOnde.vue and ComponentTwo.vue).