Every UI framerwork deserves its 'counter' example...
import van from "https://vanjs.org/code/van-0.11.9.min.js" const {button, div, h1} = van.tags const points = van.state(0) const inc = () => ++points.val function App () { return div ( h1("Value : ", points), button({onclick : inc}, "INC") ) } van.add(app, App())
In the following example, the state is represented by an object instead of a single value, read the doc for more informations.
Beware the 'actions' object is my own 'business' and has nothing to do with VanJS.
import van from "https://vanjs.org/code/van-0.11.9.min.js" const {button, div, h1} = van.tags const State = van.state({ value : 0 }) const actions = ((state) => { const s = state.val; return ({ inc : () => { state.val = {...s, value : ++s.value} }, dec : () => { state.val = {...s, value : --s.value} } }) })(State) function App (state) { return div ( van.bind(state, (s) => h1("Value : ", s.value)), button({onclick : actions.inc}, "INC"), button({onclick : actions.dec}, "DEC") ) } van.add(app, App(State))
And for the final : multiple counters :
import van from "https://vanjs.org/code/van-0.11.9.min.js" const {button, div, h1} = van.tags // I could have use an array of values... // But I wanted to play with dynamic properties const State = van.state({ value0 : 0, value1 : 0, value2 : 0 }) const actions = ((state) => { const s = state.val; return ({ inc : (index) => { state.val = {...s, [`value${index}`] : ++s[`value${index}`]} }, dec : (index) => { state.val = {...s, [`value${index}`] : --s[`value${index}`]} } }) })(State) function Counter(state, index = 0) { return div ( van.bind(state, (s) => h1("Value : ", s[`value${index}`])), button({onclick : () => actions.inc(index)}, "INC"), button({onclick : () => actions.dec(index)}, "DEC") ) } function App (state) { return div( [...Array(3)].map((_, index) => Counter(state, index)) ) } van.add(app, App(State))
Here is an optimised version, thanks Tao OpimisedMC
import van from "https://vanjs.org/code/van-0.11.9.min.js" const {button, div, h1} = van.tags const State = { value0 : van.state(0), value1 : van.state(0), value2 : van.state(0), value3 : van.state(0), } const actions = ((state) => { return ({ inc : (index) => ++(state[`value${index}`]).val , dec : (index) => --(state[`value${index}`]).val }) })(State) function Counter (state, index) { return div ( h1("Counter_", index, " : ", state[`value${index}`]), button({onclick : () => actions.inc(index)}, "INC"), button({onclick : () => actions.dec(index)}, "DEC") ) } function App (state) { return Object.keys(State) .map((_, index) => Counter(state, index) ) } van.add(app, App(State))
Top comments (6)
You can also enable a sequential workflow:
Thank you Ekehard :-)
WF
Nice , I really like your 'mix' VanJS / DML :-)
Based on your tip mAdd:
I think it should be possible to get the best of both worlds...
Sure, I think so.
What is really amazing, it is the size.
Don't hesitate to contact Tao, the author, he is a very nice guy too...
btw: it would be more efficient to use multiple primitive-valued state objects compared to using a single state object that contains everything. In other words, for your example, you can have a JavaScript object that contains multiple state-valued fields, instead of having a single state object with object-typed value.
Instead of
you can have:
Thank you for your advise Tao :-)