案例用到的知识点如下:
① vite 创建项目
② 组件的封装与注册
③ props
④ 样式绑定
⑤ 计算属性
⑥ 自定义事件
⑦ 组件上的 v-model
效果如下图;
页面2
项目结构:
初始化项目
在终端运行以下的命令,初始化 vite 项目:
npm init vite-app todos
使用 vscode 打开项目,并安装依赖项:
npm install
安装 less 语法相关的依赖项:
npm i less -D
重置 index.css 中的全局样式如下:
:root {font-size: 12px; }
body {padding: 8px;}
在终端运行以下的命令,把项目运行起来:
npm run dev
mian.js
import { createApp } from 'vue'
import App from './App.vue'// 导入bootstrap
import './assets/css/bootstrap.css'
import './index.css'createApp(App).mount('#app')
app.vue
<template><ul class="list-group container"><li class="list-group-item active" aria-current="true">星月事务管理</li></ul>
<div class="container container1"><todoInput @add="getadd"></todoInput><todo-list :list="taskList"></todo-list><todoButton :addb="mbstatus" @addb="onsta" v-model:addb="onsta"></todoButton>
</div>
</template><script>
import todoList from './components/todolist/todolist.vue'
import todoInput from './components/todoinput/todoinput.vue'
import todoButton from './components/todobutton/todobutton.vue'export default {name: 'MyApp',components:{todoList,todoInput,todoButton},data() {return{nextid:6,mbstatus:0,todoList:[{ id:1,task:'周一早晨9点开会',done:false },{ id:2,task:'周二早晨9点开会',done:true },{ id:3,task:'周三早晨9点开会',done:false },{ id:4,task:'周四早晨9点开会',done:true },{ id:5,task:'周五睡觉',done:true },]}},methods:{// 把输入框的信息添加到todolist中getadd(e){this.todoList.push({id:this.nextid,task:e,done:false})this.nextid++},// 接收子组件传递的状态,并赋值给按钮的状态,实现按钮的切换onsta(e){// console.log(e)this.mbstatus = e}},computed:{taskList(){// if ---else方法// if(this.mbstatus === 0) {// return this.todoList// }else if(this.mbstatus === 1){// return this.todoList.filter(x=>x.done)// }else{// return this.todoList.filter(x=>!x.done)// }// switch --- case 方法switch(this.mbstatus){case 0: {return this.todoList}case 1:{return this.todoList.filter(x=>x.done)}case 2:{return this.todoList.filter(x=>!x.done)}}}}
}
</script>
<style lang="less" scoped>
.list-group{max-width: 400px;text-align: center;
}
.container1{margin-top: 20px;
}
</style>
页面切换状态的按钮组件:todobutton.vue
<template>
<div class="btn-group container" role="group" aria-label="Basic example"><button type="button" class="btn" :class="addb===0?'btn-primary':'btn-secondary'" @click="onsta(0)">全部</button><button type="button" class="btn" :class="addb===1?'btn-primary':'btn-secondary'" @click="onsta(1)">已完成</button><button type="button" class="btn" :class="addb===2?'btn-primary':'btn-secondary'" @click="onsta(2)">未完成</button>
</div>
</template><script>
export default {name:'TodoButton',// 自定义需要绑定的事件addbemits:['addb'],props:{addb:{type:Number,required:true,default:0}},methods:{// 把当前点击按钮的状态传递给app父组件// 通过$emit自定义事件子传父,实现双向绑定onsta(e){// console.log(e)if(e === this.addb)returnthis.$emit('addb',e)}}
}
</script><style lang="less" scoped>
.btn-group{max-width: 400px;margin-top: 20px;text-align: center;
}
</style>
渲染事务列表组件: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-switch"><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 ?'ftdelete':''">{{ 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',data(){return{ftdelete:'ftdelete'}},props:{list:{type:Array,required:true,default:[]}},// created(){// this.list.forEach(e=>{// // console.log(e)// if( e.done === true ){// e.done = false// }else{// e.done = true // }// })// }
}
</script><style lang="less" scoped>
.list-group{max-width: 400px;.ftdelete{text-decoration: line-through;}
}
</style>