I have noticed there are a few common/repeated methods I keep reusing in some web components I am working on. When I change the method in one, if I want the improvement in the others, I have to open each one and make the changes to all the other components, which is tedious and error prone. So I am trying to create a BaseComponent
which the other components inherit from.
The issue is I would like to define the component name, e.g. wc-thingy
in one place, keep it DRY. However this name is requried in two places:
TEMPLATE_<component_name>
, e.g. TEMPLATE_wc-thingy
customElements.define
it.Below is my attempt to try accomplish it, but I think the issue is this.constructor
is not refering to the subclass class instance:
window.BaseComponent = class extends HTMLElement {
static componentName;
static define(componentName) {
this.constructor.componentName = componentName;
window.customElements.define(this.constructor.componentName, this);
}
constructor() {
super();
this.attachShadow({ mode: "open" });
const template = document.getElementById("TEMPLATE_" + this.constructor.componentName);
this.shadowRoot.appendChild(template.content.cloneNode(true));
console.log("Contructed", this.constructor.componentName)
}
sayHello() {
console.log("Hello");
}
};
(class extends window.BaseComponent {
sayBi() {
console.log("K Bi, thxns!");
}
}).define('wc-thingy')
<wc-thingy>thingy here</wc-thingy>
+1 for creating your own BaseComponent
-392.176.112 if you now think you are great, and sell it to the world like the other 60+ BaseClasses
The Web Component name is in this.nodeName
(uppercase) or this.localName
(lowercase)
<template id="WC-FOO">foo:<slot></slot></template>
<template id="WC-BAR">bar:<slot></slot></template>
<wc-foo>FOO</wc-foo>
<wc-bar>BAR</wc-bar>
<script>
class BaseComponent extends HTMLElement {
constructor() {
const template = () => document.getElementById(this.nodeName).content;
super().attachShadow({mode:"open"})
.append(template().cloneNode(true));
console.log("Contructed", this.nodeName , this.localName)
}
};
customElements.define("wc-foo", class extends BaseComponent {});
customElements.define("wc-bar", class extends BaseComponent {});
</script>