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之下。

posted @   卓能文  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示