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/