DEV Community

Cover image for Vue v-bind to React: How does VuReact handle it?
Ryan John
Ryan John

Posted on • Originally published at vureact.top

Vue v-bind to React: How does VuReact handle it?

VuReact is a compiler for migrating from Vue to React — and for writing React with Vue syntax. In this article, we dive straight into the core: how Vue's common v-bind/: directive is compiled into React code by VuReact.

Before We Start

To keep the examples easy to read, this article follows two simple conventions:

  1. All Vue and React snippets focus on core logic only, with full component wrappers and unrelated configuration omitted.
  2. The discussion assumes you are already familiar with Vue 3's v-bind directive usage.

Compilation Mapping

v-bind / :: Basic attribute binding

v-bind (shorthand :) is Vue's directive for dynamically binding HTML attributes, component props, class, and style.

  • Vue
<img :src="imageUrl" :class="imageCls" />
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
<img src={imageUrl} className={imageCls} />
Enter fullscreen mode Exit fullscreen mode

As the example shows, Vue's :src and :class directives are compiled into React's standard attribute syntax. VuReact adopts a direct attribute compilation strategy, converting template directives into React's JSX attributes. This fully preserves Vue's attribute binding semantics — dynamically binding variable values to element attributes.


Dynamic class and style binding

Vue supports complex class and style binding expressions. VuReact handles these complex scenarios through runtime helper functions.

Dynamic class binding

  • Vue
<div :class="['card', active && 'is-active', error ? 'has-error' : '']" />
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
import { dir } from '@vureact/runtime-core';

<div className={dir.cls(['card', active && 'is-active', error ? 'has-error' : ''])} />
Enter fullscreen mode Exit fullscreen mode

Dynamic style binding

  • Vue
<div :style="{ color: textColor, fontSize: size + 'px', 'background-color': bgColor }" />
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
import { dir } from '@vureact/runtime-core';

<div style={dir.style({ color: textColor, fontSize: size + 'px', backgroundColor: bgColor })} />
Enter fullscreen mode Exit fullscreen mode

As the examples show, complex class and style bindings are compiled using the dir.cls() and dir.style() helper functions. VuReact adopts a complex binding runtime processing strategy, converting Vue's complex expressions into runtime function calls. This fully preserves Vue's dynamic styling semantics.

How the runtime helper functions work:

  1. dir.cls():

    • Handles multiple class formats including arrays, objects, and strings
    • Automatically filters falsy values (false, null, undefined, '')
    • Deduplicates repeated class names
    • Generates the final className string
  2. dir.style():

    • Handles object-format styles
    • Automatically converts kebab-case to camelCase (background-colorbackgroundColor)
    • Handles values with units (automatically appends px, etc.)
    • Generates a React-compatible style object

Compilation strategy details:

// Vue: :class="{ active: isActive, 'text-danger': hasError }"
// React: className={dir.cls({ active: isActive, 'text-danger': hasError })}

// Vue: :class="[isActive ? 'active' : '', errorClass]"
// React: className={dir.cls([isActive ? 'active' : '', errorClass])}

// Vue: :style="style"
// React: style={dir.style(style)}
Enter fullscreen mode Exit fullscreen mode

Parameterless v-bind: Object spreading

Vue supports parameterless v-bind for spreading an entire object as element attributes.

  • Vue
<Comp v-bind="props">Click</Comp>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
import { dir } from '@vureact/runtime-core';

<Comp {...dir.keyless(props)}>Click</Comp>
Enter fullscreen mode Exit fullscreen mode

As the example shows, parameterless v-bind is compiled using the dir.keyless() helper function with the object spread syntax. VuReact adopts an object spread compilation strategy, converting Vue's object binding into React's object spread. This fully preserves Vue's object attribute binding semantics.

The role of the dir.keyless() helper function:

  1. Attribute conflict resolution: Handles conflicts between object properties and existing attributes
  2. Special attribute conversion: Automatically converts classclassName, forhtmlFor, etc.
  3. Style object handling: Recognizes and correctly processes style objects
  4. Event handling: Identifies and converts event attributes (@clickonClick)

Boolean attribute binding

Vue has special handling for boolean attributes, and VuReact preserves this semantics.

  • Vue
<button :disabled="isLoading">Submit</button>
<input :checked="isChecked" />
<option :selected="isSelected">Option</option>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
<button disabled={isLoading}>Submit</button>
<input checked={isChecked} />
<option selected={isSelected}>Option</option>
Enter fullscreen mode Exit fullscreen mode

Dynamic attribute name binding

Vue supports using dynamic expressions as attribute names. While not recommended, VuReact handles it correctly.

  • Vue
<div :[dynamicAttr]="value">Content</div>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
<div {...{ [dynamicAttr]: value }}>Content</div>
Enter fullscreen mode Exit fullscreen mode

Compilation strategy:

  1. Computed property name: Uses the object computed property syntax { [key]: value }
  2. Object spread: Applies to the element via the object spread syntax

Compilation strategy summary

VuReact's v-bind compilation strategy demonstrates a complete attribute binding conversion capability:

  1. Basic attribute mapping: Precisely maps Vue attribute bindings to React JSX attributes
  2. Complex style handling: Supports complex class and style bindings through runtime helper functions
  3. Object spread support: Fully supports parameterless v-bind object spread semantics
  4. Boolean attribute handling: Correctly handles the special behavior of boolean attributes
  5. Dynamic attribute names: Supports dynamic expressions as attribute names
  6. Component props conversion: Correctly handles props passing between components

Performance optimization strategy:

  1. On-demand imports: The dir helper is only imported when complex bindings are used
  2. Cache optimization: Intelligently caches the processing results of identical expressions
  3. Compile-time optimization: For simple expressions, generates inline logic directly

VuReact's compilation strategy ensures a smooth migration from Vue to React. Developers do not need to manually rewrite attribute binding logic. The compiled code preserves Vue's semantics and functionality while following React's attribute handling best practices, keeping the migrated application fully capable of UI presentation.

Related Links

Top comments (0)