数组更新后Vuex getter未更新值

时间:2017-08-28 00:48:51

标签: javascript arrays vue.js vuejs2 vuex

我正在尝试探索vuex,所以我要做的是在删除或添加值时获取计数或数组。以下是我的代码。

home.vue模板

<template>
    <div :class="page.class" :id="page.id">
        <h3>{{ content }}</h3>
        <hr>
        <p>Registered users count {{ unRegisteredUserCount }}</p>
        <ul class="list-unstyled" v-if="getUnRegisteredUsers">
            <li v-for="(unregistereduser, n) in getUnRegisteredUsers" @click="register(unregistereduser)">
                {{ n + 1 }}
                - {{ unregistereduser.id }} 
                {{ unregistereduser.fname }} 
                {{ unregistereduser.lname }}
            </li>
        </ul>
        <hr>
        <p>Registered users count {{ registeredUserCount }}</p>
        <ul class="list-unstyled">
            <li v-for="(registereduser, n) in getRegisteredUsers" @click="unregister(registereduser)">
                {{ n + 1 }}
                - {{ registereduser.id }} 
                {{ registereduser.fname }} 
                {{ registereduser.lname }}
            </li>
        </ul>
    </div>
</template>

<script>
    export default {
        name: 'home',
        data () {
            return {
                page: {
                    class: 'home',
                    id: 'home'
                },
                content: 'This is home page'
            }
        },
        computed: {
            getUnRegisteredUsers() {
                if( this.$store.getters.getCountUnregisteredUsers ) {
                    return this.$store.getters.getAllUnRegisteredUsers;
                }
            },
            getRegisteredUsers() {
                if( this.$store.getters.getCountRegisteredUsers > 0) {
                    return this.$store.getters.getAllRegisteredUsers;
                }
            },
            unRegisteredUserCount() {
                return  this.$store.getters.getCountUnregisteredUsers;
            },
            registeredUserCount() {
                return  this.$store.getters.getCountRegisteredUsers;
            }
        },
        methods: {
            register(unregistereduser) {
                this.$store.commit({
                    type: 'registerUser', 
                    userId: unregistereduser.id
                });
            },
            unregister(registereduser) {
                this.$store.commit({
                    type: 'unRegisterUser', 
                    userId: registereduser.id
                });
            }
        },
        mounted: function() {

        }
    }
</script>

state.js

export default {
    unRegisteredUsers: [
        {
            id: 1001,
            fname: 'John',
            lname: 'Doe',
            state: 'Los Angeles',
            registered: false
        },
        {
            id: 2001,
            fname: 'Miggs',
            lname: 'Ollesen',
            state: 'Oklahoma',
            registered: false
        },
        {
            id: 3001,
            fname: 'Zoe',
            lname: 'Mcaddo',
            state: 'New York',
            registered: false
        },
        {
            id: 4001,
            fname: 'Jane',
            lname: 'Roberts',
            state: 'Philadelphia',
            registered: false
        },
        {
            id: 5001,
            fname: 'Ellen',
            lname: 'Jennings',
            state: 'Houston',
            registered: false
        },
        {
            id: 6001,
            fname: 'Joseph',
            lname: 'Reed',
            state: 'Boston',
            registered: false
        },
        {
            id: 7001,
            fname: 'Jake',
            lname: 'Doe',
            state: 'Portland',
            registered: false
        }
    ],
    registeredUsers: []
}

getters.js

export default {
    getAllUnRegisteredUsers(state) {
        return state.unRegisteredUsers;
    },
    getAllRegisteredUsers(state) {
        return state.registeredUsers;
    },
    getCountUnregisteredUsers(state) {
        return state.unRegisteredUsers.length;
    },
    getCountRegisteredUsers(state) {
        return state.registeredUsers.length;
    },
    getUserById(state) {

    }
}

mutations.js

export default {
    registerUser(state, payload) {
        //find user
        const user = _.find(state.unRegisteredUsers, {
            'id': payload.userId
        });

        // remove user from original array
        _.remove(state.unRegisteredUsers, {
            'id': payload.userId
        });

        // set user object key value
        user.registered = 'true';

        // add user to new array
        state.registeredUsers.push(user);

        console.log(state.registeredUsers.length + ' - registered users count');
    },
    unRegisterUser(state, payload) {
        //find user
        const user = _.find(state.registeredUsers, {
            'id': payload.userId
        });

        // remove user from original array
        _.remove(state.registeredUsers, {
            'id': payload.userId
        });

        // set user object key value
        user.registered = 'false';

        // add user to new array
        state.unRegisteredUsers.push(user);

        console.log(state.unRegisteredUsers.length + ' - unregistered users count');
    }
}

