This repository contains a sample todo list application built three times using Angular.js (v12), React.js (v17), and Vue.js (v2). Each app uses the same CSS styles and HTML markup, and saves the data to localStorage.
Details | |
---|---|
JavaScript & HTML | 98 lines |
Total packages | 1308 packages |
Project install time | 21s |
Project build time | 30s |
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
todos: Array<any> = [];
input: String = '';
ngOnInit() {
const storedData = localStorage.getItem('todos');
this.todos = JSON.parse(storedData as string) || []
}
addItem () {
const newItem = {
description: this.input,
completed: false
};
this.todos.push(newItem)
localStorage.setItem('todos', JSON.stringify(this.todos));
this.input = ''
}
deleteItem(index: number) {
this.todos.splice(index, 1);
localStorage.setItem('todos', JSON.stringify(this.todos));
}
toggleItemStatus(index: number) {
this.todos[index][1] = !this.todos[index][1];
localStorage.setItem('todos', JSON.stringify(this.todos));
}
}
<div class="app">
<div class="app--main">
<img src="/assets/logo.svg" class="app--logo" alt="Logo" />
<form class="app--main--add-item" (ngSubmit)="addItem()">
<label>Add a task</label>
<div>
<input
name="input"
[(ngModel)]="input"
placeholder="So, what's next?"
>
<button
[disabled]="!(input.length>0)"
>
Add
</button>
</div>
</form>
<ul class="app--main--items">
<li
*ngFor="let item of todos; let i = index"
[attr.data-index]="i"
[ngClass]="{ 'completed' : item[1] == true }"
>
<button
(click)="toggleItemStatus(i)"
></button>
<div class="app--main--items-item-text">
{{ item.description }}
</div>
<button
class="delete"
(click)="deleteItem(i)"
×
</button>
</li>
</ul>
</div>
</div>
Details | |
---|---|
JavaScript & HTML | 110 lines |
Total packages | 1996 packages |
Project install time | 26s |
Project build time | 9s |
This example is a class-based component instead of being function-based
import { React, Component, createRef } from 'react';
import logo from './logo.svg';
import './App.scss';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
todos: [],
input: ''
}
this.description = createRef();
this.add = this.add.bind(this);
this.onChange = this.onChange.bind(this);
}
componentDidMount () {
const storedItems = localStorage.getItem('todos');
this.setState({
todos: storedItems ? JSON.parse(storedItems) : []
})
}
add () {
this.props.onButtonClick(this.state.value);
this.setState({ input: '' })
}
onChange (e) {
this.SetState({ input: e.target.value })
}
addItem (event) {
event.preventDefault();
const newItem = {
description: this.description.current.value,
completed: false
};
const list = [...this.state.todos, newItem]
this.setState({
todos: list
})
localStorage.setItem('todos', JSON.stringify(list));
this.setState({
input: ''
})
}
deleteItem(index) {
this.state.todos.splice(index, 1);
const list = [...this.state.todos]
this.setState({
todos: list
})
localStorage.setItem('todos', JSON.stringify(list));
}
toggleItemStatus(index) {
const list = [...this.state.todos]
list[index][1] = !list[index][1];
this.setState({
todos: list
})
localStorage.setItem('todos', JSON.stringify(list));
}
render() {
return (
<div className="app">
<div className="app--main">
<img src={logo} className="app--logo" alt="Logo" />
<form className="app--main--add-item" onSubmit={(e) => this.addItem(e)}>
<label>Add a task</label>
<div>
<input
ref={this.description}
onChange={e => this.setState({ input: e.target.value })}
value={this.state.input}
placeholder="So, what's next?" />
<button
disabled={!this.state.input}
>
Add
</button>
</div>
</form>
<ul className="app--main--items">
{this.state.todos.map((item, index) => (
<li key={index} className={ item[1] ? "completed" : ''}>
<button
onClick={() => this.toggleItemStatus(index)}
>
</button>
<div className="app--main--items-item-text">
{item.description}
</div>
<button
className="delete"
onClick={() => this.deleteItem(index)}
>
×
</button>
</li>
))}
</ul>
</div>
</div>
)
}
}
Details | |
---|---|
JavaScript & HTML | 89 lines |
Total packages | 1337 packages |
Project install tim | 17s |
Project build time | 5s |
This example uses the Options API instead of the Composition API
<template>
<div id="app">
<div class="app--main">
<img src="./logo.svg" class="app--logo" />
<form class="app--main--add-item" @submit.prevent="addItem">
<label>Add a task</label>
<div>
<input v-model="description" placeholder="So, what's next?">
<button
:class="{ 'disabled' : isButtonDisabled() }"
>Add</button>
</div>
</form>
<ul class="app--main--items">
<li
v-for="(item, index) in todos"
:key="index"
:index="index"
ref="item"
:class="{ 'completed' : item.completed }">
<button
@click="toggleItemStatus(index, item.description, item.completed)"
:data-key="item"
:class="{ 'completed' : item.completed }"
></button>
<div class="app--main--items-item-text">
{{ item.description }}
</div>
<button
class="delete"
@click="deleteItem(index)"
:data-key="item"
>×
</button>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data () {
return {
description: '',
todos: []
}
},
methods: {
isButtonDisabled () {
if (this.description == '') {
return true
} else {
return false
}
},
addItem () {
if (this.description != '') {
this.todos.push(
{
description: this.description,
completed: false
}
)
this.description = ''
localStorage.setItem('todos', JSON.stringify(this.todos));
}
},
deleteItem (index) {
this.todos.splice(index, 1)
localStorage.setItem('todos', JSON.stringify(this.todos));
},
toggleItemStatus (index, description) {
this.todos[index]['description'] = description
this.todos[index]['completed'] = !this.todos[index]['completed']
localStorage.setItem('todos', JSON.stringify(this.todos));
}
},
mounted () {
const storedItems = localStorage.getItem('todos')
this.todos = JSON.parse(storedItems)
}
}
</script>