结构
- <template>
- <div id="appContainer">
- <TodoComponent/>
- div>
- template>
-
- <script>
- import TodoComponent from './components/TodoComponent.vue';
- export default {
- name: "App",
- components: {
- TodoComponent
- }
- };
- script>
-
- <style>
- #appContainer{
- display: flex;
- justify-content: center;
- }
- style>
- <template>
- <div id="container">
- <div id="parent">
- <TodoHeader :addTodo="addTodo"/>
- <TodoList :todos="todos" />
- <TodoFooter :finish="finish" :all="all" :clear="clear" :doneAll="doneAll" />
- div>
- div>
- template>
-
- <script>
- import TodoFooter from "./TodoFooter.vue";
- import TodoHeader from "./TodoHeader.vue";
- import TodoList from "./TodoList.vue";
-
- export default {
- name: "TodoComponent",
- components: {
- TodoFooter,
- TodoHeader,
- TodoList,
- },
- data() {
- return {
- todos:[
- {id:'001',title:'吃饭',done:true},
- {id:'002',title:'睡觉',done:false},
- {id:'003',title:'喝酒',done:true},
- {id:'004',title:'开车',done:true},
- {id:'005',title:'打游戏',done:false},
- {id:'006',title:'随便',done:false},
- {id:'007',title:'创业',done:false},
- ]
- }
- },
- methods:{
- addTodo(x){
- console.log("我是Todo组件,我收到了数据",x);
- this.todos.unshift(x);
- },
- clear(){
- console.log('清除了');
-
- const idList = this.todos.filter(x=>x.done).map(x=>x.id);
-
- for(let i=0;i<this.todos.length;i++){
- if(idList.includes(this.todos[i].id)){
- this.todos.splice(i,1);
- i--;
- }
- }
-
- console.log(this.todos);
-
- },
- doneAll(choose){
- this.todos.forEach(x=>x.done=choose)
- }
- },
- computed:{
- finish(){
- return this.todos.filter(x=>x.done).length;
- },
- all(){
- return this.todos.length;
- }
-
- }
- };
- script>
-
- <style scoped>
-
-
- #parent {
- width: 600px;
- border: 1px solid #ccc;
- display: flex;
- justify-content: center; /* 水平居左 */
- align-items: center; /* 垂直居中 */
- flex-direction: column; /* 垂直排列子元素 */
- }
- #parent > *{
- margin: 10px 0px;
- }
-
-
- style>
- <template>
- <div id="container" v-show="all>0">
- <div>
- <input type="checkbox" v-model="allChoose" @change="doneAll(allChoose)"/>
- <label>已完成{{finish}} / 全部{{all}}label>
- div>
- <button id="button" @click="clear">清除已完成的任务button>
- div>
- template>
-
- <script>
- export default {
- name: "TodoFooter",
- data() {
- return {
- allChoose:false
- }
- },
- updated() {
-
- if(this.finish ===this.all && this.all > 0){
- this.allChoose = true;
- }else if(this.finish < this.all && this.all > 0){
- this.allChoose = false;
- }
-
- //双向绑定可以绑定 计算属性 前提是计算属性要写 setter
-
-
- },
- props:['finish','all','clear','doneAll']
- };
- script>
-
- <style scoped>
- #container {
- display: flex;
- justify-content: space-between; /* 水平居左 */
- width: 500px;
- height: 30px;
- padding: 10px;
- }
- #container *{
- padding: 5px;
- }
-
- #button {
- width: 140px;
- height: 28px;
- color: white;
- background-color: #eb1212;
- border: 1px solid #ccc;
- border-radius: 5px;
- padding: 5px;
- margin-right: 15px;
- cursor: pointer; /* 鼠标悬停时显示手型光标 */
- transition: background-color 0.3s ease; /* 平滑过渡 */
- }
-
- #button:hover {
- background-color: #d10d0d; /* 鼠标悬停时颜色变化 */
- }
-
- #button:active {
- background-color: #a00; /* 按下时颜色变化 */
- transform: translateY(2px); /* 按下时按钮下移效果 */
- }
-
- style>
- <template>
- <div>
- <input
- id="headerInput"
- type="text"
- placeholder="请输入你的任务名称,按回车键确认"
- v-model="title"
- @keyup.enter="submit"
- />
- div>
- template>
-
- <script>
- import { nanoid } from "nanoid"; //函数
-
- export default {
- name: "TodoHeader",
- data() {
- return {
- title: "",
- };
- },
- props: ["addTodo"],
- methods: {
- submit() {
- //将用户的输入包装成一个todo对象
- if (this.title.trim() === "") {
- alert("输入不能为空");
- return;
- }
-
- const todoObj = {
- id: nanoid(),
- title: this.title,
- done: false,
- };
- this.addTodo(todoObj);
- this.title = "";
-
- //安装一些 nanoid npm i nanoid
- },
- },
- };
- script>
-
- <style scoped>
- #headerInput {
- width: 498px;
- height: 30px;
- border: 1px solid #ccc;
- border-radius: 2px;
- padding-left: 10px;
- }
- style>
- <template>
- <div id="container" @mouseover="handleMouseOver" @mouseleave="handleMouseLeave" >
- <div id="d" >
- <input type="checkbox" v-model="todo.done" />
- <span @click="info">{{ todo.title }}span>
- div>
- <button id="button" v-show="showDelete" @click="deleteTodo">删除button>
- div>
- template>
-
- <script>
- export default {
- name: "TodoItem",
- data() {
- return {
- todo: this.todoObj,
- showDelete: false,
- };
- },
- methods: {
- info() {
- console.log(this.todo);
- },
- handleMouseOver() {
- this.showDelete = true;
- },
- handleMouseLeave() {
- this.showDelete = false;
- },
- deleteTodo(){
- this.removeTodo(this.todoObj.id)
- }
- },
- props: {
- todoObj: {
- //传入的若是引用对象 则里面修改了,外面同样生效
- type: Object,
- required: true,
- },
- removeTodo:{
- type:Function,
- }
- },
- };
- script>
-
- <style scoped>
-
- #container:hover{
- background-color: #a09a9a;
- }
-
- #container {
- display: flex;
- justify-content: space-between; /* 水平居左 */
- align-items: center; /* 垂直居中 */
- width: 500px;
- height: 30px;
- border: 0.1px solid #ccc;
- border-radius: 2px;
- padding-left: 10px;
- padding-top: 5px;
- padding-bottom: 5px;
- }
-
- #container * {
- padding: 5px;
- }
-
-
-
- #button {
- width: 50px;
- height: 28px;
- color: white;
- background-color: #eb1212;
- border: 1px solid #ccc;
- border-radius: 5px;
- padding: 5px;
- margin-right: 15px;
- cursor: pointer; /* 鼠标悬停时显示手型光标 */
- transition: background-color 0.3s ease; /* 平滑过渡 */
- }
- #button:hover {
- background-color: #d10d0d; /* 鼠标悬停时颜色变化 */
- }
-
- #button:active {
- background-color: #a00; /* 按下时颜色变化 */
- transform: translateY(2px); /* 按下时按钮下移效果 */
- }
- style>
- <template>
- <div>
- <TodoItem v-for="item in todosList" :key="item.id" :todoObj="item" :removeTodo="deleteTodo" />
-
- div>
- template>
-
- <script>
- import TodoItem from './TodoItem.vue'
-
- export default {
- name:'TodoList',
- components:{
- TodoItem
- },
- data() {
- return {
- todosList: this.todos
- }
- },
- methods:{
- deleteTodo(id){
-
- for(var i=0;i<this.todosList.length;i++){
- if(this.todosList[i].id===id){
- console.log(i,"下标");
-
- break;
- }
- }
-
- this.todosList.splice(i,1);
-
- }
-
- },
- props:['todos']
-
- }
- script>
-
- <style scoped>
-
- style>