vue3入门11 - 组件化 todoMvc 项目-拆分需求

259 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情

前言

我们已经完成了整个todoMvc项目迁移使用脚手架的需求。接下来我们要对组件进行拆分。主要包括以下需求:

  • 头部组件
    • 全选操作组件
    • 输入框组件
  • 主体内容
    • 主体内容容器组件
    • todos列表组件
  • 底部组件
    • 数量显示组件
    • 操作组件
    • 清空按钮

那么接下来就让我们开始吧。

头部组件

  • 头部组件包括两部分:全选操作、输入框,需要写两个组件

输入框

  • 首先,vue3中已经不限制一个组件只能有一个自定义v-model了,我们可以通过update:xxx来更新对应的值。
  • 我们这里为了让todos能在组件上响应式更新,采用了自定义v-model,通过computed的get函数接收props的值,set函数更新props的值,达到自定义v-model的效果。可以查看相关文档的使用方式
  • 我们发送的emit事件,需要通过emits先定义好,再进行使用,不然会直接报错说找不到相关事件,这样也方便我们知道组件中定义了多少自定义事件。
  • Header.vue
<template>
  <header class="header">
    <h1>todos</h1>
    <input
      v-model.trim="input"
      @keyup.enter="addTodo"
      class="new-todo"
      placeholder="你需要做什么"
      autocomplete="off"
      autofocus
    />
  </header>
</template>
<script>
import { computed, ref, toRefs, defineComponent } from 'vue';
export default defineComponent({
  props: {
    todos: String
  },
  emits: ['update:todos'],
  setup(props, { emit }) {
    const { todos } = toRefs(props);
    const input = ref('');
    const todosValue = computed({
      get: () => todos.value,
      set: (v) => {
        emit('update:todos', v);
      }
    });
    const addTodo = () => {
      const text = input.value;
      if (!text) return;
      todosValue.value.push({ id: todosValue.value.length + 1, text, completed: false });
      input.value = '';
    };

    return {
      input,
      addTodo
    };
  }
});
</script>
  • 使用
<Header v-model:todos="todos" />

全选操作

  • 全选操作需要处理的也是自定义v-model
  • CheckAll.vue
<template>
  <input v-model="allDoneValue" id="toggle-all" class="toggle-all" type="checkbox" />
  <label for="toggle-all">点击完成所有事项</label>
</template>
<script>
import { computed, defineComponent } from 'vue';
export default defineComponent({
  props: {
    allDone: Boolean
  },
  emits: ['update:allDone'],
  setup(props, { emit }) {
    const allDoneValue = computed({
      get() {
        return props.allDone;
      },
      set(value) {
        emit('update:allDone', value);
      }
    });
    return { allDoneValue };
  }
});
</script>
  • 使用
<CheckAll v-model:allDone="allDone" />

总结

这一节我们对整体的组件拆分需求做了梳理,然后对头部组件做了对应的封装。

项目代码在GitHub,可以查阅