Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Vue订单列表视图_List_Sorting_Vue.js - Fatal编程技术网

List Vue订单列表视图

List Vue订单列表视图,list,sorting,vue.js,List,Sorting,Vue.js,我在一个项目中使用vue js 1.27,我需要能够按数字值、字母顺序和相反顺序对列表进行排序。 我一整天都在尝试这个,但进展不大 我在代码示例中留下了一些以前的代码,以便让您知道我已经尝试了什么 多谢各位 {% extends 'base.html.twig' %} {% block body %} <div id="wrap"> <h2>Select a category</h2> <ul id="categorySelect"

我在一个项目中使用vue js 1.27,我需要能够按数字值、字母顺序和相反顺序对列表进行排序。 我一整天都在尝试这个,但进展不大

我在代码示例中留下了一些以前的代码,以便让您知道我已经尝试了什么

多谢各位

{% extends 'base.html.twig' %}

{% block body %}

<div id="wrap">
    <h2>Select a category</h2> 
    <ul id="categorySelect">
        <li v-for="cat in categories | orderBy reverse" @click="selectCategory(cat)" class="${cat.selectedCategory == category ? 'selected' : ''}">${cat.title}</li>
    </ul>
</div>

{% endblock %}

{% block javascripts %}

    <script type="text/javascript">

        Vue.config.delimiters = ['${', '}'];

        new Vue({
        el: '#wrap',
        data: {
            //reverse: -1,
            wasClicked: true,
            selectedCategory: null,
            categories: [{
                title: 'ALL',
                category: null
            }, 
            {
                title: 'CATE',
                category: 'sport'
            }, 
            {
                title: 'DOG',
                category: 'sport'
            },
            {
                title: 'SPEED',
                category: 'sport'
            },
            {
                title: 'CAT',
                category: 'sport'
            },
            {
                title: 'SPORT',
                category: 'sport'
            },
            {
                title: 'ART',
                category: 'sport'
            },
            {
                title: 'PEOPLE',
                category: 'people'
            }, 
            {
                title: 'CAR',
                category: 'car'
            }]
        },
        filters: {
            categoryFilter: function (infoBlocs) {
                return this.wasClicked ? this.categories : {};
            },

            caseFilter: function () {
                if (this.wasClicked) {
                    return this.reverseArray();
                }
                return this.alphaSortByKey(this.categories, 'category');
            },

            reverse: function(value) {
                // slice to make a copy of array, then reverse the copy
                return value.slice().reverse();
            }
        },
        methods: {
            selectCategory: function(category) {
                //this.wasClicked =! this.wasClicked;
                //this.categories = this.alphaSortByKey(this.categories, 'category');
                // if (this.reverse) {
                //  this.categories = this.alphaSortByKey(this.categories, 'category');
                // }
                // else {
                //  this.categories = this.reverseArray();
                // }

                if (this.reverse) {
                    this.categories = this.alphaSortByKey(this.categories, 'category');
                    this.reverse = false;
                }
                else {
                    this.categories = this.reverseArray();
                    //this.reverse = true;
                }
            },

            alphaSortByKey: function (arr, key) {
                arr.sort(function (a, b) {
                    if (a[key] < b[key])
                            return -1;
                    if (a[key] > b[key])
                            return 1;
                    return 0;
                });
                return arr;
            },

            reverseArray: function () {
                return this.categories.reverse();
            },

            changeOrder: function (event) {
              var self = this;
              self.reverse = self.reverse * -1
              var newItems = self.categories.slice().sort(function (a, b) { 
                var result;
                if (a.name < b.name) {
                  result = 1
                }
                else if (a.name > b.name) {
                  result = -1
                }
                else {
                  result = 0
                }
                return result * self.reverse
              })
              newItems.forEach(function (item, index) {
                item.position = index;
              });

              this.categories = newItems;
            }
        } 
    });


    </script>

