59 lines
4.0 KiB
Markdown
59 lines
4.0 KiB
Markdown
# Architecture
|
|
|
|
## Ownership boundary
|
|
|
|
Vue Router owns matching, lazy components, committed routes, redirects, guards, URL serialization, and browser history. Native Vue Router owns a separate visual ledger containing mounted route entries, scroll/focus state, cache status, and the current interactive transaction.
|
|
|
|
A forward drag calls `router.resolve()` and Vue Router's public `loadRouteLocation()`, then renders the location through `<RouterView :route>` without calling `push()`. The URL and application history remain unchanged until the gesture commits.
|
|
|
|
Each preview subtree receives a scoped `routeLocationKey`, so `useRoute()` returns preview params even though the global route is not committed. A normal `router.push()` or `replace()` runs only after the gesture chooses to commit. A guard failure cancels the transaction and removes the preview.
|
|
|
|
## Transaction lifecycle
|
|
|
|
Transactions move through `interactive`, `committing`, `settling`, and cancellation states. They expose normalized progress and velocity plus `fromKey`, `toKey`, direction, presentation, and optional source geometry.
|
|
|
|
The runtime deliberately keeps two ledgers. The navigation stack mirrors committed push/replace/pop semantics and is the only source of predictive-back targets. The view cache owns mounted component instances independently, so a replaced tab can be reused without becoming an accidental back destination.
|
|
|
|
Pointer movement changes only a CSS progress variable. Built-in presentations restrict active-frame work to compositor-friendly properties. Velocity is expressed as normalized route progress per second, so gesture behavior remains consistent across screen sizes. Release uses distance/velocity intent and a damped spring whose settling rate follows the user's flick speed. Reduced-motion mode settles immediately.
|
|
|
|
Settling animations are interruptible. A new button navigation or recognized gesture waits only for any in-flight Vue Router guard/history commit, immediately finalizes the old visual transaction, and begins from the newly authoritative route. It never waits for the previous spring to finish. Leading-edge back recognition runs in the navigator capture phase so partially visible component layers cannot steal the physical back edge.
|
|
|
|
Component gesture owners stop propagation before a containing navigator can claim the same pointer. Navigator gestures wait for horizontal intent, use pointer capture, respect form controls and `data-native-gesture="ignore"`, and preserve normal vertical scrolling through `touch-action: pan-y`.
|
|
|
|
## Route metadata
|
|
|
|
```ts
|
|
interface NativeRouteOptions {
|
|
navigator?: string
|
|
presentation?: 'push' | 'reveal' | 'slide' | 'fade' | 'modal' | 'sheet' | string
|
|
parent?: RouteLocationRaw | ((route) => RouteLocationRaw)
|
|
siblingGroup?: string
|
|
siblingOrder?: number
|
|
siblingHistory?: 'push' | 'replace'
|
|
cache?: boolean
|
|
gesture?: boolean | 'edge' | 'full'
|
|
}
|
|
```
|
|
|
|
`parent` supplies a predictive back target when a deep link starts without an in-memory predecessor. Sibling routes replace history by default and use the built-in `slide` presentation, which moves both pages one-to-one as adjacent surfaces. Direction comes from `siblingOrder`. Set `siblingHistory: 'push'` when browser back should visit prior sibling selections.
|
|
|
|
## Custom presentations
|
|
|
|
```ts
|
|
nativeRouter.registerPresentation(definePresentation({
|
|
name: 'scale-fade',
|
|
axis: 'x',
|
|
layerStyle({ role, progress }) {
|
|
return role === 'to'
|
|
? { opacity: progress, transform: `scale(${0.92 + progress * 0.08})` }
|
|
: { opacity: 1 - progress * 0.4 }
|
|
},
|
|
}))
|
|
```
|
|
|
|
Applications can call `beginInteractive()`, `updateInteractive()`, and `finishInteractive()` to drive the same transaction engine from a bespoke recognizer.
|
|
|
|
## Cache semantics
|
|
|
|
The active route and recent inactive routes remain mounted. The default limit is eight inactive views per runtime. Older entries keep their route descriptor but are unmounted and lazily restored when revisited. Application data that must survive eviction belongs in an application store.
|