How to render html tag as component inside root element - Vue 3

Viewed 44

I have a project where I am using Sage Roots (v10), with Vue js (v3).

I have been successful in bringing in Vue and mounting the App.vue (Single Page Component) onto a root element in side the app.blade.php file:

app.js

import App from './App.vue'
const app = createApp(App)

app
  .use(router)
  .mount('#wp-vue-app');

app.blade.php

<div id="wp-vue-app">
   <!-- App.vue renders here -->
</div>

But now I want to render components via php inside the root element <div id="wp-vue-app"> with Global components:

app.js

import Header from './components/Header'
import router from "@scripts/router";

const app = createApp({})

app
  .component('MainHeader', Header)
  .use(router)
  .mount('#wp-vue-app');

app.blade.php

<div id="wp-vue-app">
   <MainHeader :menu-items="{{ @json_encode(wp_get_nav_menu_items('main-menu')) }}" /> 
</div>

But this does not appear to work, and I cannot figure out why. Vue appears to remove all the content between the <div id="wp-vue-app"></div>.

I thought it might be the way the component is registered, or the way I have called the createApp(). I haven't been able to find anything useful when it comes to SPA's.

Any help would be appreciated!

1 Answers

A little digging on the internet and I found the solution!

This has do with the fact the in Vue 3 you need to specify if you are wanting to use the run-time compiler to render components during runtime instead of compile time.

When importing the createApp function from Vue, you need to specify the ESM Bundler:

import {createApp} from "vue/dist/vue.esm-bundler.js";

However, that alone did not solve the issue for me.

Since I am using Sage Roots v10, it uses Bud.js (a wrapper for Webpack), and it did not know how to handle the above import.

To fix it, you need to add the following alias into the bud.config.js file:

  app.alias('vue', 'vue/dist/vue.esm-bundler.js') 

and change the import back to:

import {createApp} from "vue";

After adding those fixes I was able to render the components placed in my blade templates at runtime!

Related