diff --git a/example07/index.html b/example07/index.html new file mode 100644 index 0000000..a9ed056 --- /dev/null +++ b/example07/index.html @@ -0,0 +1,12 @@ + + + + + Simple Component 7 + + +

Example #7

+
+ + + \ No newline at end of file diff --git a/example07/src/app.js b/example07/src/app.js new file mode 100644 index 0000000..3aa76ed --- /dev/null +++ b/example07/src/app.js @@ -0,0 +1,10 @@ +import Items from "./components/Items.js"; + +class App { + constructor() { + const $app = document.querySelector('#app'); + new Items($app); + } +} + +new App(); diff --git a/example07/src/components/Items.js b/example07/src/components/Items.js new file mode 100644 index 0000000..65f65d9 --- /dev/null +++ b/example07/src/components/Items.js @@ -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 ` + + + ` + } + + 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}); + }); + } +} + diff --git a/example07/src/core/Component.js b/example07/src/core/Component.js new file mode 100644 index 0000000..c218bde --- /dev/null +++ b/example07/src/core/Component.js @@ -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); + }) + } +}