简体   繁体   中英

VueX Mutation Optimization

I am working with a VueX store at the moment, and I have 1 mutation that does a push to entire array. Everything works currently, but want to know if I can make this code simpler, less lines / more optimized at the same time. Side note, these are objects stored in an array.

PUSH_TO_ALL: (state, data) => {
    const found = state.all.find((one, i) => {
      if (one.slug === data.slug) {
        state.all[i] = data // modify current state
        return true
      }
      return false
    })
    if (!found) {
      state.all.push(data) // add to the state
    }
  }

My first thought is that if you compare the slug in data to that in every object in the array, it must be unique (otherwise you would replace multiple objects in the find ).

This means that you can almost certainly make things a lot faster and a lot simpler if you switch from having the 'root' of state be an array, to using an object instead, indexed by slug .

Then your code would switch to being something like:

PUSH_TO_ALL: (state, data) => {
    state.all[data.slug] = data

This has 2 advantages - it is much simpler and faster to modify state, since you don't need to walk all of state checking if the object already exists. And secondly there's no need for separate code to distinguish between adding a new object, and replacing it if it already exists.

If for some reason you have to store state as an array, I would use a different part of state to maintain an object which tracks slug to array index. Then your code would be something like:

PUSH_TO_ALL: (state, data) => {
        if (state.map[data.slug]) {
          state.all[state.map[data.slug]] = data
        } else {
          // Push returns length of array - index is len-1
          state.map[data.slug] = state.all.push(data) - 1
        }

Note - in Vue2 you may need to use Vue.set() to update nested objects, since otherwise the code may not react to these changes. Vue3 no longer has this limitation.

You could use Array.findIndex instead of Array.find, and pair it with a ternary to make the trivial logic more concise (though not necessarily clearer).

 const mutations = { PUSH_TO_ALL: (state, data) => { const indexOfMatchingSlug = state.all.findIndex(one => one.slug === data.slug); state.all[indexOfMatchingSlug] = data? indexOfMatchingSlug > -1: state.all.push(data); } }

Array.findIndex documentation

JavaScript ternary operator documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM