自定义组件
TODOLIST
- 111
TodoList.vue
TODOLIST 示例,支持初始值、增删改查项 以及 过滤项
<script setup>
import { ref } from 'vue'
import Todos from '../components/Todos.vue';
const todos = ref([
{
id: 1,
checked: true,
title: '111'
}
]);
const handleAdd = (data) => {
// console.log('handleAdd', data);
const len = todos.value.length;
// 添加项
todos.value.push({
id: len + 1,
checked: false,
title: data
})
};
const handleRemove = (index) => {
// console.log('handleRemove', index)
// 移除当前项
todos.value.splice(index, 1)
};
</script>
<template>
<Todos :datas="todos" @add="handleAdd" @remove="handleRemove" />
</template>
Todos.vue
源码:
vue
<script setup>
import { ref, computed, useAttrs } from 'vue'
const attrs = useAttrs()
const datas = attrs.datas
const emits = defineEmits(['add', 'remove', 'update'])
const todoFilter = ref('')
const datasFilter = computed(() => {
return datas.filter((data) => data.title.includes(todoFilter.value))
})
const todo = ref('')
const handleAdd = () => {
if (todo.value === '') return
emits('add', todo.value)
todo.value = ''
todoFilter.value = ''
}
const handleRemove = (index) => {
emits('remove', index)
}
</script>
<template>
<div class="todo">
<form class="todo-action" @submit.prevent="handleAdd">
<label class="todo-label" for="todo">
<span>Add a todo:</span>
</label>
<input class="todo-input mr10" type="text" v-model.trim="todo" id="todo" placeholder="add" />
<button class="todo-btn" type="submit">Add</button>
</form>
<div class="todo-filter">
<input class="todo-input" type="text" v-model.trim="todoFilter" placeholder="filter" />
</div>
<ul class="todo-list">
<li
class="todo-list-item"
v-for="(todo, index) in datasFilter"
:key="todo.id"
:title="todo.title"
>
<input type="checkbox" v-model="todo.checked" @change="$emit('update', index)" />
<span :class="todo.checked ? 'checked' : ''">{{ todo.title }}</span>
<button class="todo-btn" type="button" @click="handleRemove(index)">Remove</button>
</li>
</ul>
</div>
</template>
<style lang="css">
.mr10 {
margin-right: 10px;
}
.todo-input {
border: 1px solid #ccc;
padding: 5px;
line-height: 1.4;
vertical-align: top;
}
.todo-btn {
border: 1px solid #ccc;
padding: 5px 10px;
line-height: 1.4;
}
.todo-filter {
margin: 10px 0;
}
.todo-list .todo-btn {
padding: 2px 5px;
}
.todo-list-item {
padding: 5px;
}
.todo-list-item span {
padding: 0 5px;
}
.todo-list-item .checked {
text-decoration: line-through;
color: red;
}
</style>