README
Vanilla Component
바닐라 JS(Pure JS) 환경에서 generator
문법을 이용해서 컴포넌트 기반의 구조화를 가능케 한다.
컴포넌트의 역할을 다음과 같이 단순화 및 추상화한다.
- 렌더링: DOM 에 그려진다.
- 이벤트 바인딩: 컴포넌트 내의 특정 요소에 이벤트 바인딩이 가능하다.
- 데이터 정적 바인딩: 렌더링 이전에 정적인 데이터를 바인딩한다.
- 데이터 동적 바인딩: 렌더링 이후에 동적으로 데이터를 바인딩한다.
- 컴포넌트 트리구조 추상화: 상위 컴포넌트 렌더링시 하위 컴포넌트도 자동 렌더링된다.
1. 시작하기
컴포넌터 설계 > 생성 > 렌더링의 절차를 가진다.
import vc from 'vanilla-component';
// 컴포넌트 정의하기(추상화된 뷰)
const Box = vc.define(function* (data) {
return vc.create(`
<div class="box">
<a href="#" class="link">${data.text}</a>
</div>
`);
});
// 컴포넌트 생성하기(구체화된 뷰)
// 생성 시 정적 데이터 바인딩할 데이터를 넣어준다.
const box = Box.create({ text: 'Hello World' });
// 렌더링하기
vc.render(box, document.getElementById('wrap'));
2. 이벤트 바인딩하기
delegation 을 이용하며 다음과 같은 문법으로 사용한다.
// 위에서 생성된 box 를 이용한다고 가정한다.
// .box 에 이벤트 핸들러를 등록한다.
box.on('click', function handleBox(event) {
console.log(event.target);
});
// .link 에 이벤트 핸들러를 등록한다.
box.on('click', '.link', function handleBoxLink(event) {
console.log(event.target.innerText);
});
내부적으로 bubbling 이벤트를 사용하며, event.stopPropagation()을 하도록 설계되어있다.
따라서 자식 컴포넌트에서 이벤트가 발생했을 때, 부모컴포넌트의 이벤트까지 불리지 않는다.
3. 데이터 동적 바인딩하기
동적 바인딩할 요소에 data-mutate 속성을 다음의 문법으로 넣어준다.
data-mutate="key=($variable),key=($variable),..."
import vc from 'vanilla-component';
const Box = vc.define(function* (data) {
// box 에 style 속성을 동적으로 $style 변수로 바인딩한다.
// box 에 text 속성(innerText)를 $text 변수로 바인딩한다.
return vc.create(`
<div class="box" data-mutate="style=($style),text=($text)">
${data.initialText}
</div>
`);
});
const box = Box.create({ initialText: 'text is static' });
vc.render(box, document.getElementById('wrap'));
// box 의 텍스트 속성을 동적 바인딩한다.
box.mutate({
$style: 'border: 1px solid #333;',
$text: 'text is mutated'
});
4. 컴포넌트 트리 구조 만들기
4-1. 컴포넌트 트리 렌더링
부모 컴포넌트 렌더링 시 자식컴포넌트도 모두 자동으로 렌더링된다.
yield
키워드를 이용해서 자식 컴포넌트를 정의해준다.
정의한 컴포넌트를 template literal 에 넣어주면 자동으로 렌더링된다.
import vc from 'vanilla-component';
const Child = vc.define(function* (data) {
return vc.create(`
<div class="child">
<span>${data.given}</span>
<span>${data.text}</span>
</div>
`);
});
const Parent = vc.define(function* (data) {
// 자식 컴포넌트들을 정의한다.
// 부모가 받은 데이터를 자식에게 전달해줄 수있다.
const childFirst = yield Child.create({
text: 'first child',
given: data.given
});
const childSecond = yield Child.create({
text: 'second child',
given: data.given
});
return vc.create(`
<div class="parent">
${childFirst}
${childSecond}
</div>
`);
});
const parent = Parent.create({ given: 'parent' });
vc.render(parent, document.getElementById('wrap'));
4-2. 부모 컴포넌트를 통해 자식컴포넌트 접근
yield
한 순서대로 인덱스로 접근 가능하다.
// 위의 예제에서 parent 에서 자식 컴포넌트에 접근한다고 가정한다.
parent.children[0]; // childFirst
parent.children[1]; // childSecond