'How to use vue router and vuex inside custom element from root?

I have project with nested custom elements. Now I need to vuex & vue router. How I can use this packages from root custom element and then use in all child custom elements?

Currently I tried only use vuex inside each component like this:

<script>
import store from './store';

export default {
  setup() {
    const state = store.state;

    return { state };
  },
};
</script>

Here is demo project with nested custom elements

Here is my main.js file code:

import { defineCustomElement } from "./defineCustomElementWithStyles";
import App from "./App.ce.vue";

customElements.define("app-root", defineCustomElement(App));


Solution 1:[1]

Vue plugins require the app instance, which is not defined for components created from defineCustomElement(). As a workaround, you can install the plugins on a temporary app instance, and then copy the resulting context over to the actual app, as seen in this utility (which we'll use later):

// defineCustomElementWithStyles.js
import { defineCustomElement as VueDefineCustomElement, h, createApp, getCurrentInstance } from 'vue'

export const defineCustomElement = (component, { plugins = [] } = {}) =>
  VueDefineCustomElement({
    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)
    },
  })

Use the defineCustomElement() above instead of the one from vue:

// main.js
import { defineCustomElement } from './defineCustomElementWithStyles'
import App from './App.ce.vue'
import store from './store'
import router from './router'

customElements.define(
  'app-root',
  defineCustomElement(App, {
    plugins: [store, router],
  })
)

demo

Solution 2:[2]

You could import them in your main.js file which is the file where you initialize the vue instance.

import Vue from 'vue';
import store from './store';
import { Router } from './router/index.js';

new Vue({
 
  router: Router,
  store,
  render: h => h(App),

}).$mount('#app');

The routes can be different from yours so feel comfortable editing them for your own project.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2