vue-cli todolist_前端


vue-cli todolist_ci_02

文件结构

vue-cli todolist_ci_03


代码仓库

​https://gitee.com/honbingitee/vue-todolist​

app.vue

<template>
<div id="app">
<ToDoList></ToDoList>
</div>
</template>

<script>
import ToDoList from "./components/ToDoList/index.vue";

export default {
name: "App",
components: {
ToDoList,
},
};
</script>

<style>
#app {
display: flex;
}
</style>

components/ToDoList/index.vue

<template>
<div class="container">
<h1>ToDoList</h1>
<div class="flexbox">
<input v-model="title" type="text" />
<button class="addBtn" @click="addToDoItem">添加</button>
</div>
<List :list="list" />
<button class="clearDataButton" @click="clearData">清除数据</button>
</div>
</template>

<script>
import List from "./List.vue";

export default {
data: () => {
return {
title: "",
list: [
{ title: "取快递", complete: true },
{ title: "完成辉光效果", complete: false },
],
};
},
/**
* 进入页面获取上次的本地数据
*/
mounted: function () {
this.syncLocalStorage();
},
methods: {
delItem: function () {},
/**
* 添加todo list
*/
addToDoItem: function () {
const item = {
title: this.title,
complete: false,
};
this.list.push(item);
this.saveLocalStorage();
this.clearInput();
},
/**
* 清除输入
*/
clearInput: function () {
this.title = "";
},
/**
* 将当前的列表保存本地
*/
saveLocalStorage: function () {
localStorage.setItem("todolist", JSON.stringify(this.list));
},
/**
* 从本地获取以前的todo list 数据
*/
syncLocalStorage: function () {
const localJSON = localStorage.getItem("todolist");
const payloadData = JSON.parse(localJSON || "[]");
this.list = payloadData;
},
/**
* 清除数据
*/
clearData: function () {
this.list = [];
this.saveLocalStorage();
},
},
components: {
List,
},
};
</script>

<style scoped>
.container {
background: rgb(184 174 135);
width: 40vw;
min-height: 20vh;
max-height: 80vh;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 1vw;
padding-bottom: 6vh;
border-radius: 1vw;
font-family: "Lucida Sans", "Lucida Sans Regular", "Lucida Grande",
"Lucida Sans Unicode", Geneva, Verdana, sans-serif;
display: flex;
flex-direction: column;
transition: all 0.3s ease;
}
h1 {
color: #fffae5;
font-size: 5vmax;
}
.flexbox {
display: flex;
}
input[type="text"] {
border: none;
background: #fffae5;
padding: 0.5vmin 0.5vmax;
border-radius: 1vmin;
margin-right: 1vmin;
outline: none;
color: #7f775c;
width: 70%;
}
button {
border: none;
background: #fffae5;
padding: 1vmin 1vmax;
border-radius: 1vmin;
font-size: 0.7vmin;
color: #7f775c;
}
.addBtn {
width: 10vmax;
font-size: 1rem;
font-weight: bold;
}
.clearDataButton {
position: absolute;
bottom: 1vw;
right: 1vw;
padding: 0.5vmin 0.5vmax;
}
@media screen and (max-width: 750px) {
.container {
width: 86vw;
}
}
</style>

components/ToDoList/List.vue

<template>
<div>
<div v-for="item in list" :key="item.title">
<Item :item="item" />
</div>
</div>
</template>

<script>
import Item from "./Item.vue";

export default {
props: {
list: Array,
delItem: Function,
},
components: { Item },
};
</script>

<style>
</style>

components/ToDoList/Item.vue

<template>
<div class="wrap">
<input type="checkbox" :checked="item.complete" />
<span>{{ item.title }}</span>
<span class="delBtn">删除</span>
</div>
</template>

<script>
export default {
props: {
item: Object,
},
methods: {
delItem: function () {
this.$emit("delItem", this.item.title);
},
},
};
</script>

<style scoped>
.wrap {
display: flex;
padding: 1vmin;
border-bottom: 1px solid #fffae577;
cursor: default;
transition: all 0.3s linear;
margin-top: 1vmin;
position: relative;
overflow: hidden;
align-items: center;
}
.wrap:hover {
background: #6b664e94;
}
.wrap input[type="checkbox"] {
background: #fffae5;
margin-right: 1vmax;
border: none;
}
.wrap span {
color: #fffae5;
}
.wrap:hover .delBtn {
visibility: visible;
opacity: 1;
transform: translate(0);
}
.delBtn {
transform: translate(10vmin);
opacity: 0;
visibility: hidden;
position: absolute;
right: 1vmin;
font-size: 1.5vmax;
cursor: pointer;
transition: all 0.3s 0.3s linear;
}
.delBtn:hover {
color: rgb(240, 133, 133);
letter-spacing: 3px;
font-size: 2vmax;
}
</style>