[Vuejs]-How to client-side sort inertia data?

3👍

<script setup>
import { ref, computed } from "vue";
const props = defineProps({ data: Object });
const sortByScore = ref(true);
const sortBy = computed(() => (sortByScore.value ? "score" : "name"));
const sortedData = computed(() =>
  Object.values(props.data).sort((a, b) => b[sortBy.value] - a[sortBy.value])
);
</script>

And link sortByScore to the checkbox.


I don’t like having to deal with .value in my controllers, so I’d write it as:

import { reactive, computed, toRefs } from "vue";
const props = defineProps({ data: Object });
const state = reactive({
  sortByScore: true,
  sortBy: computed(() => (state.sortByScore ? "score" : "name")),
  sortedData: computed(() =>
    Object.values(props.data).sort((a, b) => b[state.sortBy] - a[state.sortBy])
  ),
});


// expose state, so you don't have to use `state.sortedData` in `<template>`
const { sortByScore, sortBy, sortedData } = toRefs(state);

I find reactive() syntax cleaner, especially in large controllers.
Another advantage of this syntax is you can type the state using only one interface.

Another thing I’ve seen others do is to name state as S and no longer unwrap it for <template>. Just use it as S.sortByScore, S.sortedData, etc.
This way you don’t have to re-type all the keys you want exposed. Sometimes I wish there was an equivalent for return {...toRefs(state)} in <script setup>.


Note: the above transforms your data from Object to Array. It’s the only way to guarantee the order of elements. Object props can’t be reliably sorted in JavaScript.

👤tao

2👍

Give a try to computed property

<script setup>
import { computed } from 'vue'
const props = defineProps({ data: Object })

const sortedData = computed(() => Object(props.data.value).sort((a, b) => b.score - a.score))
</script>

Also, in your v-for don’t forget the :key with a UUID preferably!

👤kissu

Leave a comment