{% endblock %}
{%extends'base.html.twig%}
{%block body%}
选择一个类别
  • ${cat.title}
{%endblock%} {%block javascripts%} Vue.config.delimiters=['${','}']; 新Vue({ el:'包裹', 数据:{ //反面:-1, 是的, selectedCategory:空, 类别:[{ 标题:“全部”, 类别:空 }, { 标题:"美食",, 类别:"体育" }, { 标题:“狗”, 类别:"体育" }, { 标题:"速度",, 类别:"体育" }, { 标题:"猫",, 类别:"体育" }, { 标题:"体育",, 类别:"体育" }, { 标题:“艺术”, 类别:"体育" }, { 标题:"人",, 类别:“人民” }, { 标题:"汽车",, 类别:“汽车” }] }, 过滤器:{ categoryFilter:函数(infoBlocs){ 返回this.wasClicked?this.categories:{}; }, caseFilter:函数(){ 如果(单击了this.was){ 返回这个.reversearlay(); } 返回此.alphaSortByKey(this.categories,'category'); }, 反向:功能(值){ //切片以制作阵列的副本,然后反转副本 返回值.slice().reverse(); } }, 方法:{ 选择类别:功能(类别){ //this.wascacked=!this.wascacked; //this.categories=this.alphaSortByKey(this.categories,'category'); //如果(本条相反){ //this.categories=this.alphaSortByKey(this.categories,'category'); // } //否则{ //this.categories=this.reversearlay(); // } 如果(本条相反){ this.categories=this.alphaSortByKey(this.categories,'category'); 这个。反向=假; } 否则{ this.categories=this.reversearlay(); //这是正确的; } }, alphaSortByKey:功能(arr,键){ arr.sort(函数(a,b){ 如果(a[键]b[键]) 返回1; 返回0; }); 返回arr; }, reverseArray:函数(){ 返回此.categories.reverse(); }, 变更顺序:功能(事件){ var self=这个; self.reverse=self.reverse*-1 var newItems=self.categories.slice().sort(函数(a,b){ var结果; 如果(a.nameb.name){ 结果=-1 } 否则{ 结果=0 } 返回结果*self.reverse }) forEach(函数(项、索引){ item.position=索引; }); this.categories=newItems; } } }); {%endblock%}
创建一个计算属性,您可以在其中手动对其排序,然后循环该属性,而不是使用数据属性

这里是一个具有工作功能的工具,用于排序和反转数组的顺序。对于reverse,我只使用了内置的reverse()Javascript函数。对于字母数字排序,我借用了这个答案的解决方案:

Html:

内置的
reverse()
函数非常简单,因此我将详细介绍
sortAlphaNum()
sort函数。该函数被传递到
sort()
函数中,并且必须返回1、0或-1,以指示传入的对象是否应在数组中的特定方向上移动

变量
reA
reN
分别是识别字母和数字字符的正则表达式

首先,该函数从传入的两个对象的标题中删除所有字母字符,并比较它们是否相等。
var aA=a.title.replace(reA,”)
var bA=b.title.replace(reA,”)

如果它们不相等,则意味着我们有字母字符(而不仅仅是数字输入),我们可以相应地对它们进行排序。
返回aA>bA?1 : -1;

如果去掉字母字符的标题相等(
If(aA==bA)
),则我们从对象标题中删除数字(保留非数字字符)。
var-aN=parseInt(a.title.replace(reN,”),10)
var bN=parseInt(b.title.replace(reN)”,10)

然后我们比较结果变量并返回适当的排序值(1,0,-1)。
返回aN==bN?0:aN>bN?1 : -1;<div id="wrap">
    <h2>Select a category</h2>
    <button @click="sort">
    Sort alphanumeric
    </button>
    <button @click="reverse">
    Reverse list
    </button>
    <ul id="categorySelect">
        <li v-for="cat in categories">${cat.title}</li>
    </ul>
</div>
Vue.config.delimiters = ['${', '}'];

new Vue({
  el: '#wrap',
  data: {
    selectedCategory: null,
    categories: [{
      title: 'ALL',
      category: null
    }, 
    {
      title: 'CATE',
      category: 'sport'
    }, 
    {
      title: 'DOG',
      category: 'sport'
    },
    {
      title: 'SPEED',
      category: 'sport'
    },
    {
      title: 'CAT',
      category: 'sport'
    },
    {
      title: 'SPORT',
      category: 'sport'
    },
    {
      title: 'ART',
      category: 'sport'
    },
    {
      title: 'PEOPLE',
      category: 'people'
    }, 
    {
      title: 'CAR',
      category: 'car'
    }]
  },
  methods: {
    sort: function () {
        this.categories.sort(this.sortAlphaNum);
    },
    reverse: function () {
        this.categories.reverse();
    },
    sortAlphaNum: function (a,b) {
      var reA = /[^a-zA-Z]/g;
      var reN = /[^0-9]/g;
      var aA = a.title.replace(reA, "");
      var bA = b.title.replace(reA, "");
      if(aA === bA) {
          var aN = parseInt(a.title.replace(reN, ""), 10);
          var bN = parseInt(b.title.replace(reN, ""), 10);
          return aN === bN ? 0 : aN > bN ? 1 : -1;
      } else {
          return aA > bA ? 1 : -1;
      }
    }
  }
});
<template>
  <div>
    <table class="table table-bordered" v-if="data.length">
      <thead>
        <tr>
          <th v-for="(colValue, colKey) in cols" :key="colKey">
            <a @click="sort(colKey)" href="javascript:void(0)">
              {{colValue}}
              <icon :name="(sortColumn === colKey) ? (sortAsc ? 'sort-down' : 'sort-up') : 'sort'"></icon>
            </a>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="row in data" :key="row.id">
          <td v-for="(colValue, colKey) in cols" :key="row.id + colKey">{{row[colKey]}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
import _ from 'lodash';
import apiServer from '@/utils/apiServer'; // 

export default {
  name: 'List',

  data() {
    return {
      data: [],
      sortColumn: '',
      sortAsc: true
    };
  },

  props: {
    cols: {
      type: Object,
      required: true
    },
    apiEndpoint: {
      type: String,
      required: true
    }
  }

  created() {
    this.fetchData();
  },

  watch: {
    '$route': 'fetchData'
  },

  methods: {
    async fetchData() {
      const response = await apiServer.get(this.apiEndpoint);
      this.data = response.data;
    },

    sort(colKey) {
      this.data = _.sortBy(this.data, [colKey]);

      if (this.sortColumn === colKey) {
        if (!this.sortAsc) {
          this.data = _.reverse(this.data);
        }

        this.sortAsc = !this.sortAsc;
      } else {
        this.sortAsc = false;
      }

      this.sortColumn = colKey;
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
<template>
  <div>
    <h1>Orders</h1>

    <List :cols="cols" api-endpoint="/orders" title="Orders" />
  </div>
</template>

<script>
import List from '@/components/List.vue';

export default {
  name: 'OrderList',
  components: { List },

  data() {
    return {
      cols: {
        id: 'Id',
        title: 'Title',
        created_at: 'Created at'
      }
    };
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>