目录
项目结构
创建todolist组件
创建todoinput组件
项目结构
今天用 vite 脚手架搭建一个 vue3 的小案例,vite的搭建过程参考:vite的搭建 。其项目结构组件构成如下:注意:因为使用的是 vite 框架,使用less样式需 npm i less -D 进行下载一下
在输入框输入信息之后,会加载到数组里面,在底部的按钮进行选择已完成和未完成的情况。
项目案例书写的样式是借助 bootstrap 样式的,不清楚如何使用请翻阅这篇文章:文章链接
创建todolist组件
我们根据App根组件中data里面return过来的列表数据循环遍历到todolist组件里面,借助bootstrap里面的列表组里面的样式遍历到页面即可,如下:
<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">{{ 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:'MyList',
props:['list']
}
</script>
<style lang="less" scoped>
.list-group{
width: 400px;
}
</style>
当我们选中复选框时,我们去呈现一个文字被滑横线以及字体改变的效果,这里借助 v-bind 属性去动态绑定,借助 三元运算符 去实现即可,如下:
至此,todolist的基本功能已经实现。
创建todoinput组件
创建该组件依然借助 bootstrap 里面的样式,如下:
将样式直接粘到todoinput组件里面,进行一定的修改,如下:
<template>
<form class="form-inline">
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<div class="input-group-text">任务</div>
</div>
<input type="text" class="form-control" placeholder="请输入任务" style="width:356px">
</div>
<button type="submit" class="btn btn-primary mb-2">添加新任务</button>
</form>
</template>
接下来通过自定义事件,将todoinput里面的input输入的数据传递到根组件App上,如下:
给表单添加提交按钮,将input输入框输入的数据通过自定义事件传递给父组件身上。
<template>
<form class="form-inline" @submit.prevent="onFormInput">
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<div class="input-group-text">任务</div>
</div>
<input type="text" class="form-control" placeholder="请输入任务" style="width:356px" v-model="taskname">
</div>
<button type="submit" class="btn btn-primary mb-2">添加新任务</button>
</form>
</template>
<script>
export default {
name:'MyInput',
data(){
return {
taskname:''
}
},
emits:['add'],
methods:{
onFormInput(){
if(!this.taskname) return alert('列表不能为空!')
this.$emit('add', this.taskname);
this.taskname = ''
}
}
}
</script>
<style lang="less" scoped>
</style>
创建todobutton组件
创建该组件依然借助 bootstrap 里面的样式,如下:
将样式直接粘到该组件上,进行一定的修改,如下:
通过自定义事件,将 index 的值传递给根组件App上。
<template>
<div class='btn-container mt-3'>
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn" :class="active===0 ? 'btn-primary' : 'btn-secondary'" @click="onClick(0)">全部</button>
<button type="button" class="btn" :class="active===1 ? 'btn-primary' : 'btn-secondary'" @click="onClick(1)">已完成</button>
<button type="button" class="btn" :class="active===2 ? 'btn-primary' : 'btn-secondary'" @click="onClick(2)">未完成</button>
</div>
</div>
</template>
<script>
export default {
name:'MyButton',
props:{
active:{
type:Number,
required:true,
default:0
}
},
emits:['update:active'],
methods:{
onClick(index){
if(index==this.active) return
this.$emit('update:active',index)
}
}
}
</script>
<style lang="less" scoped>
.btn-container{
width: 400px;
text-align: center;
}
</style>
App根组件拿到index值,通过计算属性来判断按钮点击时的activeIndexBtn的值,来呈现不同的内容。
<template>
<div>
<TodoInput @add="onAddTaskname"></TodoInput>
<Todolist :list="todotask"></Todolist>
<TodoButton v-model:active="activeIndexBtn"></TodoButton>
</div>
</template>
<script>
import TodoInput from './components/to-do/todoinput/TodoInput.vue'
import Todolist from './components/to-do/todolist/Todolist.vue'
import TodoButton from './components/to-do/todobutton/TodoButton.vue'
export default {
data(){
return {
todolist:[
{id:1,task:'吃早餐',done:false},
{id:2,task:'吃午餐',done:true},
{id:3,task:'吃晚餐',done:false}
],
nextid:4,
activeIndexBtn:0
}
},
methods:{
onAddTaskname(taskname){
this.todolist.push({
id:this.nextid,
task:taskname,
done:false
})
this.nextid++
}
},
computed:{
todotask(){
switch(this.activeIndexBtn){
case 0:
return this.todolist
case 1:
return this.todolist.filter(x => x.done === true)
case 2:
return this.todolist.filter(x => x.done === false)
}
}
},
components:{
Todolist,TodoInput,TodoButton
}
}
</script>
<style>
</style>
至此,三个组件封装完成,案例的具体结构如下: