astro中创建web components
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
之下。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话