1.vue3.0容許在template裏寫多個根組件html
效果:vue
目錄結構:react
TodoList.vue:ide
<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>
Header.vue:code
<template> <div> <input type="text" :value="title" @input="handleTitle" @keyup.enter="handleAdd" autofocus placeholder="請輸入"> </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>
List.vue:component
<template> <div>正在進行({{ doningList.length }})</div> <ListItem v-for="item in doningList" :key="item.id" :item="item" @onChecked="handleChecked" @onDelete="handleDelete" ></ListItem> <div>已經完成({{ 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>
ListItem.vue:htm
<template> <div> <input type="checkbox" :id="item.id" :checked="item.done" @change="handleChange"/> <label :for="item.id">{{item.title}}</label> <button @click="handleDelete">刪除</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>
參考連接:blog
http://www.todolist.cn/ip