Vue 和 Vuex 中的排序

问题描述 投票:0回答:1

我正在尝试让我的新任务按优先级或最新任务排序。我从 vue 迁移了原始项目并添加了 vuex 进行练习,但它不再起作用。

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>

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()
    }
  }
})

我可以看到当创建新任务时,它显示了两个值。我尝试了多种编写sortedTasks函数的方法,但我似乎无法让任何东西工作,并且我没有抛出任何错误。

vue.js sorting vuex
1个回答
0
投票

输入和标签看起来排序正确。问题仅与 div 中的文本插值有关吗? v-for 正在

sortedTasks
getter 上循环,但您显示的是未排序的
$store.state.tasks

<div
  v-for="(task, i) in $store.getters.sortedTasks"
  :class="`task-item ${task.done && 'done'}`"
>
  {{ $store.state.tasks }}

  ...

</div>

显示实际的sortedTasks对象,例如

{{ $store.getters.sortedTasks }}
,或每个循环的单独任务,例如
{{ task }}

当我在 codesandbox

中运行代码时效果很好
© www.soinside.com 2019 - 2024. All rights reserved.