davestewart / vuex-pathify

Vue / Vuex plugin providing a unified path syntax to Vuex stores
https://davestewart.github.io/vuex-pathify
MIT License
1.37k stars 57 forks source link

Mutating an item in a sync'd nested array #107

Closed JeffSpies closed 4 years ago

JeffSpies commented 4 years ago

Apologies in advance if I'm missing something obvious, but I have the following in my store:

const state = {
  matrix: [
    [0,1,2],
    [2,3,4]
  ],
  column: 0,
  row: 0
}

with getters, mutations, and actions created using make.* helpers.

I then sync matrix, column, and row states as computeds. Everything works fine for the column and row computeds, but my initial naive attempt to do the following failed:

this.matrix[this.row][this.column] = newValue // newValue comes from a method call

Is there a straightforward way to accomplish the above, or does it require a custom mutation/action or a different pattern altogether? I have a custom mutation/action calling Vue.set working, but, again, wondering if there's a better way.

Thanks; love the library!

davestewart commented 4 years ago

Hey Jeff!

Glad you are loving the library. I love your website - great design!

Hmm... arrays and Vue/x. There are a few caveats.

In this case you are "reaching into" the array, and effectively bypassing the Vuex commit.

     matrix is actually a computed property created by `sync` with `set` and `get` functions
       |
       v    |
this.matrix | [this.row][this.column] = newValue
       ^    |      ^         ^
       |           |         |
       |           |        now you are working with columns of the selected row
       |         now you are working directly with the rows of the returned value (bypassing the commit)
     sync sets and gets "matrix" from store

This will be why the Vue.set() is working, though I think (I'd have to load it up and test it!) you should also just be able to replace the whole array in the commit.

Question: what's the need for Vuex here? Could this just be a local class?

JeffSpies commented 4 years ago

Hi, Dave,

I can't take all the credit for the website as I started with a commercial (albeit cheap) template, but thanks!

And that was a great explanation. Vuex-pathify makes life so much easier, I was assuming much more magic than actually exists. :)

And you were right on asking about the need for Vuex. I was attempting to create an undo/redo system using Vuex time travel, but it introduced far too much complexity, so I'm sticking to local methods for the time being. Maybe I'll push the undo/redo stacks into Vuex at some point.

Thanks again! And thanks for creating an essential library for the Vue ecosystem (so essential, I dare say it should just come standard with Vue/Vuex)!

davestewart commented 4 years ago

I can't take all the credit for the website as I started with a commercial (albeit cheap) template

You know, I may even have seen that one! I was looking for something similar a couple of years ago and it looks familiar. I think I may even have downloaded it, or one by the same author.

Yeah, Vuex architecture is so onerous it becomes hard to do anything creative with it. It's the "one pattern to crush them all"!

If you want something that feels like a class but is reactive like Vue, try this other lib I wrote recently:

https://github.com/davestewart/vue-class-store

It's still early days for this lib, but I'm working towards it being a kind of "universal" store for Vue; currently thinking about how to write an adapter for Vuex, so – again – you don't need to rewrite from the group up to use Flux if you decide you need it later, or downgrade if you don't!

Give it a go, and let me know if you find it useful.

And thank you for the kind words!