<template>
<div>
<ul>
<li v-for="todoItem in todoItems" v-bind:key="todoItem">
{{ todoItem }}</li>
</ul>
</div>
</template>
<script>
export default {
data: function() {
return {
todoItems : []
}
},
created: function() { //뷰의 라이프 사이클과 관련된 속성. 인스턴스가 생성되자마자 호출되는 라이프사이클 훅.
if(localStorage.length > 0) {
for(var i= 0; i<localStorage.length; i++) {
if(localStorage.key(i) !== 'loglevel:webpack-dev-server') {
this.todoItems.push(localStorage.key(i));
}
}
}
}
}
</script>
<ul>
<li v-for="todoItem in todoItems" v-bind:key="todoItem">
{{ todoItem }}</li>
</ul>
👇
<ul>
<li v-for="(todoItem, index) in todoItems" v-bind:key="todoItem" class="shadow">
{{ todoItem }}
<span class="removeBtn" v-on:click="removeTodo(todoItem, index)">
<i class="fas fa-solid fa-trash"></i>
</span>
</li>
</ul>
splice
: 지우고 새로운 배열을 반환slice
: 지우고 변경하지 않고 기존 배열을 반환<template>
<div>
<ul>
<li v-for="(todoItem, index) in todoItems" v-bind:key="todoItem" class="shadow">
{{ todoItem }}
<span class="removeBtn" v-on:click="removeTodo(todoItem, index)">
<i class="fas fa-solid fa-trash"></i>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
data: function() {
return {
todoItems : []
}
},
created: function() { //뷰의 라이프 사이클과 관련된 속성. 인스턴스가 생성되자마자 호출되는 라이프사이클 훅.
if(localStorage.length > 0) {
for(var i= 0; i<localStorage.length; i++) {
if(localStorage.key(i) !== 'loglevel:webpack-dev-server') {
this.todoItems.push(localStorage.key(i));
}
}
}
},
methods : {
removeTodo : function(todoItem, index) {
console.log(todoItem, index);
localStorage.removeItem(todoItem);
this.todoItems.splice(index,1);
}
}
}
</script>
❓ 좀 이해가 안간다...todoItems[]에서 지우면 새로고침 없이 바로 화면에 자동연동된다니...서버랑 통신도 안했는데? 그게 vue의 reactivity 성질인가......!!!!
addTodo : function() {
if(this.newTodoItem !== '') {
var obj = {completed : false, item : this.newTodoItem }; //이 아이템이 check됐는지아닌지.
localStorage.setItem(this.newTodoItem, JSON.stringify(obj)); //객체를 String으로 변환하는 API
//localStorage.setItem(this.newTodoItem, obj);
this.clearInput();
}
}
<template>
<header>
<h1>TODO it!</h1>
</header>
</template>
<script>
export default {
}
</script>
<style scoped> /*이 곳에서만 적용되는 style : scoped*/
h1 {
color: #2F3B52;
font-weight:900;
margin: 2.5rem 0 1.5rem;
}
</style>
<template>
<div>
<ul>
<li v-for="(todoItem, index) in todoItems" v-bind:key="todoItem.item" class="shadow">
<i class="checkBtn fas fa-solid fa-check" v-on:click="toggleComplete(todoItem, index)"></i>
<span v-bind:class="{textCompleted: todoItem.completed}"> {{ todoItem.item }} </span>
<span class="removeBtn" v-on:click="removeTodo(todoItem, index)">
<i class="fas fa-solid fa-trash"></i>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
data: function() {
return {
todoItems : []
}
},
created: function() { //뷰의 라이프 사이클과 관련된 속성. 인스턴스가 생성되자마자 호출되는 라이프사이클 훅.
if(localStorage.length > 0) {
for(var i= 0; i<localStorage.length; i++) {
if(localStorage.key(i) !== 'loglevel:webpack-dev-server') {
this.todoItems.push(JSON.parse(localStorage.getItem(localStorage.key(i))));
}
}
}
},
methods : {
removeTodo : function(todoItem, index) {
console.log(todoItem, index);
localStorage.removeItem(todoItem);
this.todoItems.splice(index,1);
},
toggleComplete : function(todoItem, index) {
todoItem.completed = !todoItem.completed;
localStorage.removeItem(todoItem.item);
localStorage.setItem(todoItem.item, JSON.stringify(todoItem));
}
}
}
</script>
<style scoped>
ul {
list-style-type: none;
padding-left:0px;
margin-top: 0;
text-align: left;
}
li {
display: flex;
min-height: 50px;
height:50px;
line-height: 50px;
margin: 0.5rem 0;
padding: 0 0.0rem;
background: white;
border-radius: 5px;
}
.checkBtn {
line-height: 45px;
color:#62acde;
margin-right: 5px;
}
.checkBtnCompleted{
color: #b3adad;
}
.textCompleted{
text-decoration: line-through;
color: #b3adad;
}
.removeBtn{
margin-left: auto;
color: #de4343;
}
</style>
<template>
<div class="inputBox shadow">
<input type="text" v-model="newTodoItem" v-on:keyup.enter="addTodo">
<!-- <button v-on:click="addTodo">등록</button> -->
<span class="addContainer" v-on:click="addTodo">
<i class="fas fa-solid fa-plus addBtn"></i>
</span>
</div>
</template>
<script>
export default {
data : function() {
return {
newTodoItem : ""
}
},
methods: {
addTodo : function() {
if(this.newTodoItem !== '') {
var obj = {completed : false, item : this.newTodoItem }; //이 아이템이 check됐는지아닌지.
//객체를 String으로 변환하는 API
localStorage.setItem(this.newTodoItem, JSON.stringify(obj));
//localStorage.setItem(this.newTodoItem, obj);
this.clearInput();
}
},
clearInput : function() {
this.newTodoItem='';
}
}
}
</script>
<style scoped>
input :focus {
outline: none;
}
.inputBox {
background:white;
height: 50px;
line-height: 50px;
border-radius:5px;
}
.inputBox input{
border-style: none;
font-size: 0.9rem;
}
.addContainer {
float: right;
background: linear-gradient(to right, #6478FB, #8763FB);
display: block;
width: 3rem;
border-radius: 0 5px 5px 0;
}
.addBtn {
color: white;
vertical-align: middle;
}
</style>
<template>
<div class="clearAllContainer">
<span class="clearAllBtn" v-on:click="clearTodo">Clear All</span>
</div>
</template>
<script>
export default {
methods : {
clearTodo : function() {
localStorage.clear();
}
}
}
</script>
<style scoped>
.clearAllContainer {
width: 8.5rem;
height: 50px;
line-height: 50px;
background-color:white;
border-radius: 5px;
margin: 0 auto;
}
.clearAllBtn {
color: #e20303;
display: block;
}
</style>
<template>
<div id="app">
<TodoHeader></TodoHeader>
<TodoInput></TodoInput>
<TodoList></TodoList>
<TodoFooter></TodoFooter>
</div>
</template>
<script>
import TodoHeader from './components/TodoHeader.vue';
import TodoInput from './components/TodoInput.vue';
import TodoList from './components/TodoList.vue';
import TodoFooter from './components/TodoFooter.vue';
export default {
components: {
'TodoHeader': TodoHeader,
'TodoInput': TodoInput,
'TodoList': TodoList,
'TodoFooter': TodoFooter,
}
}
</script>
<style>
body{
text-align: center;
background-color:#F6F6F6;
}
input {
border-style: groove;
width: 200px;
}
button {
border-style: groove;
}
.shadow {
box-shadow: 5px 10px 10px rgba(0,0,0,0.03);
}
</style>
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})