Closed DallyBoodil closed 9 months ago
Can you please prepare working CodeSandbox (https://codesandbox.io/s/vue) or GitHub repo with not working scenario? It would be easier to debug it.
Please also look at this:
Here is how I use vue-custom-element
with Vuetify 2:
/// src/main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router.js';
import store from './store';
import i18n from './i18n';
import './lib/directives';
import './lib/filters';
import ajax from './lib/ajax';
import vuetify from './vuetify.js';
import vueCustomElement from 'vue-custom-element';
Vue.config.ignoredElements = ['event-analytics'];
Vue.use(vueCustomElement);
App.router = router;
App.store = store;
App.vuetify = vuetify;
Vue.customElement('event-analytics', App, {
shadow: true,
beforeCreateVueInstance(root)
{
const rootNode = root.el.getRootNode();
if (rootNode instanceof ShadowRoot)
{
root.shadowRoot = rootNode;
}
else
{
root.shadowRoot = document.head;
}
root.i18n = i18n;
root.vuetify = vuetify; // otherwise we lose this.$vuetify on hot-reload in development
// Monkey patch querySelector to properly find root element - otherwise v-menu, v-tooltip and similar do not work
const { querySelector } = document;
document.querySelector = function(selector)
{
if (selector === '[data-app]') return root.shadowRoot.querySelector(selector);
return querySelector.call(this, selector);
};
return root;
},
});
<template>
<!-- src/App.vue -->
<v-app>
<v-main :data-route="$route.name">
<transition name="fade" appear mode="out-in">
<router-view />
</transition>
</v-main>
</v-app>
</template>
<script>
export default
{
name: 'App',
props: // whatever you need to pass from the parent HTML page to the WebComponent of your App
created()
{
// we need the Vuetify theme CSS variables to be inside the Shadow DOM - but Vuetify does not know about Shadow DOM, so we copy the styles manually
const theme = document.querySelector('#vuetify-theme-stylesheet');
if (theme)
{
const styleElem = document.createElement('style');
styleElem.innerHTML = theme.innerHTML;
this.$root.$options.shadowRoot.appendChild(styleElem);
}
// browser will not load web fonts in the Shadow DOM - only in the real DOM. But we still need the CSS styles in the ShadowDOM.
const styleOpenSans = document.createElement('link');
styleOpenSans.rel = 'stylesheet';
styleOpenSans.href = 'https://fonts.googleapis.com/css?family=Open+Sans:400,700,900&display=swap';
document.head.append(styleOpenSans);
const styleMDI = document.createElement('link');
styleMDI.rel = 'stylesheet';
styleMDI.href = 'https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css';
document.head.append(styleMDI);
this.$vuetify.lang.current = this.$i18n.locale;
}
};
</script>
<style>
@import "https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css";
</style>
<style src="vuetify/dist/vuetify.min.css"></style>
<style lang="scss">
.v-application
{
box-sizing: border-box; // really important !!!
overflow-y: scroll;
/* All browsers without overlaying scrollbars */
-webkit-text-size-adjust: 100%;
/* Prevent adjustments of font size after orientation changes in iOS */
word-break: normal;
-moz-tab-size: 4;
tab-size: 4;
}
.fade-enter-active,
.fade-leave-active
{
transition: all 0.15s cubic-bezier(0.55, 0, 0.1, 1);
}
.fade-enter,
.fade-leave-active
{
opacity: 0;
transform: translate(-2em, 0);
}
#app.v-application
{
overflow-y: visible;
}
.v-application .v-application--wrap
{
min-height: 0;
}
</style>
Thank you for sharing!
As with vue-web-component-wrapper, I'm having the same problem with getting Vuetify to work when the custom element is using shadowDOM (thankfully with this package, ShadowDOM can be disabled).
This package works fine when it's not using shadowDOM but it's not a bulletproof solution due to CSS conflicts when importing the web component onto 3rd party websites using Vuetify, Tailwind, Bootstrap, etc.
I keep getting this console error but don't know whether it's anything to with this issue:
Has anyone encountered the same issue and managed to get Vuetify to work with shadowDOM?
A working non-ShadomDom demo of my web component can be found here.
When ShadowDOM, is enabled, this is how it renders: https://ibb.co/0Y5tfjm