Thanks to @moritz-ringler for bringing up stackoverflow.com/a/76934503/4883195. I've managed to put together a working github.com/OnlyLoveOleg/vue3-vuetify-webcomponent example in case anyone is looking for a solution to this problem.
index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue3 Vuetify Web Component</title>
</head>
<body>
<my-navbar></my-navbar>
<script type="module" src="/src/main.js"></script>
</body>
</html>
src/main.js
import { defineCustomElement } from './defineCustomElementWithStyles'
import '@mdi/font/css/materialdesignicons.css'
import { createVuetify } from 'vuetify';
import { aliases, mdi } from 'vuetify/iconsets/mdi'
// Import the Vue component.
import MyNavbarComponent from './components/MyNavbar.ce.vue'
const vuetify = createVuetify({
icons: {
defaultSet: 'mdi',
aliases,
sets: {
mdi,
},
},
})
customElements.define(
'my-navbar',
defineCustomElement(MyNavbarComponent, {
plugins: [vuetify],
})
)
src/defineCustomElementWithStyles.js
// defineCustomElementWithStyles.js
import { defineCustomElement as VueDefineCustomElement, h, createApp, getCurrentInstance } from 'vue'
export const defineCustomElement = (component, { plugins = [] } = {}) =>
VueDefineCustomElement({
styles: component.styles,
render: () => h(component),
setup() {
const app = createApp()
// install plugins
plugins.forEach(app.use)
const inst = getCurrentInstance()
Object.assign(inst.appContext, app._context)
Object.assign(inst.provides, app._context.provides)
},
})
src/components/MyNavbar.ce.vue
<template>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/vuetify@3/dist/vuetify.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" />
<v-app>
<v-app-bar>
<template v-slot:prepend>
<v-app-bar-nav-icon></v-app-bar-nav-icon>
</template>
<v-app-bar-title>App title</v-app-bar-title>
<v-spacer></v-spacer>
<v-btn icon>
<v-icon>mdi-magnify</v-icon>
</v-btn>
<v-btn icon>
<v-icon>mdi-heart</v-icon>
</v-btn>
<v-btn icon>
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</v-app-bar>
</v-app>
</template>