Structuring Vuex Modules for Relationships, Speed and Flexibility
You can use Vuex modules in many ways, primarily representing single or multiple records. When using the latter it can add a lot of complexity, I wanted a solution that fit the following requirements:
- Easy lookup by ID
- Relatable to other records (only when required)
- Responsive to changes
I benchmarked a bunch of solutions but I found them pretty slow, so I used a more vanilla approach. This article assumes you are able to transpile code with Webpack for multiple browser support.
Basic Module Layout
This module describes a hypothetical albums recordset (along with artists and songs referenced elsewhere).
I store all the records in
.all, but I convert the array of listings to an object. This is for two reasons:
- I can efficiently query a record by an ID
- Converting back to an array (with
Object.values) for iteration is pretty fast
Fetching an Individual Record
Now that we are storing records in an object (Indexed by ID) we can easily fetch a record by that ID.
Listing & Querying Records
We can iterate through many records by using
Object.values of the state.all variable. You can also apply a
.filter() on the array for querying specific data.
Relationships are used primarily to augment listings. Here are some examples using computed properties.
Adding relationship data based on the context requirements is a lot more effective than populating that data all the time as some libraries do.
Active Record Pattern
I use an
.active variable to keep track of what record I am currently editing/focused on. This has a few advantages:
- Standard across all modules
- Simplifies updates and API integration
To use it you must $store.commit(‘albums/active’, 123)
Edit: Maintaining Record Order
Now we can sort by when listing:
Bonus: API Integration Actions
It is important to keep client and server records synced up. These Vuex actions integrate saving to the server and ensuring the client side represents what is saved including potential server changes. This example shows my API library in use passing in the active user module for authorization.
When I made any modification to a record I return all relevant information again so I can trust that what is on the server is on the client side.
Hopefully, you will ignore the shortcuts in syntax, thanks for reading!
Edit: Following up with Vuex ORM
I received a lot of feedback on Vuex ORM so I wanted to follow up on why I didn't choose it, check it out here.