Git Product home page Git Product logo

javascript-framework-comparison's Introduction

JavaScript Framework Comparison

This is a completely unfair comparison of components in Angular, Ember, React, and Vue.

It's unfair because the component is trivial: all it does is allow text to be entered and provide a button to reverse the text. The goal was not in any way to represent a real production component, but instead to allow comparison of some simple aspects of components:

  • How the component class is declared
  • How the component class is entered at the point of use, including passing data into it
  • How its template is set up, including how the dynamic data is outputted and how a button is bound to an action
  • How the action updates the data in the component

Primary

Angular

Cloned from quickstart

To run:

cd angular-component
npm install
npm start

The component: message-reverser.component.ts

Using it:

<message-reverser [message]="'Hello, Angular!'"></message-reverser>

Its declaration:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'message-reverser',
  template: `
    <div>
      <input [(ngModel)]="message"/>
      <button (click)="reverse()">Reverse Message</button>
    </div>
  `
})
export class MessageReverserComponent {
  @Input() message: string;

  reverse(): void {
    this.message = this.message.split('').reverse().join('');
  }
}

Observations:

  • Verbose TypeScript syntax with annotations
  • Wiring up imports is verbose as well
  • Actual mutation is a simple method declaration and implementation

Ember

Created by ember-cli

To run:

npm install -g ember-cli
cd ember-component
npm install
ember serve

The component: message-reverser.js and message-reverser.hbs

Observations:

  • Accepts any props; no distinction between props and state
  • All you had to implement was template markup and action behavior
  • Separation of template and class in different directories is challenging
  • Strange getter/setter syntax
  • Usage of components doesn't look like HTML

Usage:

{{message-reverser message="Hello, Ember!"}}

Definition:

import Ember from 'ember';

export default Ember.Component.extend({
  actions: {
    reverse() {
      let message = this.get('message');
      this.set('message', message.split('').reverse().join(''));
    }
  }
});
<div>
  {{input value=message}}
  <button {{action 'reverse'}}>Reverse Message</button>
</div>

React

Created by create-react-app

To run:

cd react-component
npm install
npm start

The component: Reverser.js

Usage:

<Reverser message="Hello, React!" />
import React, { Component } from 'react';

export default class Reverser extends Component {
  constructor(props) {
    super(props);
    this.state = { message: props.message };
  }

  render() {
    let { message } = this.state;
    return <div>
      <input type="text" value={message} onChange={(e) => this.handleChange(e)} />
      <button onClick={() => this.reverse()}>Reverse Message</button>
    </div>
  }

  handleChange(event) {
    this.setState({ message: event.target.value });
  }

  reverse() {
    let { message } = this.state;
    this.setState({
      message: message.split('').reverse().join(''),
    });
  }
}

Observations:

  • Simple ES6 classes
  • Reading data from an input was nontrivial
  • Updating state via setState()

Vue

To run: just open vuejs.html in a browser.

The component: Vue.component('reverser') in vuejs.html

Usage:

<reverser message="Hello, Vue.js!"/>

Definition:

Vue.component('reverser', {
  props: ['message'],
  data() {
    return {
      mutableMessage: this.message
    }
  },
  methods: {
    reverseMessage() {
      this.mutableMessage = this.mutableMessage.split('').reverse().join('')
    }
  },
  template: `
    <div>
      <input v-model="mutableMessage">
      <button v-on:click="reverseMessage">Reverse Message</button>
    </div>
  `
});

Observations:

  • Works in a single-page HTML file
  • Directives are a little verbose
  • Can't use the same name for a prop and data item
  • Simple mutation implementation

Secondary

React Functional-Style

To run:

cd react-functional-component
npm install
npm run start

The component: react-functional-component/src/Reverser.js

Usage:

<Reverser message="Hello, React!" />

Definition:

import React from 'react';
import { compose, withState, withHandlers } from 'recompose';

let Reverser = ({ message, onChange, reverse }) =>
  <div>
    <input type="text" value={message} onChange={onChange} />
    <button onClick={reverse}>Reverse Message</button>
  </div>

let onChange = ({ setMessage }) => event => {
  setMessage(event.target.value);
};

let reverse = ({ message, setMessage }) => () => {
  setMessage(message.split('').reverse().join(''));
};

let enhance = compose(
  withState('message', 'setMessage', ({ message }) => message),
  withHandlers({ onChange, reverse })
);

export default enhance(Reverser);

Vue Single-File Components

To run:

cd vue-single-file-component
npm install
npm run dev

The component: vue-single-file-component/src/Reverser.vue

Usage:

<reverser message="Hello, Vue.js!" />

Definition:

<template>
  <div>
    <input v-model="mutableMessage">
    <button v-on:click="reverseMessage">Reverse Message</button>
  </div>
</template>

<script>
  export default {
    name: 'reverser',
    props: ['message'],
    data() {
      return {
        mutableMessage: this.message
      }
    },
    methods: {
      reverseMessage() {
        this.mutableMessage = this.mutableMessage.split('').reverse().join('')
      }
    }
  }
</script>

javascript-framework-comparison's People

Watchers

 avatar  avatar

javascript-framework-comparison's Issues

Add FP version of React component

Using Recompose.

Pros:

  • Functional approach makes it easy to extract reusable traits and behaviors
  • Each function can be tested in isolation without mocking/setup
  • Slightly fewer LOC
  • Composition over inheritence
  • Easier to adapt for server-side rendering
  • Easier debugging and inspection

Cons:

  • Higher learning curve without an FP background
  • Deeper nesting in React elements panel
import React from 'react';
import { compose, withState, withHandlers } from 'recompose';

let Reverser = ({ message, onChange, reverse }) =>
  <div>
    <input type="text" value={message} onChange={onChange} />
    <button onClick={reverse}>Reverse Message</button>
  </div>

let onChange = ({ setMessage }) => event => {
  setMessage(event.target.value);
};

let reverse = ({ message, setMessage }) => () => {
  setMessage(message.split('').reverse().join(''));
};

let enhance = compose(
  withState('message', 'setMessage', ({ message }) => message),
  withHandlers({ onChange, reverse })
);

export default enhance(Reverser);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.