在页面加载期间,它会正确呈现数组计数,但是当我删除 registeredUsers unRegisteredUsers 的值时,计数不会更新。我在这里错过了什么?任何人都可以解释,我该怎么做才能得到正确的计数?感谢

3 个答案:

答案 0 :(得分:2)

这不起作用的原因是你正在改变一个数组。永远不要改变数组。你将花费数小时试图解决为什么反应性破裂。

用新数组替换值以保持反应性。使用_.filter或_.reject,如下例所示。

state.registeredUsers = _.reject(state.registeredUsers, {
    'id': payload.userId
});

choasia的另一个答案是不正确的。 Lodash不是问题。 Lodash对Vuejs很有帮助,你只需要使用显式返回一个新数组的函数。请参阅“返回”下的Lodash文档,了解它返回的内容。

答案 1 :(得分:1)

由于JavaScript的限制,修改vuejs(以及vuex)中的列表或对象为tricky
您似乎正在使用lodash删除数组中的项目。它会引起与vuejs反应性的冲突。 See issue here
如果您要删除数组中的项目,最好使用<!-- Made possible by the great work of David DeSandro @ https://masonry.desandro.com --> <!-- Part 1: Add the scripts --> <!-- Step 1: Let's start by loading jQuery. jQuery is not required for masonary to function but makes things easier --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- Step 2: Then load imagesloaded. imagesloaded makes sure the images are not displayed until they are fully loaded --> <script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script> <!-- Step 3: we load masonry --> <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script> <!-- Part 2: Create the grid --> <!-- Step 1: Start with a the main grid wrapper--> <div class="grid"> <!-- Step 2: Add grid items---> <div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/00/37/03/0037037f1590875493f413c1fdbd52b1--cool-beards-inspiring-photography.jpg" /> </div> <div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/cd/90/d9/cd90d9de63fa2c8e5c5e7117e27b5c18--gritty-portrait-photography-studio-photography.jpg"> </div> <!-- Step 3: repeat...---> <div class="grid-item"> <img src="https://1.bp.blogspot.com/-9QM7ciGXRkQ/V1hsB-wNLBI/AAAAAAAAMoA/eYbSHs00PTAjrI4QAmvYAIGCUe1AuRAnwCLcB/s1600/bryan_cranston_0095.jpg"> </div> <div class="grid-item"> <img src="http://webneel.com/sites/default/files/images/project/best-portrait-photography-regina-pagles%20(10).jpg" /> </div> <div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/dd/45/96/dd4596b601062eb491ea9bb8e3a78062--two-faces-baby-faces.jpg" /> </div> <div class="grid-item"> <img src="http://www.marklobo.com.au/news/wp-content/uploads/2013/03/Melbourne_Portrait_Photographer_Mark_Lobo-Cowboy.jpg" /> </div> <div class="grid-item"> <img src="https://format-com-cld-res.cloudinary.com/image/private/s--PcYqe7Zw--/c_limit,g_center,h_65535,w_960/a_auto,fl_keep_iptc.progressive,q_95/145054-8576001-Rob-Green-by-Zuzana-Breznanikova_7725_b_w.jpg" /> </div> <div class="grid-item"> <img src="http://www.iefimerida.gr/sites/default/files/janbanning11.jpg" /> </div> <div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/66/bb/e7/66bbe7acc0d64da627afef440a29714b--portrait-photos-female-portrait.jpg" /> </div> <div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/736x/25/34/b6/2534b6c18c659546463f13b2dc62d4ce--natural-portraits-female-portraits.jpg" /> </div> <div class="grid-item"> <img src="https://s-media-cache-ak0.pinimg.com/originals/8d/67/12/8d671230ced871df8428b571ed6ec192.jpg" /> </div> </div> <!-- Part 3: the script call --> <!-- Now that everything is loaded we create a script to trigger masonary on $grid. Note that this simply says: "if the images are fully loaded, trigger masnory on $grid. --> <script> var $grid = $(".grid").imagesLoaded(function() { $grid.masonry({ itemSelector: ".grid-item" }); }); </script>来执行此操作。

答案 2 :(得分:0)

要添加到“名称”中有关从数组中删除内容的注释,请在更新//添加到数组时使用Vue.set。

updateItem(state, payload) {
    Vue.set(state.items, payload.index, payload.data);
}

在此处查看文档:{​​{3}}