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 :-)