我用新 future defineCustomElement从 vue 3.2 版本开始。
代码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],
})
)
代码defineCustomElementWithStyles.js
:
import { defineCustomElement as VueDefineCustomElement, h, createApp, getCurrentInstance } from 'vue'
const getNearestElementParent = (el) => {
while (el?.nodeType !== 1 /* ELEMENT */) {
el = el.parentElement
}
return el
}
export const defineCustomElement = (component, { plugins = [] }) =>
VueDefineCustomElement({
render: () => h(component),
setup() {
const app = createApp()
// install plugins
plugins.forEach(app.use)
app.mixin({
mounted() {
const insertStyles = (styles) => {
if (styles?.length) {
this.__style = document.createElement('style')
this.__style.innerText = styles.join().replace(/\n/g, '')
getNearestElementParent(this.$el).prepend(this.__style)
}
}
// load own styles
insertStyles(this.$?.type.styles)
// load styles of child components
if (this.$options.components) {
for (const comp of Object.values(this.$options.components)) {
insertStyles(comp.styles)
}
}
},
unmounted() {
this.__style?.remove()
},
})
const inst = getCurrentInstance()
Object.assign(inst.appContext, app._context)
Object.assign(inst.provides, app._context.provides)
},
})
代码App.ce.vue
,我在其中注册和使用prop
:
<template>
<div id="app">
<p>{{ title }}</p>
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<main>
<router-view />
</main>
</div>
</template>
<script>
export default {
name: 'App',
props: {
title: String,
},
}
</script>
代码index.html
,我在其中设置属性title
的值:
<app-root title="hello"></app-root>
收到错误消息:
Uncaught TypeError: Cannot read properties of undefined (reading 'title')
完整演示项目 here
最佳答案
由于 App
组件被包装在 defineCustomElementWithStyle
中,因此包装器的 props
应在以下范围内传递给 App
: setup()
.
将组件的
props
复制到包装器的props
中:将包装器的
render
属性移至setup()
的返回值中。将
setup()
的props
参数传递给App
的渲染 (h()
接收props
作为其第二个参数)。
export const defineCustomElement = (component, { plugins = [] }) =>
VueDefineCustomElement({
props: component.props, 1️⃣
// render: () => h(component), 2️⃣
setup(props 3️⃣) {
⋮
return () => h(component, props 3️⃣)
}
})
关于javascript - 如何在新的vue自定义元素中正确注册和使用props?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69834745/