Appearance
React → Vue mapping
This page expands the “Behavior (current)” section from the root README. For a complete, implementation-level checklist (parser + codegen), see Compiler features. For unsupported patterns, see limitations.
Component shape
- One React function component per file is the intended target.
- Default export is resolved, including through
React.memo,React.forwardRef, and similar wrappers (see parser logic insrc/parser/react.ts). - Named default-export arrow forms and
functiondeclarations are supported. - The template is taken from the last
returnthat yields JSX (early returns that don’t represent the main tree can be skipped—see tests).
Setup preservation
Component body statements are emitted in source order where possible:
- Destructuring (e.g.
const { a } = useThing()), custom hooks, and nestedfunctiondeclarations are often emitted as verbatim script text. useState-backed values get best-effort.valueunwrapping inside lowered snippets when the compiler recognizes the pattern.
Hooks → Vue
| React | Vue (approximate) |
|---|---|
useState | ref (+ optional setter helper) |
useRef | ref |
useMemo(() => …, deps) | computed(() => …) using the real factory source when possible |
useEffect(fn, []) | onMounted(fn) |
useEffect(fn, [deps]) | watch([...], fn, { flush: 'post' }) — dependency expressions are rewritten so ref-like React names map to Vue refs |
useEffect(fn) (no deps array) | watchEffect(fn) |
Cleanup: return () => { ... } inside useEffect may still need manual mapping to watch / onMounted teardown in Vue.
JSX and template
- Object spread on JSX elements →
v-bindin the template (see fixturetest/fixtures/spread.jsx). - Component vs DOM follows React’s usual lowercase intrinsic rule.
- Lists:
keyis placed ontemplate/v-foras appropriate (see tests for “key on template v-for”). - Conditionals and children are lowered into the IR template tree (
TemplateNodetypes insrc/ir/types.ts).
Output format
- Vue 3 SFC with
<script setup lang="ts">and<template>.
Tests as specification
Behavior is pinned by test/convert.test.mjs and fixtures under test/fixtures/:
destructure.jsx— destructuring preserved verbatimearly-return.jsx— last JSX return winsarrow-implicit.jsx— default export arrow + implicit return JSXspread.jsx— spread →v-binduse-effect.jsx—useEffect→watch/onMounted
Additional assertions in the same test file cover useMemo with props/state, v-for / key placement, and inline handlers.