构建Vuex模块

时间:2017-09-15 08:13:24

标签: vue.js vuejs2 vuex

我在尝试保持Vuex模块清洁方面遇到了一些麻烦,我希望能够获得有关如何改进它的一些见解。我已经分解了一些突变并且正在使用动作来组成多个突变,所以我想这是一个好的开始。

在大多数例子中,我看到超级干净的突变,我也有这些突变,但我需要检查if语句或其他副作用。举例:

我的行动:

setFilteredData({ state, commit }, payload) {
    commit('setFilteredData', payload);

    // Check if we need to split up the data into 'hotels' and 'nearby_hotels'.
    if (state.filteredData.find(hotel => hotel.nearby_city)) {
        commit('splitHotelsAndNearbyHotels', state.filteredData);
    }
}

我的突变:

splitHotelsAndNearbyHotels(state, payload) {
    // Chunk it up into hotels and nearby hotels.
    const composed = groupBy(payload, 'nearby_city');

    if (composed.true) {
        composed.true.forEach((hotel) => {
            if (hotel.isFirst) hotel.isFirst = false;
        });

        composed.true[0].isFirst = true;

        // Merge them back together in the right order.
        state.filteredData = composed.false.concat(composed.true);
    }
}

在此示例中,如果我的对象数组包含hotel.nearby_city设置为true的酒店,则会执行splitHotelsAndNearbyHotels的提交。

代码不够透明。动作中的if语句感觉不对,我希望我的变异更清晰。

我曾考虑将我的splitHotelsAndNearbyHotels拆分为单独的函数,但我不知道在哪里放置它们。简单地将它们放在Vuex文件中并不是一个很大的改进,将它们放在一个单独的文件中可能是一个选项我猜。

我如何清理文件以提高可读性?也许有人可以向我展示一个Vuex示例,它没有像我正在处理的理想场景。

1 个答案:

答案 0 :(得分:0)

实际上你可以将你的动作代码移动到getter中,使用单一来源并在getter上过滤它会更加干净。 但是如果你坚持使用动作,你可以在行动中移动你的变异代码,并重新构建你的动作代码,如下所示:

  

Helper.js

这是为了提供数据和帮助函数:

var _ = require('lodash');

const payloadData = [
    {"name":"A", "nearby_city":true, "isFirst":true},
    {"name":"B", "nearby_city":false, "isFirst":false},
    {"name":"C", "nearby_city":false, "isFirst":false},
    {"name":"D", "nearby_city":true, "isFirst":false}
];

// assumed nearby_city is boolean
const isNearby = (hotels) => { return !!hotels.find(hotel => hotel.nearby_city === true) };
const groupBy = (items, key) => { return _.groupBy(items, item => item[key]) };
  

Mutations.js

现在这是你的突变:

const mutations = {
    setfilteredData : (state, hotels) => {
        state.filteredHotels = hotels || [];
    },
}
  

Actions.js

这是你的行动,没有将你的功能转移到单独的文件中也没问题。

// separate filter function
const filterNearby = (payload) => {
    if(isNearby(payload) === false){
        return payload;
    }

    const composed = groupBy(payload, 'nearby_city');
    composed.true.forEach((hotel) => {
        if (hotel.isFirst) hotel.isFirst = false;
    });

    composed.true[0].isFirst = true;
    return composed.false.concat(composed.true);
};

const actions = {
    setfilteredData: ({state, commit}, payload) => {
        /**
         * Using separate filter function
         */
        commit('setfilteredData', filterNearby(payload));
        return;

        /**
         * Using restructured code
         */

        // Check if we need to split up the data into 'hotels' and 'nearby_hotels'.
        if(isNearby(payload) === false){
            commit('setfilteredData', payload);
            return;
        }

        // Chunk it up into hotels and nearby hotels.
        const composed = groupBy(payload, 'nearby_city');

        composed.true.forEach((hotel) => {
            if (hotel.isFirst) hotel.isFirst = false;
        });

        composed.true[0].isFirst = true;

        // Merge them back together in the right order.
        commit('setfilteredData', composed.false.concat(composed.true));
    }
};