IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue ToDoList案例源码 -> 正文阅读

[JavaScript知识库]Vue ToDoList案例源码

写在前面

最近在学习Vue,此处记录下第一个学习案例。

main.js

//引入vue
import Vue from 'vue'
//引入App组件
import App from './App.vue'

//关闭生产模式提示
Vue.config.productionTip = false

//创建vue实例
new Vue({
  el:'#app',
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus = this//全局事件总线,this为vm
  }
})

APP.vue

<template>
  <div id="app">
    <div class="todo-container">
      <div class="todo-wrap">
        <MyHeader @addtodo="addtodo"/>
        <MyList :todolist="todolist" @deltodo="deltodo"/>
        <MyFoot :todolist="todolist" @checkalltodo="checkalltodo" @delAll="delAll"/>
      </div>
    </div>
  </div>
</template>

<script>
  import MyHeader from "./components/MyHeader.vue";
  import MyList from "./components/MyList.vue";
  import MyFoot from "./components/MyFooter.vue";

  export default {
    name: 'App',
    components: {
      MyHeader,
      MyList,
      MyFoot
    },
    data() {
      return {
        //使用localStrage将数据存储到本地
        todolist:JSON.parse(localStorage.getItem('todolist')) || []
      }
    },
    methods:{
      addtodo(newtodo){
        this.todolist.unshift(newtodo)
      },
      checktodo(id){
        this.todolist.forEach((value) => {
          if(value.id === id) value.done = !value.done
        })
      },
      checkalltodo(status){
        this.todolist.forEach((value) => {
          value.done = status
        })
      },
      deltodo(id){
        this.todolist = this.todolist.filter((todo) => {
          return todo.id !== id
        })
      },
      delAll(){
        this.todolist = this.todolist.filter((todo) =>{
          return !todo.done
        })
      }
    },
    watch:{
      todolist:{
        deep:true,
        handler(val){
          localStorage.setItem('todolist',JSON.stringify(val))
        }
      }
    },
    mounted() {
      this.$bus.$on('deltodo',this.deltodo)//绑定自定义事件
    },
    beforeDestroy() {
      this.$bus.$off('deltodo')//取消一个绑定自定义事件
      // this.$bus.$off()//取消所有绑定自定义事件
    },
  }
</script>

<style>
  /*base*/
  body {
    background: #fff;
  }

  .btn {
    display: inline-block;
    padding: 4px 12px;
    margin-bottom: 0;
    font-size: 14px;
    line-height: 20px;
    text-align: center;
    vertical-align: middle;
    cursor: pointer;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
    border-radius: 4px;
  }

  .btn-danger {
    color: #fff;
    background-color: #da4f49;
    border: 1px solid #bd362f;
  }

  .btn-danger:hover {
    color: #fff;
    background-color: #bd362f;
  }

  .btn:focus {
    outline: none;
  }

  .todo-container {
    width: 600px;
    margin: 0 auto;
  }
  .todo-container .todo-wrap {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
  }
</style>

MyHeader.vue

<template>
  <div class="todo-header">
    <input type="text" placeholder="请输入代办内容,按回车键确认" v-model="title" @keyup.enter="addToDo"/>
  </div>
</template>
 
<script>
    import {nanoid} from 'nanoid'
    export default {
        name: "MyHeader",
        data(){
            return {
                title:''
            }
        },
        methods:{
            addToDo(){
                this.title = this.title.trim()
                if(!this.title) return alert('请输入代办内容')
                const toDoObj = {id:nanoid(),title:this.title,done:false}
                this.$emit('addtodo',toDoObj)
                this.title=''
            }
        }
    }
</script>
 
<style scoped>
    /*header*/
    .todo-header input {
    width: 560px;
    height: 28px;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 4px 7px;
    }

    .todo-header input:focus {
    outline: none;
    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
    }
</style>

MyList.vue

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

<script>
    import MyItem from "./MyItem.vue";
    export default {
        name: "MyList",
        props:['todolist'],
        components:{
            MyItem
        }
    }
</script>

<style scoped>
    /*main*/
    .todo-main {
    margin-left: 0px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding: 0px;
    }

    .todo-empty {
    height: 40px;
    line-height: 40px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding-left: 5px;
    margin-top: 10px;
    }
</style>

MyItem.vue

<template>
  <ul class="todo-empty">
    <li>
      <label>
        <input type="checkbox" v-model="todoObj.done"/>
        <span>{{todoObj.title}}</span>
      </label>
      <button class="btn btn-danger" @click="del(todoObj.id)" >删除</button>
    </li>
  </ul>
</template>

<script>

  export default {
    name: "MyItem",
    props:['todoObj'],
    methods: {
      del(id){
        // this.deltodo(id);
        this.$bus.$emit('deltodo',id)
      },
    },
  }
</script>

<style scoped>
    .todo-empty {
    height: 40px;
    line-height: 40px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding-left: 5px;
    margin-top: 10px;
  }

  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: black;
    margin-top: 3px;
  }

  li:before {
    content: initial;
  }

  li:last-child {
    border-bottom: none;
  }
</style>

MyFooter.vue

<template>
  <div class="todo-footer">
    <label>
      <input type="checkbox" v-model="isAll" />
    </label>
    <span>
      <span>已完成{{doneTodo}}</span> / 全部{{todol}}
    </span>
    <button class="btn btn-danger" @click="delchecktodo">清除已完成代办</button>
  </div>
</template>

<script>
  export default {
    name: "MyFoot",
    props:['todolist'],
    computed:{
      todol(){
        return this.todolist.length
      },
      doneTodo(){
        //数组过滤方法reduce
        return this.todolist.reduce((pre,current)=> {
          return pre + (current.done ? 1 : 0)
        },0)
      },
      isAll:{
        set(value){
          this.$emit('checkalltodo',value)
        },
        get(){
          return this.todol === this.doneTodo && this.todol > 0
        }
      }
    },
    methods:{
      delchecktodo(){
        if(confirm("确认删除嘛")){
          this.$emit('delAll')
        }
      }
    }
  }
</script>

<style scoped>
  /*footer*/
  .todo-footer {
    height: 40px;
    line-height: 40px;
    padding-left: 6px;
    margin-top: 5px;
  }

  .todo-footer label {
    display: inline-block;
    margin-right: 20px;
    cursor: pointer;
  }

  .todo-footer label input {
    position: relative;
    top: -1px;
    vertical-align: middle;
    margin-right: 5px;
  }

  .todo-footer button {
    float: right;
    margin-top: 5px;
  }
</style>

总结

以上为第一版代码,后续会进行优化。
参考文章.

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-12 16:23:29  更:2022-05-12 16:25:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:16:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码