我正在尝试让我的新任务按优先级或最新任务排序。我从 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函数的方法,但我似乎无法让任何东西工作,并且我没有抛出任何错误。
输入和标签看起来排序正确。问题仅与 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
中运行代码时效果很好