1. Vue3.0 allows you to write multiple root components in a template
Effect:
Directory structure:
TodoList.vue:
<template>
<Header @onAdd="handleAdd"></Header>
<List
:list="state.list"
@onChecked="handleChecked"
@onDelete="handleDelete"
></List>
</template>
<script>
import { reactive } from "vue";
import Header from ".. /components/Header";
import List from ".. /components/List";
export default {
components: {
Header,
List,
},
setup() {
const state = reactive({
list: [],});const handleAdd = (title) = > {
state.list.push({
id: Date.now(),
title,
done: false}); };const handleChecked = (payload) = > {
let index = state.list.findIndex((item) = > item.id === payload.id);
state.list[index].done = payload.checked;
};
const handleDelete = (payload) = > {
state.list = state.list.filter((item) = >item.id ! == payload.id); };return{ state, handleAdd, handleChecked, handleDelete, }; }};</script>
<style>
</style>
Copy the code
Header.vue:
<template>
<div>
<input type="text" :value="title" @input="handleTitle" @keyup.enter="handleAdd" autofocus placeholder="Please enter">
</div>
</template>
<script>
import { ref } from 'vue'
export default {
emits: ['onAdd'].setup(props, context) {
const title = ref(' ')
const handleTitle = (e) = > {
title.value = e.target.value
}
const handleAdd = () = > {
context.emit('onAdd', title.value)
title.value = ' '
}
return {
title,
handleTitle,
handleAdd
}
}
}
</script>
<style>
</style>
Copy the code
List.vue:
<template>
<div>In progress ({{doninglist.length}})</div>
<ListItem
v-for="item in doningList"
:key="item.id"
:item="item"
@onChecked="handleChecked"
@onDelete="handleDelete"
></ListItem>
<div>Done ({{donelist.length}})</div>
<ListItem
v-for="item in doneList"
:key="item.id"
:item="item"
@onChecked="handleChecked"
@onDelete="handleDelete"
></ListItem>
</template>
<script>
import { computed } from "vue";
import ListItem from "./ListItem";
export default {
props: ["list"].components: {
ListItem,
},
setup(props, context) {
const doningList = computed(() = > {
return props.list.filter((item) = >! item.done); });const doneList = computed(() = > props.list.filter((item) = > item.done));
const handleChecked = (payload) = > {
context.emit("onChecked", payload);
};
const handleDelete = (payload) = > context.emit("onDelete", payload);
return{ doningList, doneList, handleChecked, handleDelete, }; }};</script>
<style>
</style>
Copy the code
ListItem.vue:
<template>
<div>
<input type="checkbox" :id="item.id" :checked="item.done" @change="handleChange"/>
<label :for="item.id">{{item.title}}</label>
<button @click="handleDelete">delete</button>
</div>
</template>
<script>
export default {
props: ['item'].setup(props, context) {
const handleChange = (e) = > {
context.emit('onChecked', { id: props.item.id, checked: e.target.checked })
}
const handleDelete = () = > {
context.emit('onDelete', { id : props.item.id })
}
return {
handleChange,
handleDelete
}
}
}
</script>
<style>
</style>
Copy the code
Reference links:
www.todolist.cn/