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.
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!