Vue 2 TodoList 案例

组件化编码流程(通用)

1.实现静态组件:抽取组件,使用组件实现静态页面的效果

结构

2.代码

1.App.vue

html 复制代码
<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>

2.TodoComponent.vue

html 复制代码
<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>

3.TodoFooter.vue

html 复制代码
<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>

4.TodoHeader.vue

html 复制代码
<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>

5.TodoItem.vue

html 复制代码
<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>

6. TodoList.vue

html 复制代码
<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>
相关推荐
I_Am_Me_6 分钟前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
雯0609~13 分钟前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ17 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z22 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
星星会笑滴26 分钟前
vue+node+Express+xlsx+emements-plus实现导入excel,并且将数据保存到数据库
vue.js·excel·express
前端百草阁1 小时前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4041 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish1 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
zwjapple1 小时前
typescript里面正则的使用
开发语言·javascript·正则表达式