You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue迁移Vuex后任务按优先级/最新时间排序功能失效求助

问题:迁移Vuex后任务排序功能失效

将原有Vue项目引入Vuex后,任务按优先级或创建时间排序的功能完全失效。添加新任务能正常显示对应数据,但无论怎么编写sortedTasks函数都无法实现排序效果,且控制台无任何报错信息。


组件代码(Vue)

import '@/assets/main.css'
import { computed } from 'vue'
import { useStore } from 'vuex'

export default {
  computed: {
    inputTitle: {
      get() {
        return this.$store.state.inputTitle
      },
      set(value) {
        this.$store.commit('SET_INPUT_TITLE', value)
      }
    },
    inputContent: {
      get() {
        return this.$store.state.inputContent
      },
      set(value) {
        this.$store.commit('SET_INPUT_CONTENT', value)
      }
    },
    inputCategory: {
      get() {
        return this.$store.state.inputCategory
      },
      set(value) {
        this.$store.commit('SET_INPUT_CATEGORY', value)
      }
    },
    sortingOptions: {
      get() {
        return this.$store.state.sortingOptions
      },
      set(value) {
        this.$store.commit('SET_SORTING_OPTION', value)
      }
    }
  },
  methods: {
    addTask() {
      this.$store.dispatch('addTask')
    },
    removeTask(task) {
      this.$store.commit('REMOVE_TASK', task)
    },
    updateSortingOption() {
      this.$store.commit('SET_SORTING_OPTION', this.sortingOptions)
    }
  }
}
</script>

<template>
  <main class="app">
    <section class="greeting">
      <h2 class="title">Welcome Back</h2>
    </section>

    <!-- Task Section -->
    <section class="create-task">
      <h3>CREATE A TASK</h3>

      <form id="new-task-form" @submit.prevent="addTask">
        <h4>What's on your task list?</h4>
        <input
          type="text"
          name="title"
          id="title"
          placeholder="Title of task"
          v-model="inputTitle"
        />
        <input
          type="text"
          name="content"
          id="content"
          placeholder="e.g. code todo app"
          v-model="inputContent"
        />

        <!-- Priority Selector -->
        <h4>Priority</h4>
        <div class="options">
          <label>
            <input type="radio" name="category" value="high" v-model="inputCategory" />
            <span class="bubble high"></span>
            <div>High</div>
          </label>

          <label>
            <input type="radio" name="category" value="medium" v-model="inputCategory" />
            <span class="bubble medium"></span>
            <div>Medium</div>
          </label>

          <label>
            <input type="radio" name="category" value="low" v-model="inputCategory" />
            <span class="bubble low"></span>
            <div>Low</div>
          </label>
        </div>
        <!-- Dropdown to select sorting option -->
        <input type="submit" value="Add task" />
      </form>

      <div>
        <label class="sort" for="sort-select">Sort by:</label>
        <select id="sort-select" v-model="sortingOptions">
          <option value="created_at">Most Recent</option>
          <option value="priority">Priority</option>
        </select>
      </div>
    </section>

    <!-- New Task Handler -->

    <section class="task-list">
      <h3>TASK LIST</h3>
      <div class="list" id="task-list">
        <div
          :key="i"
          v-for="(task, i) in $store.getters.sortedTasks"
          :class="`task-item ${task.done && 'done'}`"
        >
          {{ $store.state.tasks }}
          <label>
            <input type="checkbox" v-model="task.done" />
            <span
              :class="`bubble ${task.category === 'high' ? 'high' : task.category === 'medium' ? 'medium' : 'low'}`"
            ></span>
          </label>
          <div class="task-content">
            <div>
              <div class="inputContent" value="inputContent"></div>
            </div>
            <input type="text" v-model="task.title" />

            <input type="text" v-model="task.content" />
          </div>
          <div class="actions">
            <button class="delete" @click="removeTask(task)">Delete</button>
          </div>
        </div>
      </div>
    </section>
  </main>
  <RouterView />
</template>

Vuex Store代码

