vanilla-component
v1.0.2
Published
use component structure in repeated behavior of view
Downloads
12
Maintainers
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