zsydgithub vor 1 Jahr
Ursprung
Commit
97c3c1a231

+ 26 - 2
v3_project/src/App.vue

@@ -2,8 +2,8 @@
   <div class="todo-container">
     <div class="todo-wrap">
       <Header :addTodo="addTodo"></Header>
-      <List :todos="todos"></List>
-      <Footer></Footer>
+      <List :todos="todos" :deletTodo="deletTodo" :updateTodo="updateTodo"></List>
+      <Footer :todos="todos" :checkAll="checkAll" :clearAllComPletedTodos="clearAllComPletedTodos"></Footer>
     </div>
   </div>
 </template>
@@ -42,9 +42,33 @@ export default defineComponent({
     const addTodo = (todo: Todo) => {
       state.todos.unshift(todo);
     };
+    //删除数据的方法
+    const deletTodo = (index: number) => {
+      state.todos.splice(index,1)
+    };
+    //修改todo的isCompleted属性的状态
+    const updateTodo = (todo: Todo,isCompleted: boolean)=>{
+      todo.isCompleted = isCompleted
+      console.log(todo)
+    }
+    //全选或者全不选的一个方法
+    const checkAll = (isCompleted: boolean)=>{
+      //遍历数组
+      state.todos.forEach((todo)=>{
+        todo.isCompleted = isCompleted
+      })
+    }
+    //清理所有选中的数据
+    const clearAllComPletedTodos = ()=>{
+      state.todos = state.todos.filter((todo)=> !todo.isCompleted) //取反
+    }
     return {
       ...toRefs(state),
       addTodo,
+      deletTodo,
+      updateTodo,
+      checkAll,
+      clearAllComPletedTodos
     };
   },
   components: {

+ 41 - 8
v3_project/src/components/Footer.vue

@@ -2,21 +2,55 @@
   <div>
     <div class="todo-footer">
       <label>
-        <input type="checkbox" />
+        <input type="checkbox" v-model="isCheckAll" />
       </label>
-      <span> <span>已完成0</span> / 全部2 </span>
-      <button class="btn btn-danger">清除已完成任务</button>
+      <span> <span>已完成{{ count }}</span> / 全部{{ todos.length }} </span>
+      <button class="btn btn-danger" @click="clearAllComPletedTodos">清除已完成任务</button>
     </div>
   </div>
 </template>
 
 <script lang="ts">
-import { defineComponent } from "vue";
-
+import { computed, defineComponent } from "vue";
+import { Todo } from "../types/todo";
 export default defineComponent({
   name: "Footer",
-  setup() {
-    return {};
+  props: {
+    todos: {
+      type: Array as () => Todo[],
+      required: true,
+    },
+    checkAll: {
+      type: Function,
+      required: true
+    },
+    clearAllComPletedTodos: {
+      type: Function,
+      required: true
+    }
+  },
+  setup(props) {
+    //已完成的计算属性操作
+    const count = computed(() => {
+      return props.todos.reduce(
+        (pre, todo, index) => pre + (todo.isCompleted ? 1 : 0),
+        0
+      );
+    });
+    //全选/全部选的计算属性操作
+    const isCheckAll = computed({
+      get(){
+        return count.value > 0 && props.todos.length == count.value
+      },
+      set(val){
+        props.checkAll(val)
+      }
+    })
+
+    return {
+      count,
+      isCheckAll
+    };
   },
 });
 </script>
@@ -46,5 +80,4 @@ export default defineComponent({
   float: right;
   margin-top: 5px;
 }
-
 </style>

+ 70 - 10
v3_project/src/components/Item.vue

@@ -1,28 +1,88 @@
 <template>
   <div>
-    <li>
+    <li
+      @mouseenter="mouseHandler(true)"
+      @mouseleave="mouseHandler(false)"
+      :style="{ backgroundColor: bgColor, color: myColor }"
+    >
       <label>
-        <input type="checkbox" />
-        <span>{{todo.title}}</span>
+        <input type="checkbox" v-model="isComptete"  />
+        <span>{{ todo.title }}</span>
       </label>
-      <button class="btn btn-danger" style="display: none">删除</button>
+      <button class="btn btn-danger" v-show="isShow" @click="delTodo">
+        删除
+      </button>
     </li>
   </div>
 </template>
 
 <script lang="ts">
-import { defineComponent } from "vue";
-import {Todo} from "../types/todo"
+import { computed, defineComponent, ref } from "vue";
+import { Todo } from "../types/todo";
 export default defineComponent({
   name: "Item",
   props: {
     todo: {
       type: Object as () => Todo, //函数返回的是一个Todo类型
-      required: true
+      required: true,
+    },
+    deletTodo: {
+      type: Function,
+      required: true,
+    },
+    index: {
+      type: Number,
+      required: true,
     },
+    updateTodo: {
+      type: Function,
+      required: true
+    }
   },
-  setup() {
-    return {};
+  setup(props) {
+    //背景色
+    const bgColor = ref("white");
+    //前景色
+    const myColor = ref("black");
+
+    const isShow = ref(false);
+    //鼠标进入和离开事件的回调函数
+    const mouseHandler = (flag: boolean) => {
+      if (flag) {
+        //鼠标划入
+        bgColor.value = "pink";
+        myColor.value = "green";
+        isShow.value = true;
+      } else {
+        //鼠标划出
+        bgColor.value = "white";
+        myColor.value = "black";
+        isShow.value = false;
+      }
+    };
+    //删除数据的方法
+    const delTodo = () => {
+      if (window.confirm("确定删除吗?")) {
+        props.deletTodo(props.index);
+      }
+    };
+    //计算属性的方式---来让当前的复选框选中/不选中
+    const isComptete = computed({
+      get(){
+        return props.todo.isCompleted
+      },
+      set(val){
+        props.updateTodo(props.todo,val)
+      }
+    })
+    return {
+      bgColor,
+      myColor,
+      mouseHandler,
+      isShow,
+      delTodo,
+      isComptete
+    };
   },
 });
 </script>
@@ -50,7 +110,7 @@ li label li input {
 
 li button {
   float: right;
-  display: none;
+  /* display: none; */
   margin-top: 3px;
 }
 

+ 11 - 4
v3_project/src/components/List.vue

@@ -1,7 +1,14 @@
 <template>
   <div>
     <ul class="todo-main">
-      <Item v-for="(todo,index) in todos" :key="todo.id" :todo="todo"></Item>
+      <Item
+        v-for="(todo, index) in todos"
+        :key="todo.id"
+        :todo="todo"
+        :deletTodo="deletTodo"
+        :updateTodo="updateTodo"
+        :index="index"
+      ></Item>
     </ul>
   </div>
 </template>
@@ -11,13 +18,13 @@ import { defineComponent } from "vue";
 import Item from "./Item.vue";
 export default defineComponent({
   name: "List",
-  props: ['todos'],
+  props: ["todos", "deletTodo",'updateTodo'],
   setup() {
     return {};
   },
   components: {
-    Item
-  }
+    Item,
+  },
 });
 </script>