vuejs/vue-web-component-wrapper

Vuetify compatibility

DallyBoodil opened this issue · 3 comments

As with vue-custom-element, I'm having the same problem with getting Vuetify to working when the custom element is using shadowDOM.

vue-custom-element 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.

The error I get is the following:

[Vuetify] Unable to locate target [data-app]

found in

---> <VDialog>
       <Payment> at src/views/Payment.vue
         <VApp>
           <App> at src/App.vue
             <Root>

Has anyone encountered the same issue and managed to get Vuetify to work with shadowDOM?

For that particular problem, add a <div data-app/> element to your HTML source file that is using your web component.

@alfreema Could you further develop what to do?

I have this in my HTML:

<my-component/>

This in my typescript entrypoint:

const customLoginModal = wrap(Vue, {
		vuetify: new Vuetify(vuetifyConfig()),
		template: `<MyComponent/>`,

Then MyComponent.vue:

<template>
	<v-app id="my-component-app" v-if="dialog">
		<v-dialog v-model="dialog" fullscreen
...

I don't think v-dialog works well inside a web component, but if you want them to work at all you have to put:

<div data-app/>
<my-component/>

in your HTML. Vuetify requires a div with data-app attached to it. See this answer for another example of the issue: https://stackoverflow.com/a/60990132/2957186

I suppose you could create it dynamically in javascript too, but I didn't try it. You'd do something like ...

var appDiv = document.createElement('div')
appDiv.setAttribute('data-app')
document.body.appendChild(appDiv)

but I went a different direction.

I gave up on using v-dialog as it introduced a host of issues and I found that using a standard HTML <dialog> worked quite well in it's place. I styled the <dialog> like this:

<style scoped>
  /* Make the dialog "full screen"-ish, and center it vertically and horizontally */
  #dialog {
    height: 100vh;
    width: 100vh;
    border-radius: 5px;
    border: none;
    margin: auto;
  }
  /* Make the background behind the dialog transparent but dark */
  #dialog::backdrop {
      background-color: rgb(4, 4, 16);
      opacity: 0.6;
    }  
</style>

v-dialog is one of the only Vuetify components I really tussled with other than perhaps v-autocomplete. So far the rest of the components have worked quite well inside my web component.