import { createApp } from 'vue'
import type { Component, Plugin } from 'vue'
export function mountAll(component: Component, selector: string, uses: Plugin[] = []): Component[] {
var apps: Component[] = []
if (typeof document.querySelectorAll(selector)[0] !== 'undefined') {
const els = Array.prototype.slice.call(document.querySelectorAll(selector));
for (var i in els) {
const atts = { ...els[i].dataset }
const innerHtml = els[i].innerHTML
delete(atts.vApp)
if(typeof atts.inner === 'undefined') {
atts.inner = innerHtml
const app = createApp(component, atts)
uses.forEach((plugin: Plugin) => {
app.use(plugin)
app.mount(els[i])
apps.push(app)
return apps
luis_troya-as:
That’s not entirely true, this is a strategy I have been using in Laravel for several years. This is how it looks with vue 2:
The reason I mentioned it, is because bud-vue is set up to do this by default, as it only bundles the runtime version of Vue 3 out of the box.
As @talss89 already mentioned, adding app.vue.runtimeOnly(false)
to your bud config should enable you to use the strategy you’re familiar with.
talss89:
I haven’t had to bundle the template compiler in Vue 3 before, but you should be able to use vue.runtime.esm-browser.prod.js
instead of vue.esm-bundler.js
.
I didn’t know that. I thought it was doing a compiling process under the hood. But taking a look at the source code, it makes sense now
The only thing that worries me is that everything under #main
breaks because of this error without a console error, failing silently.
talss89:
EDIT: I realise I was really vague here, sorry. The idea is to mount multiple ‘root’ Vue components as Apps using a selector string. You can then share state if required using a store like pinia
loaded via the uses
argument to mountAll()
. Instead of <Component>
in your blade view, output a <div class="vue-app-component1">
, then mountAll(Component1, '.vue-app-component1')
. Do this for each component.
No problem @talss89, I appreciate any help, and that snippet you shared it’s really good. Nice to know more ways how to use the strategy I have in mind.
I think I should fix the problem I have right now in order to iterate new ideas of the best way to use Vue. What do you think @talss89?
If by any chance @talss89 @mensch, you have an example I can take a look at using Vue, I will really appreciate it!
Kind regards,
Luis.
I’ve just cloned your repo, and the template compiler is working in both dev and prod…
I wonder if Bud is reusing some cached fragments between builds. I’ve managed to break the project by removing the runtimeOnly
setting, then doing a clean.
Keep your bud.config.js
file as-is, then try running yarn run bud clean
before running yarn build
again. Hopefully that should now work.
Also, prefer app.vue.set('runtimeOnly', false)
over app.vue.runtimeOnly(false)
- I wasn’t aware of the deprecation!
Hey @talss89, the clean
command did trick!
Several hours doing changes without seeing any result, not sure for how many hours I have been using cached
But finally, it is working for me.
Thank you so much for the help, ideas and for taking the time to check the repo!
Glad to hear you’re up and running @luis_troya-as!
I think others will run into the same issue you highlighted (needing to bud clean
).
I’ve opened a feature request to address this. A fix should be included in Bud 6.12.0
, due for release tomorrow (23rd March 2023), thanks to kellymears.