Huy Phạm
Huy Phạm

Reputation: 1023

Vue.component alternative in Vue 3

I'm using Vue with Laravel Mix. In Vue version 2, I was able to do this:

1. resources/js/app.js:

import Vue from 'vue';
import MyComponent from './MyComponent';
Vue.component('my-component', MyComponent);

2. resources/js/MyComponent.vue:

<template>
    <p>{{message}}</p>
</template>
<script>
export default {
    name: "MyComponent",
    props: ['message']
}
</script>

As this Vue 2 document instructed. I know it was not the best practice, but it was the only approach that I have to conveniently pass data from Laravel's Blade template to the component, such as below:

3. anyview.blade.php:
<my-component :message='message' id='app'></my-component>
<script src='public/js/app.js'><script> //include compiled resources/js/app.js
<script>
    let app = new Vue({
        el: '#app',
        data() {
            return {
                message: 'Hello World';
            }
        }
    })
</script>

In real case, 'Hello World' would be replaced with something like:

message: {{$myMessaGe}}

But since Vue 3, Vue.component is no longer a thing because Vue object is not a default export.

This work flow (1-2-3) has been seamlessly fine, so returning to Vue2 is the last unhappy choice :(


I have tried to work around, just changing Vue.component with the new createApp:

4. resources/js/app.js:

import { createApp } from 'vue';
import MyComponent from './MyComponent';
createApp({
    components: {
        MyComponent,
    }
}).mount('#app');

But instead of adding MyComponent to current instance, it just creates a new one as depicted below - meaning that the prop message can't be passed through.

enter image description here


My question is: Is there any alternative API or workaround to compensate the loss of Vue.component()?

Upvotes: 5

Views: 3197

Answers (2)

Huy Phạm
Huy Phạm

Reputation: 1023

This is quite an old post. Although I'm not sure if it is the best practice, to overcome this, what I had done was instead of printing value (directly from Blade template) to the main App component, I just passed the value to the destination, or child components. Passing value through the component trees is not always the best thing to do.

3. anyview.blade.php:
<div id='app'>
    <my-component message='{{$myMessage}}'></my-component>
    <my-other-component foo='{{$bar}}'></my-other-component>
</div>

Any other piece of code are basically kept the same. The key is to pass the value to the component which needs. The thing I was doing wrong was trying to pass props value directly onto the parent most App component from a PHP variable in Blade templates

Upvotes: 0

EduDev
EduDev

Reputation: 334

I have only worked with Vue3 so far but what I understand from the documentation is that the components in Vue3 are not that different from components in Vue2.

Try this solution:

import { createApp } from 'vue';
import MyComponent from './MyComponent';

const app = createApp({});

app
   .component('MyComponent', MyComponent)
   .mount('#app');

You can find more about this in the Vue3 docs.

Upvotes: 6

Related Questions