[英]How can you register global components in Svelte?
Vue (at least Vue 2) allows developers to register components globally: Vue(至少 Vue 2)允许开发者全局注册组件:
import MyComponent from '@/components/MyComponent'
Vue.component('my-component-name', MyComponent)
Which then results into:然后导致:
I read in another SO post that Svelte does not support global component registration.我在另一篇 SO 帖子中读到 Svelte 不支持全局组件注册。 However, I would still like to achieve the same results as given above.
但是,我仍然希望获得与上面给出的相同的结果。
How would I approach this in Svelte?我将如何在 Svelte 中解决这个问题?
I rolled my own when I needed a similar function (it was very handy when adding some interactive components to a WordPress site).当我需要类似的 function 时,我自己推出了自己的产品(在向 WordPress 站点添加一些交互式组件时非常方便)。
Here's the code I used:这是我使用的代码:
/**
* Turn a svelte element into a simple web component
* The content inside the web component will be passed in as the `slot` attribute and it's of type: `Array<ChildNode>`
* @param svelteElem
* @param elemName
*/
export function elementify(svelteElem: any, elemName: string) {
class newElem extends HTMLElement {
svelteComp: any
constructor() {
super()
//at this point the internal elements are not mounted yet, so we need to do it before the next `paint` cycle
window.requestAnimationFrame(() => {
let children: Record<string, Array<ChildNode>> = { '___': [] }
Array.from(this.childNodes).forEach(elem => {
let slotName = "___"
if ((elem instanceof HTMLElement) && elem.getAttribute("slot")) slotName = elem.getAttribute("slot")
if (!children[slotName]) children[slotName] = []
children[slotName].push(elem)
elem.remove()
})
let props: Record<string, any> = {
slot: children,
parent: this,
}
let attribs:Array<string>
if (typeof(this.getAttributeNames)=="undefined"){
attribs = Array.from(this.attributes).map(x=>x.name)
} else {
attribs = this.getAttributeNames()
}
attribs.forEach(attr => {
props[attr] = this.getAttribute(attr)
})
let comp = this.svelteComp = new svelteElem({
target: this,
props
})
// transfer the properties and methods exposed by the component
Object.getOwnPropertyNames(Object.getPrototypeOf(comp)).forEach(prop => {
if (prop != "constructor") (this as any)[prop] = comp[prop]
})
})
}
// connectedCallback() {
// }
// disconnectedCallback(){
// }
}
customElements.define(elemName, newElem);
}
To use it, you simply do this:要使用它,您只需执行以下操作:
import MyComponent from './components/MyComponent.svelte'
elementify(MyComponent,"my-component-name")
After that you can use the <my-component-name>
tag and the Svelte component will be mounted inside that component.之后,您可以使用
<my-component-name>
标记,Svelte 组件将安装在该组件内。
My solution might have some flaws but it's been working for months in production.我的解决方案可能存在一些缺陷,但它已经在生产中运行了几个月。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.