Skip to content

Instantly share code, notes, and snippets.

@DanielCoulbourne
Last active May 27, 2024 22:33
Show Gist options
  • Save DanielCoulbourne/61bb9d2a5bdea5e4d03060eae6822e1a to your computer and use it in GitHub Desktop.
Save DanielCoulbourne/61bb9d2a5bdea5e4d03060eae6822e1a to your computer and use it in GitHub Desktop.
Vue loves to strip all the content out of template tags, even if those tags are within a `v-pre`. This breaks many AlpineJS features that rely on templates like `x-if` and `x-for`.
let copyContentsIntoTemplateTags = (templates, selector) => {
document
.querySelectorAll(selector)
.forEach((element, index) => {
element.replaceChildren();
element.content.prepend(templates[index]);
});
}
let copyContentsOutOfTemplateTags = (selector) => {
let templates = []
document
.querySelectorAll(selector)
.forEach(template => {
templates.push(
template.content.cloneNode(true)
)
});
return () => copyContentsIntoTemplateTags(templates, selector);
}
export {
copyContentsOutOfTemplateTags,
copyContentsIntoTemplateTags
}
import vue from 'vue';
import { copyContentsOutOfTemplateTags, copyContentsIntoTemplateTags } from './AlpineVueHackAdaptor';
import { Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';
// Cache the contents of all the template tags
let resetTemplates = copyContentsOutOfTemplateTags('[alpine-pre] template');
const app = vue.createApp({});
app.mount('#app');
// Put the Contents back after vue does its thing.
resetTemplates();
window.Alpine = Alpine
Alpine.start()
<html>
<head>
@vite(['resources/js/app.js'])
</head>
<body>
<div id="app" class="container mx-auto py-24">
<example-component></example-component>
<!-- v-pre tells vue to leave us alone. alpine-pre is our selector -->
<div x-data="{ open: false }" class="py-12" v-pre alpine-pre>
<button x-on:click="open = ! open">Alpine x-if</button>
<template x-if="open">
<div>
Content...
</div>
</template>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment