vue实现todolist的增删改查

vue实现todolist的目录和效果图

在这里插入图片描述
image.png

app.vue
<template>
  <div id="app">
    <div className='container'>
      <Inputs @addItem="addItem" @search="search"></Inputs>
      <List :list="list"></List>
      <Total @sendCheckAll="checkAllHandler" :isCheckAll="isCheckAll" :list="list"></Total>
      <Masks :isOpen="isOpen" @sendIsOpen="isOpen = false" :content="edit.content" @getContent="getContent" @updateHandler="updateHandler"></Masks>
    </div>
  </div>
</template>
<script>
import List from "./components/List.vue";
import Item from "./components/Item.vue";
import Masks from "./components/Mask.vue";
import Total from "./components/Total.vue";
import Inputs from "./components/Input.vue";
export default {
  props: {},
  components: { List, Item, Masks, Total, Inputs },
  data() {
    return {
      flag: false,
      list: [
        {
          id: 1,
          content: "哈哈哈",
          checked: false,
        },
        {
          id: 7,
          content: "1212",
          checked: false,
        },
        {
          id: 5,
          content: "33",
          checked: false,
        },
      ],
      selectLength: 0,
      item: {},
      isCheckAll: false,
      isOpen: false,
      edit: {
        content:""
      }
    };
  },
  computed: {},
  methods: {
    // 全选全不选
    checkAllHandler(checked) {
      this.list = this.list.map(item => ({...item,checked}))
    },
    // 单选单不选
    checkHandler(id,checked) {
      this.list = this.list.map(item => {
        if(item.id === id) {
          item.checked = checked;
        }
        return item
      })
      let length = this.list.filter(item => item.checked).length;
      if(length === this.list.length) {
        this.isCheckAll = true
      } else {
        this.isCheckAll = false
      }
    },
    // 添加
    addItem(v) {
      this.list = [...this.list,v]
    },
    // 搜索
    search(e) {
      console.log("e",e)
      this.list = this.list.filter(item => {
        console.log("item",item)
        return item.content.includes(e)
      })
    },
    // 删除
    deleteHandler(id) {
      this.list = this.list.filter(item => {
        return item.id !==id;
      })
    },
    // 编辑回显
    getContent(content) {
      this.edit = Object.assign(this.edit,{content})
    },
    // 编辑更新
    updateHandler({content,flag}) {
      this.isOpen = flag;
      // this.getContent(content)
      this.list = this.list.map(item =>{
        if(item.id=== this.edit.id) {
          item = {...this.edit}
        }
        return item
      })
    }
  },
  mounted() {
    this.$bus.$on("getCheckHandler",({id,checked})=>{
      this.checkHandler(id,checked)
    })
    this.$bus.$on("getDelete",id=>{
      this.deleteHandler(id)
    })
    this.$bus.$on("getOpen",({item,flag})=>{
      console.log("flag",flag)
      this.isOpen = flag;
      this.edit = {...item};
    })
  },
  destroyed() {
    this.$bus.$off("getCheckHandler");
    this.$bus.$off("getDelete");
    this.$bus.$off("getOpen");
  }
};
</script>
<style scoped>
@import url("./assets/common.css");
</style>

Input.vue

<template>
  <div>
    <div class="input">
        <input type="text" placeholder='请输入你的任务名称,按回车键确认' v-model="content"/>
        <button class="btn btn-success" @click="addHandler">添加</button>
        <button class="btn btn-primary" @click="searchHandler">搜索</button>
    </div>
  </div>
</template>
<script>
export default {
  props:{},
  components:{},
  data() {
    return {
      content: ''
    }
  },
  methods: {
    addHandler() {
      let v = {
        id: Date.now(),
        content: this.content,
        checked: false
      }
      this.$emit("addItem",v)
    },
    searchHandler() {
      console.log("搜索")
      if(!this.content) return console.log("请输入")
      this.$emit("search",this.content)
    }
  },
  mounted() {}
}
</script>
<style scoped>

</style>
List.vue
<template>
    <ul class="task-list">
      <Item v-for="(item,index) in list" :key="index" :item="item">
      </Item>
    </ul>
</template>
<script>
import Item from './Item'
export default {
  props:{
    list: {
      type: Array,
      default: ()=>{
        return []
      }
    }
  },
  components:{Item},
  data() {
    return {}
  },
  methods: {},
  mounted() {}
}
</script>
<style scoped>

</style>
Item.vue
<template>
  <li class="task-item">
      <input type="checkbox" v-model="item.checked" @change="changeHandler(item.id,$event)"/>
      <div class="content">
        {{item.content}}
      </div>
      <button class="btn btn-success" @click="editHandler(item)">编辑</button>
      <button class="btn btn-primary" @click="deleteHandler(item.id)">删除</button>
    </li>
</template>
<script>
export default {
  props:{
    item: {
      type: Object,
      default: ()=>{
        return {}
      }
    }
  },
  components:{},
  data() {
    return {}
  },
  methods: {
    changeHandler(id,e) {
      let checked = e.target.checked
      this.$bus.$emit("getCheckHandler",{id,checked})
    },
    deleteHandler(id) {
     this.$bus.$emit("getDelete",id)
    },
    editHandler(item) {
      console.log("编辑")
      this.$bus.$emit("getOpen",{item,flag:true})
    }
  },
  mounted() {}
}
</script>
<style scoped>

</style>
Mask.vue
<template>
    <div class="mm-mask" v-if="isFlag">
    <div class="mm-modal">
      <div class="mm-title">
        <span class="mm-edit">编辑</span>
        <span class="mm-close"  @click="isFlag=false">x</span>
      </div>
      <div class="mm-content">
        <input type="text" placeholder="任务名称" v-model="setContent" />
      </div>
      <div class="mm-box-btn">
        <div class="mm-update" @click="updateHandler">更新</div>
        <div class="mm-cancel" @click="isFlag=false">取消</div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props:{
    isOpen: {
      type: Boolean
    },
    content: {
      type: String
    }
  },
  components:{},
  data() {
    return {
      flag: this.isOpen,
      text: ""
    }
  },
  computed: {
    isFlag: {
      get() {
        return this.flag = this.isOpen
      },
      set(val) {
        this.flag = val
        this.$emit("sendIsOpen",val)
      }
    },
    setContent: {
      get() {
        return this.text = this.content
      },
      set(val) {
        this.text = val
        this.$emit("getContent",val)
      }
    }
  },
  methods: {
    updateHandler() {
      console.log("更新")
      if(!this.setContent) return console.log("请输入")
      this.$emit("updateHandler",{content: this.setContent,flag:false})
    }
  },
  mounted() {}
}
</script>
<style scoped>

</style>
Total.vue
<template>
   <div class="task-done">
      <input type="checkbox" @change="changeHandler($event)" v-model="getCheckAll"/>
      <p>已完成<span class="single-number">{{selectLength}}</span> 全部<span class="all-number">{{list.length}}</span></p>
      <p></p>
    </div>
</template>
<script>
export default {
  props:{
    checkAll: {
      type: Function
    },
    isCheckAll: {
      type: Boolean
    },
    list: {
      type: Array,
      default: ()=>{
        return []
      }
    }
  },
  computed: {
    getCheckAll: {
      get() {
        return this.checked = this.isCheckAll
      },
      set(value) {
        this.checked = value
      }
    },
    selectLength() {
       return this.list.filter(item => item.checked).length
    }
  },
  components:{},
  data() {
    return {
      checked: false,
    }
  },
  methods: {
    changeHandler(e) {
      this.$emit("sendCheckAll",e.target.checked)
    }
  },
  mounted() {
   
  }
}
</script>
<style scoped>

</style>
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lxslxskxs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值