원하는 내용을 담은 html 코드를 태그 하나로 축약할 수 있음
<hello-p name="song"></hello-p>
// connectedCallback() 함수는 컴포넌트가 html에 적용될 때 실행됨
if ('customElements' in globalThis) {
customElements.define("hello-p", class extends HTMLElement {
connectedCallback() {
let name = this.getAttribute('name');
this.innerHTML = `<p>${name} 입니다. 잘 부탁드립니다!</p>`
}
});
}
/* 풀어서 작성 위 코드와 의미 같음 */
class hello extends HTMLElement {
connectedCallback() {
let name = this.getAttribute('name');
this.innerHTML = `<p>${name} 입니다. 잘 부탁드립니다!</p>`
}
}
if ('customElements' in globalThis) {
customElements.define("hello-p", hello);
}

스타일을 넣으면 오염됨
<p>왜 나도 색이 변해?</p>
<hello-p name="song"></hello-p>
class hello extends HTMLElement {
connectedCallback() {
let name = this.getAttribute('name');
this.innerHTML = `
<p>${name} 입니다. 잘 부탁드립니다!</p>
<style>p{color : skyblue}</style>
`
}
}
if ('customElements' in globalThis) {
customElements.define("hello-p", hello);
}

스타일을 shadow DOM에 넣으면 됨
<p>왜 나도 색이 변해?</p>
<hello-p name="song"></hello-p>
class hello extends HTMLElement {
connectedCallback() {
let name = this.getAttribute('name');
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<p>${name} 입니다. 잘 부탁드립니다!</p>
<style>p{color : skyblue}</style>
`
}
}
if ('customElements' in globalThis) {
customElements.define("hello-p", hello);
}

slot은 웹 컴포넌트에서 특별한 역할을 하는 태그<euid-stack>
<span slot="headline">슬롯(Slot)</span>
<span slot="description">슬롯! 나를 넣어줘</span>
</euid-stack>
if ('customElements' in globalThis) {
customElements.define('euid-stack', class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<div class="euid-stack">
<h2><slot name="headline"></slot></h2>
<p><slot name="description"></slot></p>
</div>
<style>h2 {color : skyblue}</style>
<style>p {color : pink}</style>
`;
}
});
}

: JSX에 데이터를 끼워 넣으려면 슬롯을 사용 (React에서 slot이라는 명칭은 공식적이지 않음)
📍주의) JSX 내부 슬롯 { } 안에 문을 사용할 수 없음
<div id="root"></div>
<button type="button">대답</button>
import React from 'https://esm.sh/react';
import ReactDOM from 'https://esm.sh/react-dom';
const question = '지금 무슨 노래 듣고 계세요? '
const answer = '뉴진스의 하입보이요'
const button = document.querySelector('button');
const creatApp = (data) => {
return (
<div id="app">
<h1>
{data}
</h1>
</div>
)
}
function render(mode = 'question') {
reactDomRoot.render(creatApp(mode === 'question' ? question : answer));
}
const handleChangeMent = () => {
if (mode.includes('question')) {
mode = 'answer';
button.textContent = '질문'
}
else {
mode = 'question';
button.textContent = '대답'
}
render(mode);
}
const root = document.getElementById('root');
const reactDomRoot = ReactDOM.createRoot(root);
let mode = 'question';
render()
button.addEventListener('click', handleChangeMent)

class, for, while, if ....aria-label, aria-hidden, data-index ...style={{ color: 'blue'}}style={{ color: 'green', fontSize: '20px' }}// ex)
<div id="app">
<h1 style={{ color: 'blue', fontSize: '20px' }}>
안녕하시오
</h1>
</div>
{' '}