Vue
by Alexandru Gatea
HTML
<div id="todo-list">
<form class="add-todo card" v-on:submit.prevent="addNewTodo">
<label for="new-todo">Add a todo</label>
<input v-model="newTodoText" id="new-todo" placeholder="E.g. Feed the cat" autocomplete="off" autocorrect="off">
<button>Add</button>
</form>
<ul class="todo-list">
<li
class="card"
is="todo-item"
v-for="todo in todos"
v-bind:title="todo.title"
v-bind:url="todo.url"
v-on:remove="todos.splice(index, 1)">
</li>
</ul>
</div>
SCSS
//fonts and variables
@import url('https://fonts.googleapis.com/css?family=Titillium+Web:300,400,700');
$font: 'Titillium Web', sans-serif;
$color: #ff3355;
* {
box-sizing: border-box;
}
body {
background: transparent;
font-family: $font;
}
.card {
background: #fff;
display: block;
padding: 20px;
margin-bottom: 5px;
border-radius: 5px;
}
.add-todo {
background: $color;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
text-align: center;
margin-bottom: 20px;
label {
display: block;
width: 100%;
font-size: 2em;
line-height: 1;
text-transform: uppercase;
font-weight: bold;
color: #fff;
margin-bottom: 15px;
margin-top: 0;
}
input {
min-height: 50px;
border-radius: 50px;
border: 5px solid #fff;
min-width: 300px;
padding: 0 75px 0 25px;
outline: none;
}
button {
width: 80px;
height: 40px;
margin-top: 30px;
margin-left: -60px;
line-height: 40px;
border-radius: 40px;
color: #fff;
background: #20262e;
border: none;
outline: none;
cursor: pointer;
box-shadow: -2px -2px 0px 4px $color;
}
}
.todo-list {
display: block;
max-width: 80%;
margin: auto;
li {
position: relative;
transition: all 0.3s ease;
top:0;
display: flex;
align-items: center;
min-height: 64px;
padding-left: 60px;
img {
width: 40px;
height: 40px;
object-fit: cover;
margin-left: -40px;
margin-right: 20px;
}
}
button {
position: absolute;
top:0;
right: 0;
padding: 20px;
height: 100%;
display: block;
background: transparent;
outline: none;
border: none;
...
Vue
Vue.component('todo-item', {
template: '\
<li>\
<img src="https://picsum.photos/200/300/?random">\
{{ title }}\
<button v-on:click="$emit(\'remove\')">×</button>\
</li>\
',
props: ['title']
})
new Vue({
el: '#todo-list',
data: {
todos: [
{
title: 'Do the dishes'
},
{
title: 'do this'
},
{
title: 'that also'
}
]
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText
})
this.newTodoText = ''
}
}
})