对 vue 3 v-for 表组合 api 进行排序

Dej*_*mes 6 sorting vue.js vuejs3 vue-composition-api

我已使用以下代码成功创建了对象数组的表:

      <div class="table-responsive">
    
                <table  ref="tbl" border="1" class="table"> 
                    <thead>
             <tr>
               
                <th  scope="col" @click="orderby('b.property')">Property</th>
                 <th  scope="col"> Price </th>
                 <th  scope="col"> Checkin Date </th>
                 <th  scope="col"> Checkout Date </th>
                 <th scope="col" > Beds </th>
             </tr>
         </thead>
         <tbody>
            <tr scope="row" class="table-bordered table-striped" v-for="(b, index) in properties" :key="index">
                
                <td> {{b.property}} </td>
                <td> {{b.pricePerNight}}</td>
                <td> {{b.bookingStartDate}} </td> 
                <td> {{b.bookingEndDate}} <br> {{b.differenceInDays}} night(s)  </td> 
                <td> {{b.beds}} </td> 
    
            </tr>
         </tbody>
     </table>
      </div>


    <script>

    import {ref} from "vue";
    import { projectDatabase, projectAuth, projectFunctions} from '../../firebase/config'
    import ImagePreview from "../../components/ImagePreview.vue"
    
    export default {
      components: {
        ImagePreview
      },
      setup() {
    
    const properties = ref([]);
    
    //reference from firebase for confirmed bookings
           const Ref = projectDatabase .ref("aref").child("Accepted Bookings");
                Ref.on("value", (snapshot) => {
          properties.value = snapshot.val();
        
        });

        //sort table columns
       const orderby = (so) =>{
        desc.value = (sortKey.value == so)
        sortKey.value = so
        }
      
         return {
          properties,
orderby
        };
      },
    };
    </script>
Run Code Online (Sandbox Code Playgroud)

有没有办法让每列按字母顺序(或数字或日期的数字顺序)排序?我尝试了一个简单的 @click 函数,该函数可以按属性排序,但不起作用

wit*_*ein 5

您可以创建一个计算属性并返回排序后的数组。

这只是一个快速演示,给您举个例子。

Vue.createApp({
  data() {
    return {
      headers: ['name', 'price'],
      properties: [
        {
          name: 'one',
          price: 21
        },
         {
          name: 'two',
          price: 3
        },
         {
          name: 'three',
          price: 5
        },
         {
          name: 'four',
          price: 120
        }
      ],
      sortDirection: 1,
      sortBy: 'name'
    }
  },
  computed: {
    sortedProperties() {
      const type = this.sortBy === 'name' ? 'String' : 'Number'
      const direction = this.sortDirection
      const head = this.sortBy
      // here is the magic
      return this.properties.sort(this.sortMethods(type, head, direction))
    }
  },
  methods: {
    sort(head) {
      this.sortBy = head
      this.sortDirection *= -1
    },
    sortMethods(type, head, direction) {
       switch (type) {
          case 'String': {
            return direction === 1 ?
              (a, b) => b[head] > a[head] ? -1 : a[head] > b[head] ? 1 : 0 :
              (a, b) => a[head] > b[head] ? -1 : b[head] > a[head] ? 1 : 0 
          }
          case 'Number': {
            return direction === 1 ?
              (a, b) => Number(b[head]) - Number(a[head]) :
              (a, b) => Number(a[head]) - Number(b[head])
          } 
       }
    }
  }
}).mount('#app')
Run Code Online (Sandbox Code Playgroud)
th {
  cursor: pointer;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@next"></script>

<div id="app">
  <table>
    <thead>
      <tr>
        <th v-for="head in headers" @click="sort(head)">
        {{ head }}
        </th>
      </tr>
    </thead>
    
    <tbody>
      <tr v-for="(data, i) in sortedProperties" :key="data.id">
          <td v-for="(head, idx) in headers" :key="head.id">
              {{ data[head] }}
          </td>
        </tr>
    </tbody>
  </table>
</div>
Run Code Online (Sandbox Code Playgroud)