【Vue.js/Vue-cli】实现To do list

Vue.js实现To do list

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TodoList</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <style>
        .completed {
            color: #999999;
            text-decoration: line-through;
        }
    </style>
</head>

<body>
    <div id="app">
        <h2>To do list</h2>
        <input type="text" v-model="inputValue">
        <button @click="addTolist">添加</button>
        <ul>
            <li v-for="item of filterList" :key="item.id" :class="{completed:item.completed}"
                @click="onCompletedList(item.id)" @dblclick="onDeleteList(item.id)">
                {{item.id}} | {{item.text}}
            </li>
        </ul>
        <button @click="onFilterList(1)" :disabled = "filterType === 1">全部</button>
        <button @click="onFilterList(2)" :disabled = "filterType === 2">已完成</button>
        <button @click="onFilterList(3)" :disabled = "filterType === 3">未完成</button>
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            inputValue: '',
            list: [], // 备份数据
            filterList: [], // 展示数据
            filterType: 1
        },
        methods: {
            // 添加商品
            addTolist() {
                // 当有输入的内容时, 把输入的内容存储到list中
                if (this.inputValue !== '') {
                    // data存储数据
                    const data = {
                        id: Date.now(),
                        text: this.inputValue,
                        completed: false
                    }
                    // 头部插入
                    this.list.unshift(data) // 把data添加到备份数据中
                    this.filterList.unshift(data) // 把data添加到展示数据中
                }
                this.inputValue = ''
            },

            // 把事件设置为已完成
            onCompletedList(id) {
                // 从list中查找符合要求的第一个元素
                const index = this.list.findIndex((item) => item.id === id)
                this.list[index].completed = true
                this.filterList[index].completed = true
            },

            // 删除选中list
            onDeleteList(id) {
                const index = this.list.findIndex(item => item.id === id)
                this.list.splice(index, 1) // 修改备份数据
                this.filterList.splice(index, 1) // 从数组中删除
            },

            // 事件过滤
            onFilterList(type) {
                this.filterType = type
                // 所有的过滤操作不能改变原数据
                // 深拷贝数组
                const list = JSON.parse(JSON.stringify(this.list))
                switch (type) {
                    case 1: // 全部的数据
                        this.filterList = list
                        break
                    case 2: // 已完成的数据
                        this.filterList = list.filter(item => item.completed)
                        break
                    case 3: // 未完成的数据
                        this.filterList = list.filter(item => !item.completed)
                        break

                }
            }
        }
    })
</script>

</html>

Vue-cli组件化实现To do list

在这里插入图片描述

  • Main.js
// 创建通信总线
// Vue.prototype.bus = new Vue()
  • App.vue
<template>
  <div id="app">
    <!-- <h2 @click="handleClick">hello</h2> -->
    <!-- 响应子组件的事件 @子组件定义的事件且组件默认响应自定义事件
    使用事件修饰符.native才会触发JS的原生事件-->
    <!-- bus method -->
    <!-- <t-input
    @add = "addToList"
    @click.native = "handleClick"
    ></t-input>
    <t-list :list ="list" ></t-list> -->
    <t-input
    @add = "addToList"
    @click.native = "handleClick"
    ></t-input>
    <t-list
    :list ="list"
    @update="updateList"
    @delete="deleteList">
    </t-list>
  </div>
</template>

<script>
import TInput from './components/Input'
import TList from './components/List'
export default {
  name: 'App',
  components: {
    TInput,
    TList
  },
  data () {
    return {
      list: [
        /* {
          id: 1,
          text: 'aaa'
        },
        {
          id: 2,
          text: 'bbb'
        },
        {
          id: 3,
          text: 'ccc'
        } */
      ]
    }
  },
  // 总线机制
  /* mounted() {
    // console.log(this.bus)
    this.bus.$on('completed', id => {
      // console.log('app bus:', id)
      this.updateList(id)
    })

    this.bus.$on('delete', id => {
      // console.log('app bus:', id)
      this.deleteList(id)
    })
  }, */
  methods: {
    addToList (res) {
      // console.log(res)
      this.list.push({
        id: Date.now(),
        text: res,
        completed: false
      })
    },
    updateList (id) {
      // console.log('app', id)
      // 修改id对应的数据
      const task = this.list.find(item => item.id === id)
      task.completed = true
    },

    deleteList (id) {
      // 删除id对应的数据
      const index = this.list.findIndex(item => item.id === id)
      this.list.splice(index, 1)
    },
    handleClick () {
      // alert('123')
    }
  }
}
</script>

<style>

</style>

  • Components/ Input.vue
<template>
  <div>
    <!-- <h1 @click="$emit('click')">HELLO</h1> -->
    <h1>hello</h1>
    <input type="text" v-model.trim="inputValue" />
    <button @click="handleClick">Add to list</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      inputValue: ''
    }
  },
  methods: {
    handleClick () {
      if (this.inputValue !== '') {
        // console.log(this.inputValue)
        // 把this.inputValue传递到父组件
        // this.$emit(事件名, 要传递的数据)
        this.$emit('add', this.inputValue)
        // 清空输入框
        this.inputValue = ''
      }
    }
  }
}
</script>

<style scoped>

</style>

  • Components/ List.vue
<template>
  <ul>
    <!-- <list-item
      v-for = "item of list"
      :key = "item.id"
      :item = "item"
      @delete = "handleDelete"
      ></list-item> -->
    <list-item
      v-for="item of list"
      :key="item.id"
      :item="item"
      @completed="handleCompleted"
      @delete="handleDelete"
    ></list-item>
  </ul>
</template>

<script>
import ListItem from './ListItem'
export default {
  // 接收属性
  // 需要限制属性的类型
  // props: ['list'],
  props: {
    list: {
      type: Array,
      required: true
      // 如果是引用类型, 默认值必须是函数, 然后引用类型
      // default(){
      //     return [1, 2, 3]
      // }
    }
    /*  age :{
        type: Number,
        // 当父组件的传递数据未定义的时候取默认值
        default: 20,
        // 自定义验证
        validator(value){
          // 参数value就是父组件传递过来的数据
          // console.log('validator', value)
          // 必须返回布尔类型
          return value >= 0
        }
      } */
  },
  components: {
    ListItem
  },
  methods: {
    handleCompleted (id) {
      // console.log('list', id)
      // 通知父组件做修改
      this.$emit('update', id)
    },
    handleDelete (id) {
      this.$emit('delete', id)
    }
  },
  // 生命周期
  mounted () {
    // 使用通过属性传递的数据
    console.log(this.list)
  }
}
</script>

<style>
</style>

  • Components/ ListItem.vue
<template>
  <li
    @click="handleClick"
    :class="{ completed: item.completed }"
    @dblclick="handleDblclick"
  >
    {{ item.text }}
  </li>
</template>

<script>
export default {
  props: {
    item: Object
  },
  methods: {
    handleClick () {
      // 把当前的item的complete的值变为true
      // 不能在组件中直接修改父组件传递的值
      // 通知父组件修改处理
      this.$emit('completed', this.item.id)
      // console.log(this.bus)
      // 通过bus触发了一个事件
      // this.bus.$emit('completed', this.item.id)
    },
    handleDblclick () {
      this.$emit('delete', this.item.id)
      // 通过bus触发了一个事件
      // this.bus.$emit('delete', this.item.id)
    }
  }
}
</script>

<style>
.completed {
  color: #999;
  text-decoration: line-through;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值