MyCounter.astro
:
<script>
const template = `
<style>
* {
font-size: 200%;
}
span {
width: 4rem;
display: inline-block;
text-align: center;
}
button {
width: 4rem;
height: 4rem;
border: none;
border-radius: 10px;
background-color: seagreen;
color: white;
}
</style>
<button id="dec">-</button>
<span id="count"></span>
<button id="inc">+</button>
`;
class MyCounter extends HTMLElement {
count: number = 0;
shadowRoot: ShadowRoot | null = null;
constructor() {
super();
const elem = document.createElement("template");
elem.innerHTML = template;
this.shadowRoot = this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(
elem.content.cloneNode(true)
);
}
connectedCallback() {
this.shadowRoot!.getElementById("inc")!.onclick = () => this.inc();
this.shadowRoot!.getElementById("dec")!.onclick = () => this.dec();
this.update(this.count);
}
inc() {
this.update(++this.count);
}
dec() {
this.update(--this.count);
}
update(count: number) {
this.shadowRoot!.getElementById("count")!.innerHTML = count.toString();
}
}
customElements.define("my-counter", MyCounter);
</script>
test.mdx
:
---
title: Welcome to Starlight
description: Get started building your docs site with Starlight.
template: splash
---
# Welcome
import "../../components/MyCounter.astro";
<my-counter />
注意,只能采用这种形式渲染:
import "../../components/MyCounter.astro";
<my-counter />
而不能采用:
import MyCounter from "../../components/MyCounter.astro";
<MyCounter />
否则,控件不显示任何内容!!!
通过浏览器调试器可以看到所有html元素都放在一个shadow-root
之下。