admin管理员组文章数量:1195167
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));
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));
Share
Improve this question
edited Nov 2, 2021 at 9:36
Andreas Hunter
asked Nov 2, 2021 at 9:30
Andreas HunterAndreas Hunter
5,00418 gold badges75 silver badges142 bronze badges
3 Answers
Reset to default 24Vue 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
Just a little fix for tony19's solution:
export const defineCustomElementWrapped = (component, { plugins = [] } = {}) =>
defineCustomElement({
styles: component.styles, // <- this
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)
},
})
and then
customElements.define(
'app-root',
defineCustomElementWrapped(App, {
plugins: [store, router],
})
)
This will also include styles exported by components
(also I don't like shadowing original function names if you are changing their behaviors, so I renamed it)
Might be also required:
styles: component.styles.map((style) => {
return style
.replace(":root", ":host") // <- rename :root values to :host
.replace("body {", "#my-app {"); // <- in case of frameworks like bootstrap that styles directly body
}),
Just a small adjustments to the great answers: when you need props, emits or styles, it might be easier to destructure the component instead of wrapping it:
const defineCustomElement = (component, { plugins = [] } = {}) =>
VueDefineCustomElement({
...component, // <---- use all props from the original component (except setup)
setup(...args) {
const app = createApp({})
plugins.forEach(app.use)
const instance = getCurrentInstance()
Object.assign(instance.appContext, app._context)
Object.assign(instance.provides, app._context.provides)
return component.setup?.(...args) // <---- run initial setup if exists
},
})
本文标签: javascriptHow to use vue router and vuex inside custom element from rootStack Overflow
版权声明:本文标题:javascript - How to use vue router and vuex inside custom element from root? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738458834a2087912.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论