0.12.0
Added
-
React hooks, written into HTML attributes.
useState,useEffect,
useMemo,useRefanduseContext, reachable by bare name inside any
expression. They are a surface over primitives that already existed —effect,
computed,refandstore— so the whole set costs 70 bytes in the core
bundle. The point is not new machinery. It is that someone arriving from React
can write what they already know and have it mean the right thing here.<div v-data="{ count: useState(0) }"> <p>You clicked {count} times</p> <button @click="count++">click</button> </div>
Three differences from React, all deliberate:
The dependency array is optional. Reads are tracked through a Proxy, so an
effect with no array re-runs when something it actually read changes. The array
narrows that when you want to; it is not needed for correctness.No rule of hooks. Slots are keyed per element in call order within one
evaluation, andv-dataandv-initeach evaluate once per element. Calling a
hook inside a branch shifts nothing.No setter pair.
useStatereturns the value, not[value, setValue].
Reactive objects unwrap refs, socount++is the update and there is no
.valueanywhere in the markup.There is no
useReducer,useCallbackoruseLayoutEffect, and the reasons
are in the guide rather than left to be discovered. -
v-datacan read itself. A key can now use the keys written before it:<div v-data="{ n: useState(4), dobro: useMemo(() => n * 2) }">
Previously
v-datawas evaluated in the PARENT scope and handed over
afterwards, sodobrothere producedNaN—ndid not exist yet. It is now
filled one key at a time into the scope it is defining. Order matters, and only
backwards.A
v-datathat is not a plain object literal — a spread, a computed key, a call
returning an object — keeps the old behaviour, because there is no partial state
to expose midway through those.
Fixed
-
$theme.resolvedcontradicted the screen. It consulted only the stored
choice and the operating system, never thedata-themethe page was actually
wearing.apply()deliberately leaves an authored attribute alone, so a page
written as light, opened on a machine set to dark, displayed light while
reporting'dark'.This project's own documentation showed it: the theme page sat on a white
background with a live example inside it insisting "You are on the dark theme." -
The theme was not reactive, so text never followed it. Everything the theme
derives from is invisible to the Proxy —localStorage, a module variable, an
attribute, a media query — sov-show="$theme.resolved === 'dark'"rendered
once and then froze. Switching the theme appeared to need two clicks: the first
changed the theme, and only a later unrelated render made the text catch up.Reads now subscribe, and a
MutationObservercoversdata-themebeing written
by someone else, which is what a documentation shell pushing its theme into an
example frame does. -
The site was serving a different library from the one being tested.
site/*.min.jsare copies kept by hand and nothing checked them. All three had
drifted by a session's work, so the documentation, playground and landing page
ran an older build while every test passed against the new one. A feature could
be written, tested, committed and published and still be absent from the site.npm run check:sitenow compares them and CI fails on drift.
Read more in the CHANGELOG, or browse the documentation and the playground.