Alex Riviere - https://alex.party
Senior Web Developer
Nexcor Technologies
@fimion@notacult.social
... because React is popular.
Photo by Kyle Glenn on Unsplash
Photo by Icons8 Team on Unsplash
babel-plugin-transform-vue-jsx
Released June 16th, 2016
import { useState } from 'react'
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
function App() {
const [todos, updateTodos] = useState([]);
const [showArchived, updateShowArchived] = useState(false);
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
}
export default App
App.jsx - React Version
import { useState } from 'react'
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
function App() {
const [todos, updateTodos] = useState([]);
const [showArchived, updateShowArchived] = useState(false);
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
}
export default App
App.jsx - Update Imports
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
function App() {
const [todos, updateTodos] = useState([]);
const [showArchived, updateShowArchived] = useState(false);
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
}
export default App
App.jsx - Update Imports
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
function App() {
const [todos, updateTodos] = useState([]);
const [showArchived, updateShowArchived] = useState(false);
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
}
export default App
App.jsx - Update Definition
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const [todos, updateTodos] = useState([]);
const [showArchived, updateShowArchived] = useState(false);
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update Definition
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const [todos, updateTodos] = useState([]);
const [showArchived, updateShowArchived] = useState(false);
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - New State Mechanics
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - New State Mechanics
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - create a computed value
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update to use array methods
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update to use array methods
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update marking todo as done
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update marking todo as done
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Return a Render Function
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return ()=>(
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Return a Render Function
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return ()=>(
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update to ref.value
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return ()=>(
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>showArchived.value = !showArchived.value)}
checked={showArchived.value} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update to ref.value
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return ()=>(
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived.value)}
checked={showArchived.value} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update to ref.value
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return ()=>(
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived.value)}
checked={showArchived.value} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived.value)
.map((todo, index) => (<li key={todo.id}>
{!showArchived.value && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update to ref.value
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return ()=>(
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived.value)}
checked={showArchived.value} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived.value)
.map((todo, index) => (<li key={todo.id}>
{!showArchived.value && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update to use a computed value
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return ()=>(
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived.value)}
checked={showArchived.value} />
Show Finished
</label>
<ul>
{filteredTodos.value.map((todo, index) => (<li key={todo.id}>
{!showArchived.value && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Update to use a computed value
<script>
import {ref, reactive, defineComponent, computed} from "vue"
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent({
setup() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>{
return todos.filter((e)=>e.done===showArchived.value);
})
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return {
todos,
showArchived,
addTodo,
markDone,
handleSubmit,
filteredTodos,
}
}
});
export default App
</script>
<template>
<div class="App">
<header class="App-header">
<h1>My Todo List</h1>
</header>
<form @submit="handleSubmit" class="add-item">
<label for="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type="checkbox"
v-model="showArchived">
Show Finished</label>
<ul>
<li v-for="todo in filteredTodos" :key="todo.id">
<button v-if="!showArchived" @click="markDone(todo)">
<span aria-hidden="true">✔</span>
<span class="sr-only">Mark Done</span>
</button>
{{todo.id}} - {{todo.item}}
</li>
</ul>
</div>
</template>
<style scoped src="./App.css" />
App.vue - Vue Single File Component
Nerando Johnson - Cassidy Williams
import { useState } from 'react'
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
function App() {
const [todos, updateTodos] = useState([]);
const [showArchived, updateShowArchived] = useState(false);
const addTodo = (item) => {
const myTodo = newTodo(item);
updateTodos([...todos, myTodo]);
}
const markDone = (todo)=>{
todo.done = true;
const index = todos.indexOf(todo);
todos[index] = { ...todo };
updateTodos([...todos]);
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return (
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived)}
checked={showArchived} />
Show Finished
</label>
<ul>
{todos.filter((e)=>e.done===showArchived)
.map((todo, index) => (<li key={todo.id}>
{!showArchived && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
}
export default App
App.jsx - React Version
/** @jsx h */
import {h, defineComponent, ref, reactive, computed} from "vue"
import './App.css'
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent(function() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>todos.filter((e)=>e.done===showArchived.value))
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return ()=>(
<div className="App">
<header className="App-header">
<h1>My Todo List</h1>
</header>
<form onSubmit={handleSubmit} className="add-item">
<label htmlFor="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type={'checkbox'}
onChange={()=>updateShowArchived(!showArchived.value)}
checked={showArchived.value} />
Show Finished
</label>
<ul>
{filteredTodos.map((todo, index) => (<li key={todo.id}>
{!showArchived.value && (<button onClick={()=>markDone(todo)}>
<span aria-hidden="true">✔</span>
<span className="sr-only">Mark Done</span>
</button>)} {todo.id} - {todo.item}
</li>))}
</ul>
</div>
)
})
export default App
App.jsx - Vue Version
<script>
import {ref, reactive, defineComponent, computed} from "vue"
let todoCount = 0;
const newTodo = (item) => ({id:++todoCount, done:false, item });
const App = defineComponent({
setup() {
const todos = reactive([]);
const showArchived = ref(false);
const filteredTodos = computed(()=>{
return todos.filter((e)=>e.done===showArchived.value);
})
const addTodo = (item) => {
const myTodo = newTodo(item);
todos.push(myTodo);
}
const markDone = (todo)=>{
todo.done = true;
}
const handleSubmit = (e) => {
e.preventDefault();
const formStuff = new FormData(e.target);
addTodo(formStuff.get('item'));
e.target.reset();
}
return {
todos,
showArchived,
addTodo,
markDone,
handleSubmit,
filteredTodos,
}
}
});
export default App
</script>
<template>
<div class="App">
<header class="App-header">
<h1>My Todo List</h1>
</header>
<form @submit="handleSubmit" class="add-item">
<label for="item">New Todo</label>
<input type="text" name="item" id="item" />
<button>ADD!</button>
</form>
<label>
<input type="checkbox"
@change="showArchived = !showArchived"
:checked="showArchived">
Show Finished</label>
<ul>
<li v-for="todo in filteredTodos" :key="todo.id">
<button v-if="!showArchived" @click="markDone(todo)">
<span aria-hidden="true">✔</span>
<span class="sr-only">Mark Done</span>
</button>
{{todo.id}} - {{todo.item}}
</li>
</ul>
</div>
</template>
<style scoped src="./App.css" />
App.vue - Vue Single File Component