vue基础项目--任务清单

0.最终样式演示

完整代码地址
GitHub:https://github.com/xiaoxin179/tasklist
概述:目的在于熟悉vue的各种语法,做出一点小成品,话费少量的事件,提升学习兴趣
请添加图片描述

1.构建vue工程

使用vite+boostrap

//命令行创建vite项目
npm init  vite-app tasklist
npm install
npm run dev

2.代码细节

0.app.vue

<template>
  <div class="app">
    <h1>任务清单</h1>
    <AddTask @addTask="addTask"/>
    <!-- 字符组件之间的传值 -->
    <TaskList :tasklist="tasklist"></TaskList>
    <TodoButton @changeActive="changeActive"/>
  </div>
</template>

<script>
import TaskList from './components/TaskList.vue'
import TodoButton from './components/TodoButton.vue'
import AddTask from './components/AddTask.vue'
export default {
  name: "App",
  data(){
      return{
        active:0,
        tasklist:[
          {id:1,task:'吃饭',isCompleted:true},
          {id:2,task:'洗衣服',isCompleted:true},
          {id:3,task:'玩手机',isCompleted:false}
        ]
      }
    },
    // 计算属性,响应式式数据计算之后返回新的值,就是计算之后让todolist为新的值,通过这个来实现过滤的效果
  computed:{
    tasklist(){
      if(this.active === 0){
        return this.tasklist
      }else if(this.active === 1){
        return this.tasklist.filter(item =>item.isCompleted)
      }else{
        return this.tasklist.filter(item =>!item.isCompleted)
      }
    }
  },
  components: {
    TaskList,
    TodoButton,
    AddTask
  },
  methods:{
    changeActive(active){
      this.active=active
      // 测试值是否传递过来
      // console.log(this.active);
    },
    addTask(taskname){
      this.tasklist.push({
        id:this.tasklist.length+1,
        task:taskname,
        isCompleted:false
      })
    }
  },
};
</script>

A.TaskList.vue --任务列表

<template>
  <div>
    <div class="list">
      <ul class="list-group">
        <li
          class="list-group-item d-flex justify-content-between align-items-center"
          v-for="item in tasklist" :key="item.id"
        >
        <!-- 复选框 -->
          <div class="form-check">
            <input
              class="form-check-input"
              type="checkbox"
              value=""
              :id="item.id"
              v-model="item.isCompleted"
            />
            <!-- 动态绑定css属性 -->
            <label class="form-check-label" :for="item.id" :class="item.isCompleted?'del':''">
              {{item.task}}
            </label>
        </div> 
          <span class="badge badge-primary badge-pill" v-if="item.isCompleted">已完成</span>
          <span class="badge badge-warning badge-pill" v-else>未完成</span>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
export default {
    props: {
    tasklist: {
      type: Array, 
      required: true
    }
  },
  data() {
    return {
      name: "TaskList",
    };
  },
};
</script>
<style scoped>
.list-group {
  width: 500px;
  margin: 20px auto;
}
.del{
    text-decoration: line-through;
}
</style>

代码解释:
子父数据传递

在父组件app.vue中,定义数据具有的属性

tasklist:[
          {id:1,task:'吃饭',isCompleted:true},
          {id:2,task:'洗衣服',isCompleted:true},
          {id:3,task:'玩手机',isCompleted:false}
        ]

在子组件中接受

props: {
      // 定义require的值为true的意思就是父组件必须给子组件传递这个参数
    tasklist: {
      type: Array, 
      required: true
    }
  },
完成的任务css动态属性绑定
<label class="form-check-label" :for="item.id" :class="item.isCompleted?'del':''">
//在css中定义del
.del{
    text-decoration: line-through;
}
完成未完成的标签显示
<span class="badge badge-primary badge-pill" v-if="item.isCompleted">已完成</span>
<span class="badge badge-warning badge-pill" v-else>未完成</span>

B.TodoButton.vue

