在vue2中实现

我们以 todoList 为案例展示如何在Vue2中实现派发器思想

编写视图

先创建所需要的文件

image-20220608090321634

index.vue

  1. <template>
  2. <div>
  3. <td-title :title="title" />
  4. <td-form />
  5. <td-list :todoData="todoData" />
  6. </div>
  7. </template>
  8. <script>
  9. import TdTitle from "./Title";
  10. import TdForm from "./Form";
  11. import TdList from "./List";
  12. export default {
  13. name: "TodoList",
  14. components: {
  15. TdTitle,
  16. TdForm,
  17. TdList,
  18. },
  19. data() {
  20. return {
  21. title: "Todo List",
  22. todoData: [],
  23. };
  24. },
  25. };
  26. </script>

Title.vue

  1. <template>
  2. <h1>{{ title }}</h1>
  3. </template>
  4. <script>
  5. export default {
  6. name: "TdTitle",
  7. props: {
  8. title: String,
  9. },
  10. };
  11. </script>

Form.vue

  1. <template>
  2. <div>
  3. <form>
  4. <input
  5. type="text"
  6. v-model.trim="todoText"
  7. placeholder="input what you wanna add!"
  8. />
  9. </form>
  10. </div>
  11. </template>
  12. <script>
  13. export default {
  14. name: "TdForm",
  15. data() {
  16. return {
  17. todoText: "",
  18. };
  19. },
  20. };
  21. </script>

List > index.vue

  1. <template>
  2. <div>
  3. <ul>
  4. <list-item
  5. v-for="item in todoData"
  6. :key="item.id"
  7. :item="item"
  8. />
  9. </ul>
  10. </div>
  11. </template>
  12. <script>
  13. import ListItem from "./ListItem";
  14. export default {
  15. name: "TdList",
  16. components: {
  17. ListItem,
  18. },
  19. props: {
  20. todoData: Array,
  21. },
  22. };
  23. </script>

List > ListItem.vue

  1. <template>
  2. <li>
  3. <input
  4. type="checkbox"
  5. :checked="item.completed"
  6. />
  7. <span :class="{ completed: item.completed }">
  8. {{ item.text }}
  9. </span>
  10. <button>删除</button>
  11. </li>
  12. </template>
  13. <script>
  14. export default {
  15. name: "ListItem",
  16. props: {
  17. item: Object,
  18. },
  19. };
  20. </script>
  21. <style>
  22. .completed {
  23. text-decoration: line-through;
  24. }
  25. </style>

编写好组件后我们就可以去派发器所需要的逻辑了

编写逻辑

首先在 src 下创建一个 actions 用来存放事件触发 type

image-20220608091557362

todoList.js

  1. export const
  2. ADD = 'ADD', // 添加待办的type
  3. REMOVE = 'REMOVE', // 删除待办的type
  4. COMPLETED = 'COMPLETED' // 切换待办状态的type

再创建一个 reducers 文件夹来存放所需的逻辑实现

image-20220608091904139

  1. export default function todoReducer(data) {
  2. /**
  3. * 添加待办事件
  4. * @param newItem 添加的事项数据
  5. * @returns 拼接好之后的待办列表
  6. */
  7. function addItem(newItem) {
  8. return data.concat(newItem)
  9. }
  10. /**
  11. * 根据id删除对应的待办
  12. * @param id 需要删除的待办id
  13. * @returns 删除之后的待办列表
  14. */
  15. function removeItem(id) {
  16. return data.filter(item => item.id !== id)
  17. }
  18. /**
  19. * 切换代办事项状态
  20. * @param id 需要切换状态待办事项的id
  21. * @returns 切换待办事项状态之后的待办列表
  22. */
  23. function changeCompleted(id) {
  24. return data.map(item => {
  25. if (item.id === id) {
  26. item.completed = !item.completed
  27. }
  28. return item
  29. })
  30. }
  31. return {
  32. addItem,
  33. removeItem,
  34. changeCompleted,
  35. }
  36. }

最后创建一个 dispatchers 文件夹来存放派发器

image-20220608112757687

  1. export default function todoReducer(data) {
  2. /**
  3. * 添加待办事件
  4. * @param newItem 添加的事项数据
  5. * @returns 拼接好之后的待办列表
  6. */
  7. function addItem(newItem) {
  8. return data.concat(newItem)
  9. }
  10. /**
  11. * 根据id删除对应的待办
  12. * @param id 需要删除的待办id
  13. * @returns 删除之后的待办列表
  14. */
  15. function removeItem(id) {
  16. return data.filter(item => item.id !== id)
  17. }
  18. /**
  19. * 切换代办事项状态
  20. * @param id 需要切换状态待办事项的id
  21. * @returns 切换待办事项状态之后的待办列表
  22. */
  23. function changeCompleted(id) {
  24. return data.map(item => {
  25. if (item.id === id) {
  26. item.completed = !item.completed
  27. }
  28. return item
  29. })
  30. }
  31. return {
  32. addItem,
  33. removeItem,
  34. changeCompleted,
  35. }
  36. }