我正在使用 vue 开发 Web 组件。其中很多都是使用 vuetify 组件库制作的,我目前正在尝试导出到 Web 组件。我已按照此线程中描述的步骤操作:How can Add Library like Vuetify inside of a web component generated by Vue 3?,其中包括覆盖标准的“defineCustomElement”方法,但是在执行所有步骤之后,我现在无法将 props 传递给 index.html 文件中的导出组件。
一些代码片段可以给你一个想法:
<custom-vuetify-element checkProp = "foo"></custom-vuetify-element>
这个问题的原因可能是什么?重写定义自定义元素方法中是否有任何内容可以更改以使得传递道具成为可能?
任何帮助将不胜感激! 预先感谢
尝试过各种方法。不幸的是,这个具体问题并没有在其他地方真正提到过。
您可以尝试直接使用它,而不是包装传入的组件:
const defineCustomElement = (component, { plugins = [] } = {}) =>
VueDefineCustomElement({
...component,
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)
},
})
见游乐场
如果将组件包装在重写的
defineCustomElement()
函数中,则需要传递 props 并发出,然后将它们连接到组件实例:
const defineCustomElement = (component, { plugins = [] } = {}) =>
VueDefineCustomElement({
props: component.props, // <---- pass on component props
emits: component.emits, // <---- pass on component emits
setup(props, {emit}) {
const app = createApp({})
plugins.forEach(app.use)
const instance = getCurrentInstance()
Object.assign(instance.appContext, app._context)
Object.assign(instance.provides, app._context.provides)
const emitProps = turnEventNamesToProps(component.emits, emit) // <--- turn events into props (see below)
return () => h(component, {...props, ...emitProps}) // <--- return render function from setup
},
})
要将发射传递给实例,您必须将它们转换为道具。例如,如果您的组件发出名为
myEvent
的事件,则需要传入一个属性 onMyEvent
以及触发包装器组件上的发出的处理程序。
这是一个示例,它将事件名称数组转换为一个对象,其中 prop 名称作为键,处理程序作为值:
const emitEventToProp = eventName => 'on' + eventName[0].toUpperCase() + eventName.slice(1)
const turnEventNamesToProps = (eventNames, emitter) => {
const buildHandler = (eventName) => (...args) => emitter(eventName, ...params)
const entries = eventNames.map(eventName => [
emitEventToProp(eventName),
buildHandler(eventName)
])
return Object.fromEntries(entries)
}
请注意,Vue 在 Web 组件上可以监听的事件名称似乎受到限制。虽然 Web 组件可以发出
update:modelValue
事件,甚至会随之发出 update:model-value
,但将 @update:modelValue
放在 Vue 模板中的 Web 组件上似乎不会注册侦听器。
这是在游乐场