<template>
  <div class="taskbutton">
    <div class="btn-group" role="group" aria-label="Basic example">
      <button
        type="button"
        class="btn"
        :class="active === 0 ? 'btn-primary' : 'btn-secondary'"
        @click="changeActive(0)"
      >
        全部计划
      </button>
      <button
        type="button"
        class="btn"
        :class="active === 1 ? 'btn-primary' : 'btn-secondary'"
        @click="changeActive(1)"
      >
        完成计划
      </button>
      <button
        type="button"
        class="btn"
        :class="active === 2 ? 'btn-primary' : 'btn-secondary'"
        @click="changeActive(2)"
      >
        未完成计划
      </button>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      namne: "TaskButton",
      active: 0,
    };
  },
  emit:["changeActive"],
  methods:{
    changeActive(index){
        this.active=index;
        // <!-- emit的作用是触发自定义事件,携带事件名,并且传递参数 -->
        this.$emit('changeActive',index);
    }

  }
};
</script>
<style scoped>
.btn-group {
  width: 500px;
}
</style>
代码解释
按钮被点击显示不同的颜色

思路:创建一个变量,然后csss属性动态绑定,如果变量的值0,代表第一个被点击到,为蓝色,点击事件就触发函数传递这个值,函数就是修改这个值

<button
        type="button"
        class="btn"
        :class="active === 0 ? 'btn-primary' : 'btn-secondary'"
        @click="changeActive(0)"
      >
        全部计划
      </button>
父组件中表单数据的过滤

思路:通过emit来给父组件传递自定义事件,在父组件中通郭computed(计算)计算属性来过滤

//TodoList.vue
emit:["changeActive"],
  methods:{
    changeActive(index){
        this.active=index;
        // <!-- emit的作用是触发自定义事件,携带事件名,并且传递参数 -->
        this.$emit('changeActive',index);
    }
  }
  //app.vue
  computed:{
    tasklist(){
      if(this.active === 0){
        return this.tasklist
      }else if(this.active === 1){
        return this.tasklist.filter(item =>item.isCompleted)
      }else{
        return this.tasklist.filter(item =>!item.isCompleted)
      }
    }
  },

C. AddTask.vue

代码:

<template>
  <div class="add">
    <div class="input-group mb-3">
      <input
        type="text"
        class="form-control"
        placeholder="请输入需要添加的任务"
        aria-label="Recipient's username"
        aria-describedby="basic-addon2"
        v-model="taskname"
      />
      <button class="btn-primary" @click="submit">提交</button>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    name: "addtask";
    return {
      taskname: "",
    };
  },
  emits:["addTask"],
  methods: {
    submit() {
        this.$emit('addTask',this.taskname)
        this.taskname=""
    },
  },
};
</script>
<style scoped>
.add{
    width: 500px;
    margin: auto;
}
</style>
代码解释

给按钮输入的数据绑定,同时绑定按钮提交事件,vue的双向数据绑定所以也是需要在data中绑定数据

//AddTask.vue
<div class="input-group mb-3">
      <input
        type="text"
        class="form-control"
        placeholder="请输入需要添加的任务"
        aria-label="Recipient's username"
        aria-describedby="basic-addon2"
        v-model="taskname"
      />
      <button class="btn-primary" @click="submit">提交</button>
    </div>
    

通过emit创建自定义事件,同时,通过点击事件触发向父组件传递自定义事件和参数,然后在app.vue
中把他加到tasklist中

//AddTask.vue
emits:["addTask"],
  methods: {
    submit() {
        this.$emit('addTask',this.taskname)
        this.taskname=""
    },
  }
  //app.vue
  //组件名
   <AddTask @addTask="addTask"/>
  addTask(taskname){
      this.tasklist.push({
        id:this.tasklist.length+1,
        task:taskname,
        isCompleted:false
      })
    }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT民工小新

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

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

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

打赏作者

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

抵扣说明:

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

余额充值