Tengo un componente Vue para mostrar una lista de datos. Debería recibir los data y sortBy como accesorios y renderizarse correctamente. Sin embargo, tengo un botón adicional en el componente que quiero actualizar sortBy y volver a mostrar la nueva lista, pero no sé cómo asignar nuevos datos a la propiedad calculada sortedData . Muchas gracias si puedo tener algunos consejos.
<template> <div> <template v-for="(item, index) in sortedData" :key="index"> {{ item.name }} </template> <button @click.prevent="sortWith('color')">sort Color</button> </div> </template> <script> export default { props: { data: { type: Array, default: [] }, sortBy: { type: String, default: 'name' }, }, methods: { sort(array, sortBy) { return array.sort(function (a, b) { return b[sortBy] - a[sortBy] }) }, sortWith(sortBy) { // Need to sort the list and re-render new order } } computed: { sortedData() { return this.sort(this.data, this.sortBy) } } } </script>Prueba como el siguiente fragmento:
const app = Vue.createApp({ data() { return { items: [{name: 'aaa', color: 'red'}, {name: 'ccc', color: 'purple'}, {name: 'fff', color: 'yellow'}, {name: 'bbb', color: 'blue'}, {name: 'eee', color: 'green'}], sortingBy: 'name', sortingOrder: false } }, methods: { setSorting(item) { this.sortingBy = item this.sortingOrder = !this.sortingOrder } } }) app.component('child', { template: ` <div> <template v-for="(item, index) in sortedData" :key="index"> <div>{{ item.name }} - {{ item.color }}</div> </template> <div class="sort"> <p>Sort By (child) :</p> <div v-for="(title, i) in Object.keys(data[0])" :key="i" class="fields"> <a href="#" @click="sorting(title)">{{ title }}</a> </div> </div> </div> `, props: { data: { type: Array, default: [] }, sortBy: { type: String, default: 'name' }, sortOr: { type: String, default: false }, }, data() { return { sortField: this.sortBy, sortOrder: this.sortOr } }, methods: { sort(array, sortBy) { return array.sort((a, b) => { let x = a[sortBy].toLowerCase() let y = b[sortBy].toLowerCase() if (this.sortOrder) { return x > y ? -1 : 1; } else { return x > y ? 1 : -1; } return 0 }) }, sorting(item) { this.sortField = item this.sortOrder = !this.sortOrder } }, computed: { sortedData() { return this.sort(this.data, this.sortField) } }, watch: { sortBy: function (val) { this.sortField = val }, sortOr: function (val) { this.sortOrder = val }, } }) app.mount('#demo') .sort { display: flex; align-items: center; } .fields { margin-left: 1em; } <script src="https://unpkg.com/vue@3.2.29/dist/vue.global.prod.js"></script> <div id="demo"> <div class="sort"> <p>Sort By (parent) :</p> <div v-for="(title, i) in Object.keys(items[0])" :key="i" class="fields"> <a href="#" @click="setSorting(title)">{{ title }}</a> </div> </div> <child :data="items" :sort-by="sortingBy" :sort-or="sortingOrder"></child> </div>