LoginSignup
4
6

More than 5 years have passed since last update.

aurelia のチュートリアルを実装しつつ他のフレームワークと比較してみた

Posted at

motivation

  • aurelia のチュートリアルを実装してみる
  • 同じものを他のフレームワークで実装してみる
  • なんとなくそれぞれの雰囲気を感じ取り、比較した気分に浸る

* 雰囲気を掴むだけなので深くはみない。実装も割と雑。

frameworks

* 他のフレームワークも試してみたら適宜追加していく。

todo app

なんでこの手のチュートリアルはTODOアプリなんだろうと思いつつ。

(フォーム・リスト・アイテムとコンポーネントの分割、各種アクションと基本的なものが学べるイイ教材?)

todo class

todo.js
export default class Todo {
  constructor(description) {
    this.description = description;
    this.done = false;
  }
}

タスクの概要と、進捗を要素として持つ。

case aurelia

app.html
<template>
  <h1>${heading}</h1>

  <form submit.trigger="addTodo()">
    <input type="text" value.bind="todoDescription">
    <button type="submit">Add Todo</button>
  </form>

  <ul>
    <li repeat.for="todo of todos">
      <input type="checkbox" checked.bind="todo.done">
      <span css="text-decoration: ${todo.done ? 'line-through' : 'none'}">
        ${todo.description}
      </span>
      <button click.trigger="removeTodo(todo)">Remove</button>
    </li>
  </ul>
</template>
app.js
import Todo from './Todo';

export class App {
  constructor() {
    this.heading = 'Todos';
    this.todos = [];
    this.todoDescription = '';
  }

  addTodo() {
    if (this.todoDescription) {
      this.todos.push(new Todo(this.todoDescription));
      this.todoDescription = '';
    }
  }

  removeTodo(todo) {
    let index = this.todos.indexOf(todo);
    if (index !== -1) {
      this.todos.splice(index, 1);
    }
  }
}

少ないコードでスッキリ書ける。

case vue

App.vue
<template>
  <div>
    <h1>{{heading}}</h1>

    <form v-on:submit.prevent="addTodo()">
      <input type="text" v-model="todoDescription">
      <button type="submit">Add Todo</button>
    </form>

    <ul>
      <li v-for="todo of todos">
        <input type="checkbox" v-model="todo.done">
        <span v-bind:class="[todo.done ? 'done' : '']">
          {{todo.description}}
        </span>
        <button v-on:click="removeTodo(todo)">Remove</button>
      </li>
    </ul>
  </div>
</template>

<script>
import Todo from './todo';

export default {
  name: 'App',
  data() {
    return {
      heading: 'Todos',
      todoDescription: '',
      todos: [],
    };
  },
  methods: {
    addTodo() {
      if (this.todoDescription) {
        this.todos.push(new Todo(this.todoDescription));
        this.todoDescription = '';
      }
    },
    removeTodo(todo) {
      const index = this.todos.indexOf(todo);
      if (index !== -1) {
        this.todos.splice(index, 1);
      }
    },
  },
};
</script>

<style>
  .done {
    text-decoration: line-through;
  }
</style>

Vue.js のシンタックスはちょっと苦手。

case react

App.js
import React, { Component } from 'react';
import update from 'immutability-helper';
import Todo from './todo';

class App extends Component {
  constructor() {
    super();
    this.state = {
      heading: 'Todos',
      todos: [],
      todoDescription: ''
    }
  }

  onInput(e) {
    this.setState({ todoDescription: e.currentTarget.value });
  }

  addTodo(e) {
    e.preventDefault();
    if (this.state.todoDescription) {
      this.setState({
        todos: update(this.state.todos, {$push: [new Todo(this.state.todoDescription)]}),
        todoDescription: ''
      });
    }
  }

  removeTodo(todo) {
    const index = this.state.todos.indexOf(todo);
    if (index !== -1) {
      const prevTodos = this.state.todos;
      const nextTodos = update(prevTodos, {$splice: [[index, 1]]});
      this.setState({
        todos: nextTodos
      });
    }
  }

  render() {
    const todos = this.state.todos.map((todo, i) => (
      <li>
        <input type="checkbox" checked={todo.done}
          onChange={
            () => {
              this.setState({
                todos: update(this.state.todos, {[i]: {done: {$set: !todo.done}}})
              });
            }
          }/>
        <span style={todo.done ? { textDecoration: 'line-through' } : {} }>
          {todo.description}
        </span>
        <button onClick={() => this.removeTodo(todo)}>Remove</button>
      </li>
    ));

    return (
      <div>
        <h1>{this.state.heading}</h1>
        <form onSubmit={e => this.addTodo(e)}>
          <input type="text" onChange={e => this.onInput(e)} value={this.state.todoDescription}/>
          <button type="submit">Add Todo</button>
        </form>
        <ul>
          {todos}
        </ul>
      </div>
    );
  }
}

export default App;

コード量は多いけど、スクリプトだけで書けるのは良い。

summary

見出しに英語を使うと、ちょっと出来てる感が醸し出せる。

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6