Dreaming of Code

Vue.js vs React.js

May 03, 2016

I recently published two posts, one was a tutorial for using Vue.js and Rails, and the other about using React.js and Rails. Evan You has published a good post that compares the higher level concepts of various JavaScript frameworks including React. With the announcement of Vue.js 2.0, this will put Vue.js on par with React in terms of Virtual-DOM and Server side rendering. I would like to compare the two frameworks from a development perspective with a few simple how-tos for each framework. Let's get started!

I would like to provide examples for the following common tasks when building a feature rich web application including Iterations, Props in Components, Two Way Binding, and Conditional rendering.

Iterating the React Way

// React.js  (.jsx)

const array = [1, 2, 3, 4];
const Iteration = ({ items }) => <div> {items.map(item => <span>{item}</span>)} </div>;

ReactDOM.render(<Iteration items={array}/>, document.getElementById('array'));
<!-- React.js (html) -->

<div id="array"></div>

Iterating the Vue Way

// Vue.js (js)

var Iteration = new Vue({
  el: '#array',
  data: {
    array: [1,2,3,4]
  }
});
<!-- Vue.js (html) -->

<div id="array">
  <span v-for="value in array">{{value}}</span>
</div>

Iteration Winner: Vue.js

You can see that Vue.js takes up just a few lines of code and I believe that it feels really intuitive compared to looking at the React code. I also like how initializing a Vue instance just takes a plain Javascipt object as the data, where as with React, we need to us the getInitialState() function and return the state data that way.

Props

For this next comparison, we will imagine that we are initializing an example similar to above, except our array is an array of Objects and we are looping through a passing each object as a prop into a component.

For example:

[
  {
    id: 1,
    title: Foo
  },
  {
    id: 2,
    title: Bar
  }

  //...
]

Props and Components the React Way

// React.js (jsx)

const Component = ({ object }) => <span>{object.title}</span>

// Rendering the Component with the Prop
    // ...

    this.state.array.map( object => <Component key={object.id} object={object} />

    // ...

Props and Components the Vue Way

// Vue.js (js)

var Component = Vue.component('component', {
  template: '<span>{{object.title}}</span>',
  props: {
    object: Object
  }
});
<!-- Vue.js (html) -->

<component
  v-for="object in array"
  track-by="id"
  :object="object">
</component>

Props and Components Winner: Tie

I feel as though creating a component in Vue seems a little more intuitive but goes back to my previous comparison of initializing with a plain object as opposed to the getInitialState. The actual rendering of the components is almost equivalent when you compare the React way <Component key="... /> vs the Vue way <component v-for=".... One note is that React throws a warning when you don't pass in a key. Vue does not require this, but can be accomplished using track-by or defining the prop as object: {type: Object, required: true}.

Two-Way Binding

In my opinion, the main reason for using any of the popular Javascript Libraries is to take advantage of Two-Way binding. The simplest example is inserting some text into a text box an have the text appear as you are typing it.

Two-Way Binding the React Way

// React.js (jsx)

var Message = React.createClass({
  getInitialState() {
    return {
      message: ''
    }
  },

  handleMessageChange(e) {
    this.setState({message: e.target.value});
  },

  render() {
    return (
      <div>
        <input type="text" onChange={this.handleMessageChange} />
        <span>{this.state.message}</span>
      </div>
    )
  }
});


Two-Way Binding the Vue Way

// Vue.js (js)

var Message = new Vue({
  el: '#message',
  data: {
    message: ''
  }
});
<div id="message">
  <input type="text" v-model="message" />
  <span>{{message}}</span>
</div>

Two-Way Binding Winner: Vue.js

This is where I think Vue.js takes the cake. Two-Way Binding for Vue.js is as simple as adding a v-model attribute to and input tag and Vue takes care of it for you. In React you have to define a function and call setState to apply the changes.

Conditional Rendering

Let's say you want to conditionally render some html based on the current state. One example might be if a user is not logged into the site, then display the login form, otherwise display the appropriate markup. We'll assume that we have a state variable called loggedIn which is a boolean value. We'll also assume that we have two components defined, one for the LoginForm and another General Component that can be viewed after a user is authenticated.

Conditional Rendering the React Way

// React.js (jsx)

  render() {
    if ( this.state.loggedIn ) {
      return( <Component /> );
    } else {
      return( <LoginForm /> );
    }
  }


Conditional Rendering the Vue Way

<!-- Vue.js (html) -->

<component v-if="loggedIn"></component>
<login-form v-else></login-form>

Conditional Rendering Winner: Tie

I feel as though Vue.js is simpler to use the v-if and v-else attributes when you are using a simple booolean to determine whether or not you render something, but to do something more complicated, then it requires you to separate some logic out into a JavaScript function. With React, you can see the logic more clearly because everything is in one place.

Conclusion

We covered just the tip of the iceberg, but in conclusion I believe that Vue.js is much easier to work with than React from a development perspective and I'm sure there are others in the community who could provide more insight into other functionality of the two frameworks, but for now, this is where I leave you.