Superfine の Issues で 「How to unmount? #136」 とあって、自分が unmount を書くならこうしたいと思ったのがきっかけ。ついでに部品化のコードも書いた。
動いている様子はこちらからどうぞ。
superfineview.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>SuperfineView</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="module" src="/script.js" defer></script>
</head>
<body>
<section id="s1"></section>
<section id="s2"></section>
</body>
</html>
script.js
import * as superfine from 'https://unpkg.com/superfine?module';
export class SuperfineManager {
constructor(container, template) {
this.container = container;
this.template = template;
this.node = null;
this.update = null;
}
setup(node) {
this.node = node;
this.update = () => {
this.node = superfine.patch(this.node, this.template(), this.container);
return this;
}
return this;
}
teardown() {
// this.update = () => {
// this.node = superfine.patch(null, null, this.container);
// return this;
// }
return this;
}
mount(node) {
this.setup(node).update();
return this;
}
unmount() {
this.teardown().update();
return this;
}
}
export class SuperfineComponents extends Array {
h(name, attributes, children) {
this.push(superfine.h(name, attributes, children));
return this;
}
}
export class Counter extends SuperfineComponents {
display(attributes, children=this.state.count) {
return this.h('h2', attributes, children);
}
addButton(attributes, children='+') {
const handlers = {
onclick: () => { this.state.count++ }
}
const properties = Object.assign(handlers, attributes);
return this.h('button', properties, children);
}
subButton(app, attributes, children='-') {
const handlers = {
onclick: () => { this.state.count-- }
}
const properties = Object.assign(handlers, attributes);
return this.h('button', properties, children);
}
}
export const counter = state => {
const c = new Counter();
c.state = state;
return c;
};
SuperfineManager.prototype.pushTo = function(array) {
array.push(this);
return this;
}
const state = {count:0};
const proxy = new Proxy(state, {
set(target, property, value, receiver) {
target[property] = value;
managers.forEach(m => m.update());
return true;
}
});
const managers = [];
new SuperfineManager(document.querySelector('#s1'), () =>
superfine.h('div', {}, counter(proxy)
.h('h1', {}, 'S1 Counter')
.display()
.subButton()
.addButton()
)
)
.mount()
.pushTo(managers);
new SuperfineManager(document.querySelector('#s2'), () =>
superfine.h('div', {}, counter(proxy)
.h('h1', {}, 'S2 Counter')
.addButton()
.subButton()
.display()
)
)
.mount()
.pushTo(managers);