美文网首页
toDoList案例

toDoList案例

作者: 冰点雨 | 来源:发表于2022-04-06 10:13 被阅读0次

1.组件化编码流程
(1)拆分静态组件:组件要按照功能点拆分,命名不要与 html 元素冲突
(2)实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用
a.一个组件在用,放在组件自身即可
b.一些组件在用:放在他们共同的父组件上()
(3)实现交互:从绑定事件开始

2.props 适用于:
(1)父组件 ==> 子组件 通信
(2)子组件 ==> 父组件 通信(要求先给子一个函数)
3.使用 v-model 时要切记:v-model 绑定的值不能是 props 传过来的值,因为 props 是不可以修改的
4.props 传过来的若是对象类型的值,修改对象中的属性时 Vue 不会报错,但不推荐这样做


e77a0010f82ea8861182a5b39fb115b.png

App.vue

<template>
  <div id="root">
    <div class="todo-container">
      <div class="todo-wrap">
        <MyHeader :addTodo="addTodo" />
        <MyList
          :todos="todos"
          :changeTodo="changeTodo"
          :deleteTodo="deleteTodo"
        />
        <MyFooter
          :todos="todos"
          :checkAllTodo="checkAllTodo"
          :clearAllTodo="clearAllTodo"
        />
      </div>
    </div>
  </div>
</template>

<script>
// 引入组件
import MyHeader from './components/MyHeader'
import MyList from './components/MyList'
import MyFooter from './components/MyFooter'

export default {
  name: 'App',
  components: {
    MyHeader,
    MyList,
    MyFooter,
  },
  data() {
    return {
      todos: [],
    }
  },
  methods: {
    // 添加
    addTodo(todoObj) {
      this.todos.unshift(todoObj)
    },
    // 选择
    changeTodo(id) {
      this.todos.forEach((todo) => {
        if (todo.id === id) todo.done = !todo.done
      })
    },
    // 删除
    deleteTodo(id) {
      this.todos = this.todos.filter((todo) => {
        return todo.id !== id
      })
    },
    // 全选
    checkAllTodo(done) {
      this.todos.forEach((todo) => {
        todo.done = done
      })
    },
    //清除所有已完成的todo
    clearAllTodo() {
      this.todos = this.todos.filter((todo) => {
        return !todo.done
      })
    },
  },
}
</script>

<style>
</style>

MyHeader.vue

<template>
  <div class="todo-header">
    <input
      type="text"
      placeholder="请输入你的任务名称,按回车键确认"
      v-model="title"
      @keyup.enter="add"
    />
  </div>
</template>

<script>
import { nanoid } from 'nanoid'
export default {
  name: 'MyHeader',
  data() {
    return {
      title: '',
    }
  },
  props: ['receive'],
  methods: {
    add() {
      if (!this.title.trim()) return alert('输入不能为空')
      // 将用户的输入包装成一个todo对象
      const todoObj = { id: nanoid(), title: this.title, done: false }
      // 通知APP组件去添加一个todo对象
      this.receive(todoObj)
      // 清空输入框数据
      this.title = ''
    },
  },
}
</script>

<style scoped>
</style>

MyList.vue

<template>
  <ul class="todo-main">
    <MyItem
      v-for="todoObj in todos"
      :key="todoObj.id"
      :todo="todoObj"
      :changeTodo="changeTodo"
      :deleteTodo="deleteTodo"
    />
  </ul>
</template>

<script>
import MyItem from './MyItem'
export default {
  name: 'MyList',
  components: { MyItem },
  props: ['todos', 'changeTodo', 'deleteTodo'],
}
</script>

<style scoped>
</style>

MyFooter.vue

<template>
  <div class="todo-footer" v-show="total">
    <label>
      <!-- <input type="checkbox" :checked="isAll" /> -->
       <input type="checkbox" v-model="isAll"/>
    </label>
    <span>
      <span>已完成{{ doneTotal }}</span>/全部{{total}}
    </span>
    <button class="btn btn-danger" @click="clearAll">清除已完成任务</button>
  </div>
</template>

<script>
export default {
  name: 'MyFooter',
  props: ['todos','checkAllTodo','clearAllTodo'],
  computed: {
    total(){
      return this.todos.length
    },
    doneTotal() {
      // return this.todos.reduce((pre,current)=>{
      //   return pre+(current.done ? 1 :0)
      // },0)
      return this.todos.reduce(
        (pre, current) => pre + (current.done ? 1 : 0),
        0
      )
    },
    isAll:{
      get(){
         return this.doneTotal === this.total && this.total > 0
      },
      set(value){
         this.checkAllTodo(value)
      }
    }
  },
  methods:{
    clearAll(){
        this.clearAllTodo()
    }
  }
}
</script>

<style scoped>
</style>

MyItem.vue

<template>
  <li>
    <label>
      <input
        type="checkbox"
        :checked="todo.done"
        @change="handleCheck(todo.id)"
      />
      <!-- 如下代码也能实现功能,但是不太推荐,因为有点违反原则,修改了props-->
      <!-- <input
        type="checkbox"
        v-model="todo.done"
      /> -->
      <span>{{ todo.title }}</span>
    </label>
    <button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>
  </li>
</template>

<script>
export default {
  name: 'MyItem',
  // 声明接收todo对象
  props: ['todo', 'changeTodo', 'deleteTodo'],
  methods: {
    handleCheck(id) {
      // 通知APP对象将对应的todo对象done取反
      this.changeTodo(id)
    },
    handleDelete(id) {
      if (confirm('确定删除吗?')) {
        this.deleteTodo(id)
      }
    },
  },
}
</script>

<style scoped>
li {
  list-style: none;
  height: 36px;
  line-height: 36px;
  padding: 0 5px;
  border-bottom: 1px solid #ddd;
}

li label {
  float: left;
  cursor: pointer;
}

li label li input {
  vertical-align: middle;
  margin-right: 6px;
  position: relative;
  top: -1px;
}

li button {
  float: right;
  display: none;
  margin-top: 3px;
}

li:before {
  content: initial;
}

li:last-child {
  border-bottom: none;
}

li:hover {
  background-color: #ddd;
}

li:hover button {
  display: block;
}
</style>

相关文章

  • toDoList案例

    1.组件化编码流程(1)拆分静态组件:组件要按照功能点拆分,命名不要与 html 元素冲突(2)实现动态组件:考虑...

  • Vuex案例ToDoList

    Vuex学习 使用UI:ant-design-vue 修改main.js 修改App.vue组件,完善功能 创建 ...

  • react案例todoList

    项目结构 效果图 app.js app.css Foot.js Head.js Item.js List.js

  • toDoList 案例分析

    1.8.1 案例:案例介绍 鼠标按下keydown ;鼠标弹起 keyup ; keyCode 记录键盘按下事件...

  • vue todoList 案例

    添加,修改,删除 Footer组件 Head组件 List 组件 MyItem 组件 App 主组件 main.js

  • 本地存储localstorage 2019-12-10

    网盘案例下载链接 var todolist = [{title: '我今天吃八个馒头',done: false},...

  • React 经典案例--TodoList

    上次写了一个React生命周期详解,给新手看还是不是特别容易理解(其实我也是新手),这边再做一个React的tod...

  • vue经典案例todolist

  • 案例-todolist-1

  • mobx-react简明教程

    mobx是很好,很容易理解的状态管理工具 先讲一下这个案例是做TODOlist的案例,利用antd样式,用mobx...

网友评论

      本文标题:toDoList案例

      本文链接:https://www.haomeiwen.com/subject/vosjdrtx.html