feat: example07 작성 완료

This commit is contained in:
junilHwang
2020-10-25 22:03:42 +09:00
parent 949db9500e
commit 0a13686d6c
4 changed files with 119 additions and 0 deletions

12
example07/index.html Normal file
View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Simple Component 7</title>
</head>
<body>
<h1>Example #7</h1>
<div id="app"></div>
<script src="./src/app.js" type="module"></script>
</body>
</html>

10
example07/src/app.js Normal file
View File

@@ -0,0 +1,10 @@
import Items from "./components/Items.js";
class App {
constructor() {
const $app = document.querySelector('#app');
new Items($app);
}
}
new App();

View File

@@ -0,0 +1,69 @@
import Component from "../core/Component.js";
export default class Items extends Component {
setup() {
this.$state = {
items: [
{
seq: 1,
contents: 'item1',
active: false,
},
{
seq: 2,
contents: 'item2',
active: true,
}
]
};
}
template() {
const {items} = this.$state;
return `
<ul>
${items.map(({contents, active, seq}) => `
<li data-seq="${seq}">
${contents}
<button class="toggleBtn" style="color: ${active ? '#09F' : '#F09'}">
${active ? '활성' : '비활성'}
</button>
<button class="deleteBtn">삭제</button>
</li>
`).join('')}
</ul>
<button class="addBtn">추가</button>
`
}
setEvent() {
this.addEvent('click', '.addBtn', ({target}) => {
const {items} = this.$state;
const seq = Math.max(0, ...items.map(v => v.seq)) + 1;
const contents = `item${seq}`;
const active = false;
this.setState({
items: [
...items,
{seq, contents, active}
]
});
});
this.addEvent('click', '.deleteBtn', ({target}) => {
const items = [ ...this.$state.items ];;
const seq = Number(target.closest('[data-seq]').dataset.seq);
items.splice(items.findIndex(v => v.seq === seq), 1);
this.setState({items});
});
this.addEvent('click', '.toggleBtn', ({target}) => {
const items = [ ...this.$state.items ];
const seq = Number(target.closest('[data-seq]').dataset.seq);
const index = items.findIndex(v => v.seq === seq);
items[index].active = !items[index].active;
this.setState({items});
});
}
}

View File

@@ -0,0 +1,28 @@
export default class Component {
$target;
$state;
constructor ($target) {
this.$target = $target;
this.setup();
this.setEvent();
this.render();
}
setup () {};
template () { return ''; }
render () {
this.$target.innerHTML = this.template();
}
setEvent () {}
setState (newState) {
this.$state = { ...this.$state, ...newState };
this.render();
}
addEvent (eventType, selector, callback) {
const children = [ ...this.$target.querySelectorAll(selector) ];
const isTarget = (target) => children.includes(target) || target.closest(selector);
this.$target.addEventListener(eventType, event => {
if (!isTarget(event.target)) return false;
callback(event);
})
}
}