Restrict vue/vuex reactivity

后端 未结 3 1828
忘了有多久
忘了有多久 2020-12-15 12:57

Let\'s assume we have some array of objects, and these objects never change. For example, that may be search results, received from google maps places api - every result is

相关标签:
3条回答
  • 2020-12-15 13:22

    I created a fork out of vue called vue-for-babylonians to restrict reactivity and even permit some object properties to be reactive. Check it out here.

    With it, you can tell Vue to not make any objects which are stored in vue or vuex from being reactive. You can also tell Vue to make certain subset of object properties reactive. You’ll find performance improves substantially and you enjoy the convenience of storing and passing large objects as you would normally in vue/vuex.

    0 讨论(0)
  • 2020-12-15 13:30

    At the second glance data split seems not so ugly solution for this task. All that we need is using getters instead of the raw vuex state. We suppose that incoming results is an array with any objects that have unique id field. Then the solution could look like:

    const state = {
        ids: []
    }
    
    let resultsCache = {};
    
    const getters = {
        results: function(state) {
            return _.map(state.ids,id => resultsCache[id]);
        }
    }
    
    const mutations = {
        replaceResults: function(state,results) {
            const ids = [];
            const cache = {};
            (results||[]).forEach((r) => {
                if (!cache[r.id]) {
                    cache[r.id] = r;
                    ids.push(r.id);
                }
            });
            state.ids = ids;
            resultsCache = cache;
        },
        appendResults: function(state,results) {
            (results||[]).forEach((r) => {
                if (!resultsCache[r.id]) {
                    resultsCache[r.id] = r;
                    state.results.push(r.id);
                }
            });
        }
    }
    
    export default {
        getters,
        mutations,
        namespaced: true
    }
    
    0 讨论(0)
  • 2020-12-15 13:40

    You can use Object.freeze() on those objects. This comes with a (really tiny!) performance hit, but it should be negligible if you don't add hundreds or thousands of objects at once.

    edit: Alternatively, you could freeze the array (much better performance) which will make Vue skip "reactifying" its contents.

    And when you need to add objects to that array, build a new one to replace the old one with:

    state.searchResults = Object.freeze(state.searchResults.concat([item]))
    

    That would be quite cheap even for bigger arrays.

    0 讨论(0)
提交回复
热议问题