如何使用变异对 Vuex 状态中的数据进行排序

How to sort data in Vuex state with mutation

我有一个对象数组显示在我的一个 Vue 组件的 html 页面上的 table 中。对象数组是 Vuex 存储状态中的数据。

export const store = new Vuex.Store({
    state: {
        jobs: [{...},{...},{...},{...},{...},{...}]
    },
    mutations: {
        sortJobs(state, sortKey) {
            console.log('running mutation');
            let compare = 0;
            this.state.jobs.sort((a, b) => {
                if (a.sortKey > b.sortKey) {
                    compare = 1;
                } else if (b.sortKey > a.sortKey) {
                    compare = -1;
                }
                return compare;
            });
        }
    },
    getters: {
        jobs: state => state.jobs
    }
});

我正在尝试对变异 sortJobs 中的对象数组进行排序,但它不起作用。我在我的一个组件中调用突变。

methods: {
    sortBy: function(sortKey) {
        this.$store.commit('sortJobs', sortKey);
    }
}

这不会改变对象数组的顺序,也不会改变我的 table。我已经测试过是否可以对对象数组执行任何操作,当我将 this.state.jobs.sort(...) 替换为 this.state.jobs.shift(); 时,数组中的第一个对象元素从我的 table 中消失了。但是说到排序,我根本无法排序。我做错了什么?

数组在 Vue 中很棘手。看看这些 common gotchas.

不要就地改变数组,而是尝试制作一个副本,对副本进行排序并将 state.jobs 设置为排序后的数组。

像这样:

  mutations: {
    sortJobs(state, sortKey) {
        console.log('running mutation');
        const jobs = this.state.jobs;
        jobs.sort((a, b) => {
            let compare = 0;
            if (a[sortKey] > b[sortKey]) {
                compare = 1;
            } else if (b[sortKey] > a[sortKey]) {
                compare = -1;
            }
            return compare;
        });
        state.jobs = jobs;
    }
  },

还有:

  • 将比较变量的实例化移到排序回调中,因此每次对两个列表项进行排序时它都会是新的。
  • 不要使用 a.sortKey,它会直接查找 sortKey 属性,而是使用 a[sortKey],它会让您访问变量属性。

没有 vuex 的工作示例: https://jsfiddle.net/ebbishop/7eku4vf0/

获取@Ebbishops 的答案,您可以通过检查当前的排序方向来进一步修改它:

// html
<th scope="col" @click="sort('title')">Title</th>
<th scope="col" @click="sort('content')">Content</th>

// script
    methods: {
        ...mapActions(['articles/SORT_ARTICLES']),
        sort(s) {
          this.$store.dispatch('articles/' + 'SORT_ARTICLES', s)
        }
      },


// state
export const state = () => ({
  articles: {},
  currentSort: 'title',
  currentSortDir: 'asc',
});


//mutations
  SET_SORT_ARTICLES: (state, sortKey) => {
    if(sortKey === state.currentSort) {
      state.currentSortDir = state.currentSortDir === 'asc' ? 'desc' : 'asc';
    }
    state.currentSort = sortKey;

      state.articles.sort((a,b) => {
        let modifier = 1;
        if(state.currentSortDir === 'desc') modifier = -1;
        if(a[state.currentSort] < b[state.currentSort]) return -1 * modifier;
        if(a[state.currentSort] > b[state.currentSort]) return modifier;
        return state.articles;
      });
  },

这允许您双向排序