javascript - _.orderBy 不在 Vue 中按列排序
问题描述
在 Vue2 中,当我在选择中选择一列时,我想按列对我的测验数组进行排序。但是当我更改选择时 _.orderBy (lodash) 不会排序,它会调整 sortDirection。orderBy 在 sortDirection 更改时执行。我没有错误。有谁知道我做错了什么?提示表示赞赏!
Vue组件
<template>
<div class="py-6">
<div class="max-w-7xl mx-auto lg:px-8">
<div class="mt-5 flex lg:mt-0">
<span class="block w-1/5">
<input v-model="search" autocomplete="no"
class="ml-3 border border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm rounded-md"
placeholder="Zoek hier naar quizzen..."
type="text">
</span>
<span class="block">
<select v-model="sortProperty"
class="ml-6 block w-full py-2 px-4 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
name="sortBy">
<option value="name">Naam</option>
<option value="playdate">Speeldatum</option>
</select>
</span>
<span class="block">
<button
class="ml-9 inline-flex justify-center py-2 border border-transparent text-sm font-medium rounded-md text-gray-500 focus:outline-none"
type="button" @click="sortDirection === 'asc' ? sortDirection = 'desc' : sortDirection = 'asc'">
<svg v-if="sortDirection === 'asc'" class="h-5 w-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path d="M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12" stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"/>
</svg>
<svg v-if="sortDirection === 'desc'" class="h-5 w-5 mr-3" fill="none" stroke="currentColor"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4" stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"/>
</svg>
</button>
</span>
</div>
<div v-for="quiz in filteredQuizzes" v-if="filteredQuizzes.length > 0"
class="bg-white rounded-lg shadow-sm duration-500 px-2 sm:px-6 md:px-2 py-4 my-6">
<div class="grid grid-cols-12 gap-3">
<div class="col-span-12 sm:col-start-3 sm:col-end-13 px-3 sm:px-0">
<div class="mt-2">
<a class="sm:text-sm md:text-md lg:text-lg text-gray-700 font-bold">
{{ quiz.name }}
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import _ from 'lodash';
import axios from "axios";
export default {
data() {
return {
search: '',
sortProperty: 'name',
sortDirection: 'asc',
quizzes: [],
}
},
computed: {
filteredQuizzes() {
let quizzes = this.quizzes.filter(quiz => quiz.name.toLowerCase().includes(this.search.toLowerCase()))
return _.orderBy(quizzes, this.sortProperty, this.sortDirection)
}
},
created() {
this.fetchQuizzes();
},
methods: {
fetchQuizzes() {
axios.get('/quizzes').then(({data}) => (this.quizzes = data));
},
},
name: "Quizzes"
}
</script>
解决方案
编辑版
Vue.component("QuizItem", {
props: ["name", "otherVar"],
template: `
<div>
Name: {{ name }}<br>
Other var: {{ otherVar }}<br>
<hr />
</div>
`
})
new Vue({
el: "#app",
data() {
return {
search: "",
sortDirection: "asc",
sortProperty: "name",
quizzes: [{
name: "Quiz 34",
otherVar: "DEF",
},
{
name: "Quiz 23",
otherVar: "GHI",
},
{
name: "Quiz 12",
otherVar: "JKL",
},
{
name: "Quiz 45",
otherVar: "ABC",
},
]
}
},
computed: {
filteredQuizzes() {
let quizzes = this.quizzes.filter(quiz => quiz.name
.toLowerCase()
.includes(
this.search.toLowerCase()
))
quizzes = _.orderBy(
quizzes, [this.sortProperty], [this.sortDirection]
)
return quizzes
},
},
template: `
<div
class="container"
>
<div class="quizzes col">
<h4>FULL LIST:</h4>
<quiz-item
v-for="quiz in quizzes"
:key="quiz.name"
v-bind="quiz"
/>
</div>
<div class="quizzes col">
<h4>FILTERED LIST:</h4>
<quiz-item
v-for="quiz in filteredQuizzes"
:key="quiz.name"
v-bind="quiz"
/>
</div>
<div class="filters col">
<h4>CONTROLS</h4>
<div>
<span>Settings:</span>
{{ search }}, {{ sortProperty }}, {{ sortDirection }}
</div>
<hr>
<label>
Search:
<input type="text" v-model="search" />
</label>
<label>
Sort property:
<select v-model="sortProperty">
<option value="name">Name</option>
<option value="otherVar">Other var</option>
</select>
</label>
<label>
Sort direction:
<select v-model="sortDirection">
<option value="asc">ASC</option>
<option value="desc">DESC</option>
</select>
</label>
</div>
</div>
`
})
.container {
display: flex;
}
.col {
width: 33%;
padding: 8px 16px;
}
label {
display: block;
padding-bottom: 8px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<div id="app"></div>
试试上面的代码片段——它有效。问题出在这一行:
return _.orderBy(quizzes, this.sortProperty, this.sortDirection)
// this should be this:
return _.orderBy(quizzes, [this.sortProperty], [this.sortDirection])
原因是它_.orderBy()
接受一个属性名称列表(数组),它将通过它对数组进行排序,以及另一个控制排序方向的列表(与属性名称的顺序相同)。这两个参数都应该是Array
s,即使你只设置了 1 个属性和 1 个对应的排序方向。
推荐阅读
- react-native - react native - 为什么我的 console.log 返回 [] 但项目会在屏幕上呈现?
- python - 成功 url 在我基于类的 DeleteView 中不起作用
- python - Python Regex 检测字母之间的下划线
- php - 验证单个产品页面中“添加到购物车”上方添加的自定义字段
- javascript - 使用 Google API 自动完成用户地址字段
- python - 在 Mongoengine 中填充,参考字段
- github - GitHub Action - 从分支 A 推送到分支 B 时触发,但不分支到分支 B
- sql - 根据时间值折叠多行
- c# - 对 C# 中的返回方法和 void 感到困惑
- laravel - 如何为 spatie/laravel-permission 合同/权限制作包装器?