Panduan Praktis Developing Web Components dengan Claude Code
Panduan praktis tentang developing web components menggunakan Claude Code dengan contoh kode dunia nyata.
gambaran umum Web Components
Web Components 、再pemanfaatandimungkinkanなカスタムHTMLelemen pembuatan untuk Web標準技術.framework 依存せず、ど proyek juga 使えるkomponen 作れ.Claude Code 使えば、Web Components pengembangan efisien 進められ.
dasar Custom Elements
class AppCounter extends HTMLElement {
private count = 0;
private shadow: ShadowRoot;
constructor() {
super();
this.shadow = this.attachShadow({ mode: "open" });
}
// pemantauanatribut
static get observedAttributes() {
return ["initial", "step"];
}
connectedCallback() {
this.count = parseInt(this.getAttribute("initial") || "0");
this.render();
}
attributeChangedCallback(
name: string,
oldValue: string,
newValue: string
) {
if (name === "initial" && oldValue !== newValue) {
this.count = parseInt(newValue);
this.render();
}
}
private get step(): number {
return parseInt(this.getAttribute("step") || "1");
}
private render() {
this.shadow.innerHTML = `
<style>
:host {
display: inline-flex;
align-items: center;
gap: 8px;
font-family: system-ui, sans-serif;
}
button {
padding: 4px 12px;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #f0f0f0;
}
.count {
font-size: 24px;
font-weight: bold;
min-width: 40px;
text-align: center;
}
</style>
<button id="dec">-</button>
<span class="count">${this.count}</span>
<button id="inc">+</button>
`;
this.shadow.getElementById("dec")!.addEventListener("click", () => {
this.count -= this.step;
this.render();
this.dispatchEvent(new CustomEvent("change", { detail: this.count }));
});
this.shadow.getElementById("inc")!.addEventListener("click", () => {
this.count += this.step;
this.render();
this.dispatchEvent(new CustomEvent("change", { detail: this.count }));
});
}
}
customElements.define("app-counter", AppCounter);
使い方:
<app-counter initial="10" step="5"></app-counter>
Lit frameworkでefisiensi
import { LitElement, html, css } from "lit";
import { customElement, property, state } from "lit/decorators.js";
@customElement("app-todo-list")
class AppTodoList extends LitElement {
static styles = css`
:host {
display: block;
max-width: 400px;
font-family: system-ui, sans-serif;
}
.input-row {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
input {
flex: 1;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
ul {
list-style: none;
padding: 0;
}
li {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 0;
border-bottom: 1px solid #eee;
}
.done {
text-decoration: line-through;
color: #999;
}
`;
@state()
private todos: Array<{ text: string; done: boolean }> = [];
@state()
private newTodo = "";
private addTodo() {
if (!this.newTodo.trim()) return;
this.todos = [...this.todos, { text: this.newTodo, done: false }];
this.newTodo = "";
}
private toggleTodo(index: number) {
this.todos = this.todos.map((todo, i) =>
i === index ? { ...todo, done: !todo.done } : todo
);
}
render() {
return html`
<div class="input-row">
<input
.value=${this.newTodo}
@input=${(e: InputEvent) =>
(this.newTodo = (e.target as HTMLInputElement).value)}
@keyup=${(e: KeyboardEvent) => e.key === "Enter" && this.addTodo()}
placeholder="task input..."
/>
<button @click=${this.addTodo}>追加</button>
</div>
<ul>
${this.todos.map(
(todo, i) => html`
<li>
<input
type="checkbox"
.checked=${todo.done}
@change=${() => this.toggleTodo(i)}
/>
<span class=${todo.done ? "done" : ""}>${todo.text}</span>
</li>
`
)}
</ul>
`;
}
}
スロットによるコンポジション
@customElement("app-card")
class AppCard extends LitElement {
static styles = css`
:host {
display: block;
border: 1px solid #e2e8f0;
border-radius: 8px;
overflow: hidden;
}
.header {
padding: 16px;
background: #f8fafc;
border-bottom: 1px solid #e2e8f0;
}
.body {
padding: 16px;
}
.footer {
padding: 16px;
background: #f8fafc;
border-top: 1px solid #e2e8f0;
}
`;
render() {
return html`
<div class="header">
<slot name="header"></slot>
</div>
<div class="body">
<slot></slot>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
`;
}
}
<app-card>
<h2 slot="header">カードタイトル</h2>
<p>カードの本文がここに入ります。</p>
<button slot="footer">アクション</button>
</app-card>
Integrasi dengan React
import { useRef, useEffect } from "react";
function CounterWrapper({
initial,
onChange,
}: {
initial: number;
onChange: (value: number) => void;
}) {
const ref = useRef<HTMLElement>(null);
useEffect(() => {
const el = ref.current;
const handler = (e: Event) => {
onChange((e as CustomEvent).detail);
};
el?.addEventListener("change", handler);
return () => el?.removeEventListener("change", handler);
}, [onChange]);
return <app-counter ref={ref} initial={initial} />;
}
Pemanfaatan dengan Claude Code
Web Componentspengembangan Claude Code 依頼 例.スタイリング Tailwind CSSpemanfaatan法、komponen設計 参考 sebagai コード分割・遅延loading juga bisa dijadikan referensi.
Lit 使ってデザインsistem komponen buatkan.
- app-button, app-input, app-modal, app-toast
- CSS Custom Properties dengan temadukungan
- TypeScript dengan type safety
- Storybook dengan dokumen化して
Web Components 仕様 MDN Web Components silakan lihat.Claude Code 詳細 公式dokumen konfirmasi bisa dilakukan.
Summary
Web Components framework非依存 再pemanfaatandimungkinkanなUI pembangunan きる標準技術.Claude Code 使えば、Custom ElementsやLit implementasi efisien 進められ、既存proyek dan integrasi juga スムーズ 行え.
Related Posts
Cara Mempercepat Side Project dengan Claude Code [Dengan Contoh]
Pelajari cara mempercepat project development personal secara drastis menggunakan Claude Code. Dilengkapi contoh nyata dan workflow praktis dari ide hingga deployment.
Cara Mengotomatisasi Refactoring dengan Claude Code
Pelajari cara mengotomatisasi code refactoring secara efisien menggunakan Claude Code. Dilengkapi prompt praktis dan pola refactoring konkret untuk project nyata.
Panduan Lengkap Konfigurasi CORS dengan Claude Code
Pelajari tentang panduan lengkap konfigurasi CORS menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.