Vue实现简单的任务列表案例

1 案例效果

Vue实现简单的任务列表案例

2 用到的知识点

  • 1 使用vite创建项目
  • 2 组件的封装和组册
  • 3 props
  • 4 样式的绑定
  • 5 计算属性
  • 6 自定义事件
  • 7 组件的v-model

3 实现步骤

Vue实现简单的任务列表案例

4 实现功能

  • 1 实现添加新任务功能
  • 2 输入内容不能为空
  • 3 区分完成与未完成任务
  • 4 对任务进行区分

5案例展示

Vue实现简单的任务列表案例
Vue实现简单的任务列表案例
Vue实现简单的任务列表案例

Vue实现简单的任务列表案例

6程序结构

Vue实现简单的任务列表案例

初始化项目

  1. x npm init vite-app todos
  2. npm install
  3. npm i less -D

7 代码展示

App.vue

<template>
    <h1>app根组件</h1>
    <!-- 使用组件 -->
     <!-- 监听TodoInput的自定义add事件 -->
    <todo-input @add="onAddNewTask"></todo-input>
    <todo-list :list="tasklist" class="mt-2"></todo-list>
    <todo-button v-model:active="activeBtnIndex"></todo-button>
</template>

<script>

import TodoList from './components/TodoList.vue'
import TodoInput from './components/TodoInput.vue'
import TodoButton from  './components/TodoButton.vue'

export default {
  name: 'RootApp',
  components:{
      TodoList,
      TodoInput,
      TodoButton
  },
  data(){
    return{
      todoList:[
        { id:1,task:'周一早晨九点开会',done:false},
        { id:2,task:'周一晚上八点半聚餐',done:false},
        { id:3,task:'准备周三上午发布会',done:true},
      ],
      
      //下一个可用的id值
      nextId:4,
      //激活按钮的索引
      activeBtnIndex:0
    }
  },
  computed:{
    tasklist(){
      switch(this.activeBtnIndex){
        case 0: // 全部
        return this.todoList;
        case 1: // 已完成
        return this.todoList.filter(todo=>todo.done)
        case 2: //未完成
        return this.todoList.filter(todo=>!todo.done)
      }
    }
  },
  methods:{
    onAddNewTask(taskname){
        // 向任务列表新增任务
        this.todoList.push({
          id : this.nextId,
          task:taskname,
          done:false
        })
        this.nextId++
    }
  },
}
</script>

TodoList.vue

<template>
      <ul class="list-group ">
    <li class="list-group-item d-flex justify-content-between align-items-center" v-for="item in list" :key="item.id">
      <!-- 复选框 -->
      <div class="custom-control custom-checkbox">
          <input type="checkbox" class="custom-control-input" :id="item.id" v-model="item.done">
          <label class="custom-control-label" :for="item.id" :class="item.done? 'delete':''">{{item.task}}</label>
      </div>
      <span class="badge badge-success badge-pill" v-if="item.done">完成</span>
      <span class="badge badge-warning badge-pill" v-else>未完成</span>
    </li>
  </ul>
</template>

<script>
    export default{
        name:'TodoList',
        props:{
           //列表数据
            list:{
                type:Array,
                required:true,
                default:[]
            } 
        }, 
        data(){
            return{
                taskname:''//新任务的名称
            }
        }
    }
</script>
<style lang='less' scoped>
    .list-group{
        width:600px
    }
    .delete{
        text-decoration: line-through;
    }
</style>

TodoInput.vue

<template>
    <form class="form-inline" @submit.prevent="onFormSubmit">
        <div class="input-group md-2 mr-sm-2">
            <div class="input-group-prepend">
                <div class="input-group-text">任务</div>
            </div>
            <input type="text" class="form-control" v-model.trim="taskname" placeholder="请填写任务信息" style="width:355px">
        </div>
         <!-- 添加按钮 -->
         <button type="submit" class="btn btn-primary md-2">添加新任务</button>
    </form>

</template>

<script>
export default{
    name:'TodoInput',
    //声明自定义事件
    emits:['add'],
    data(){
        return{
            taskname:''
        }
    },
    methods:{
        onFormSubmit(){
            //判断任务名称是否为空
            if(!this.taskname){
                alert('任务不能为空')
                return
            }
               //触发自定义事件  并向外传递数据
            this.$emit('add',this.taskname)
            //清空文本
            this.taskname=''  
            
           
        }
    }
}

</script>

<style class="less" scoped>

</style>

TodoButton.vue

<template>
    <div class="button-container mt-3">
      <div class="btn-group">
           <div class="btn-group">
          <button type="button" class="btn" :class="active===0?'btn-primary':'btn-secondary'" @click='onBtnClick(0)'>全部</button>
          <button type="button" class="btn" :class="active===1?'btn-primary':'btn-secondary'" @click='onBtnClick(1)'>已完成</button>
          <button type="button" class="btn" :class="active===2?'btn-primary':'btn-secondary'" @click='onBtnClick(2)'>未完成</button>
      </div>
      </div>
  </div>
</template>

<script>
export default{
    name:'TodoButton',
    props:{
        active:{//激活项的索引值
            type:Number,
            required:true,
            // 默认激活索引值为0(0 全部   1 已完成  2 未完成)
            default:0
        }
    },
    emits:['update:active'],
    methods:{
        onBtnClick(index){
             console.log(index +"---"+this.active)
            if(index === this.active){
                return
            }else{
                this.$emit('update:active',index)
            }
        }
    }
}
</script>

<style class="less" scoped>
 .button-container{
    width: 400px;
    text-align: center;
  }
</style>

index.css

:root{
  font-size: 12px;
}
body{
  padding: 8px;
}
上一篇:阿里云linux配置ftp服务


下一篇:模板指令-v-for和v-if的优先级