export default createStore({
  state: {
    tasks: [],
    inputTitle: '',
    inputContent: '',
    inputCategory: null,
    sortingOptions: 'created_at'
  },
  mutations: {
    ADD_TASK(state, task) {
      state.tasks.push(task)
      // console.log(task)
    },
    REMOVE_TASK(state, task) {
      state.tasks = state.tasks.filter((t) => t !== task)
    },
    SET_INPUT_TITLE(state, title) {
      state.inputTitle = title
    },
    SET_INPUT_CONTENT(state, content) {
      state.inputContent = content
    },
    SET_INPUT_CATEGORY(state, category) {
      state.inputCategory = category
    },
    SET_SORTING_OPTION(state, category) {
      state.sortingOptions = category
    }
  },
  actions: {
    addTask({ commit, state }) {
      if (state.inputContent.trim() === '' || state.inputCategory === null) {
        return
      }

      const newTask = {
        title: state.inputTitle,
        content: state.inputContent,
        category: state.inputCategory,
        done: false,
        editable: false,
        createdAt: new Date().getTime()
      }

      commit('ADD_TASK', newTask)
      commit('SET_INPUT_TITLE', '')
      commit('SET_INPUT_CONTENT', '')
      commit('SET_INPUT_CATEGORY', null)
      commit('SET_SORTING_OPTION', null)
    }
  },
  getters: {
    sortedTasks(state) {
      if (state.sortingOptions === 'created_at') {
        // Sort by createdAt timestamp
        return state.tasks.slice().sort((a, b) => a.createdAt - b.createdAt)
      } else if (state.sortingOptions === 'priority') {
        // Sort by priority (high > medium > low)
        const priorityOrder = { high: 1, medium: 2, low: 3 }
        return state.tasks.slice().sort((a, b) => {
          return priorityOrder[a.category] - priorityOrder[b.category]
        })
      }
      return state.tasks.slice()
    }
  }
})

问题根源及修复方案

1. 添加任务后排序选项被重置为null

在addTask Action的最后,错误执行了commit('SET_SORTING_OPTION', null),导致sortingOptions被设为null,sortedTasks getter中的两个排序条件都不匹配,直接返回未排序的任务数组。
修复:删除该行代码,保留当前排序选项。

2. 创建时间排序方向错误

当前created_at排序逻辑是a.createdAt - b.createdAt,会让最早创建的任务排在前面,与“Most Recent(最新)”的预期相反。
修复:改为b.createdAt - a.createdAt,实现最新任务在前的排序效果。

3. 冗余调试代码干扰页面

模板中{{ $store.state.tasks }}会直接渲染整个任务数组,属于调试残留,需删除避免影响展示。

4. 无用方法可移除

组件中的updateSortingOption方法无实际作用,因为select已经通过v-model="sortingOptions"自动触发mutation更新状态,可直接删除。


修复后的关键代码片段

修复后的Vuex Action

actions: {
  addTask({ commit, state }) {
    if (state.inputContent.trim() === '' || state.inputCategory === null) {
      return
    }

    const newTask = {
      title: state.inputTitle,
      content: state.inputContent,
      category: state.inputCategory,
      done: false,
      editable: false,
      createdAt: new Date().getTime()
    }

    commit('ADD_TASK', newTask)
    commit('SET_INPUT_TITLE', '')
    commit('SET_INPUT_CONTENT', '')
    commit('SET_INPUT_CATEGORY', null)
    // 移除错误的排序选项重置
    // commit('SET_SORTING_OPTION', null)
  }
}

修复后的Getter

getters: {
  sortedTasks(state) {
    if (state.sortingOptions === 'created_at') {
      // 修改为降序,最新任务在前
      return state.tasks.slice().sort((a, b) => b.createdAt - a.createdAt)
    } else if (state.sortingOptions === 'priority') {
      const priorityOrder = { high: 1, medium: 2, low: 3 }
      return state.tasks.slice().sort((a, b) => {
        return priorityOrder[a.category] - priorityOrder[b.category]
      })
    }
    return state.tasks.slice()
  }
}

修复后的模板片段

<div
  :key="i"
  v-for="(task, i) in $store.getters.sortedTasks"
  :class="`task-item ${task.done && 'done'}`"
>
  <!-- 移除调试用的数组渲染代码 -->
  <label>
    <input type="checkbox" v-model="task.done" />
    <span
      :class="`bubble ${task.category === 'high' ? 'high' : task.category === 'medium' ? 'medium' : 'low'}`"
    ></span>
  </label>
  <!-- 其余内容不变 -->
</div>

内容的提问来源于stack exchange,提问作者Colton Skiera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:20:10