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

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

Posted by: admin November 26, 2021 Leave a comment

Questions:

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));
Answers:

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

###

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.