DEV Community

Cover image for Architecting Vuex store for large-scale Vue.js applications

Architecting Vuex store for large-scale Vue.js applications

Musthaq Ahamad on October 13, 2019

At the heart of all large-scale Vue.js application lies the store which holds all its data. The Vuex store in a Vue.js application acts as a single...
Collapse
 
ausmurp profile image
Austin Murphy • Edited

On a large scale Vue application, one thing you should absolutely do is utilize SOLID code patterns. Consider creating 3 base store classes to manage CRUD, CRUD arrays, and paged state. Trust me, that will save you a ton of time, and boilerplate.

Collapse
 
haxzie profile image
Musthaq Ahamad

Awesome. Thanks for the suggestion! Would love to learn more about this. Any pointers?

Collapse
 
ausmurp profile image
Austin Murphy • Edited

This is where Typescript proves it's worth, as you can simply create these 3 classes, each extending the previous:
BaseStore<T>
ListStore<T>
PagedStore<T>

You have to use dynamic modules for this to work. Then your base store contains functions to mutate state as a whole, setState(T state), changeState(indexOrProp: string | number), clearState(), etc. And state$ across all 3 classes is:
T
Array<T>
Page<T>

Collapse
 
syaleni profile image
Siavash Habibi

Would love to see a post on that! I'm working on a project where I'm making a dashboard for a db with more than 20 years of sales data and all I worry about is how large the data can be and how to deal with it. I was thinking about making a base store and then extend the base store for each year... But even one year of data is large enough to impair the app if it's not handled properly.

Collapse
 
maftalion profile image
Matthew Aftalion

I really like the auto-importer. One optimization though:
Since you're appending all your module files with .store.js you can just change your regex to:
const requireModule = require.context('.', false, /\.store.js$/);
and that allows you to get rid of if (filename === './index.js') return;

Collapse
 
haxzie profile image
Musthaq Ahamad

Yes! Thanks for the suggestion Matthew ✨

Collapse
 
psnehanshu profile image
Snehanshu Phukon

Nice article Musthaq.
Can you please elaborate on why we should use getters instead of directly accessing state properties?

Collapse
 
haxzie profile image
Musthaq Ahamad • Edited

There is a good chance that you might actually try to mutate it outside the store. The store object should be treated as an immutable object and should only be mutated inside the mutation handlers. Since we have used strict: true in our main store file. Vuex will actually throw errors when you try to mutate it outside the mutation handlers. You will likely come across this error a lot if you try to mutate it outside ~ Do not mutate vuex store state outside mutation handlers.

Considering this, it's in our best interest to expose only the getters outside the store :)

Collapse
 
psnehanshu profile image
Snehanshu Phukon

I understand that, we shouldn't mutate state outside of mutations. But mutating is one thing and reading is different. What I am concerned with is reading. I can directly read store object from this.$store.state, so why do you think it is a good practice to use getters?

Thread Thread
 
haxzie profile image
Musthaq Ahamad

It is totally fine to use this.$store.state, or mapState to map the state properties into a component. But, considering the chances that these might get referenced or mutated, we can take a safe stand. Using getters too much is also a problem since they are actually computed properties for your store they need a bit of extra computation. The pro side of using getters is that we can move more of the logic, (if any involved in processing the state properties) inside your getters and have a safe stand on preventing it from getting mutated.

Collapse
 
shreshthmohan profile image
Shreshth Mohan

This probably is the best post explaining when and when not to use getters. You can simply use mapState to access state properties directly.

codeburst.io/vuex-getters-are-grea...

Collapse
 
nkoik profile image
Nikos Koikas

Cause you could return a filter or map or whatever you want from state property in vuex and not in component privately

Collapse
 
cooper09 profile image
cooper09 • Edited

I'm trying to use your boiler plate but I can seem to initialize my state data to appear in the HelloWord component.

I'm trying to attach screenshots of the HelloWorld component and the template.store.js to illustrate the point. It doesn't look like I can import more than one image so I'll send just the component screen shot.

If you need more info let me know...

Collapse
 
haxzie profile image
Musthaq Ahamad

github.com/haxzie/haxzie.com/issues/3

Please attach your screenshots here.

Collapse
 
anwar_nairi profile image
Anwar

Auto module export is on fire!

Collapse
 
wormss profile image
WORMSS • Edited

I believe state can be supplied as a function, so no need to run state = { ...initalState() }. Just state: initalState

Collapse
 
haxzie profile image
Musthaq Ahamad

Thanks for the suggestion! ❤️

Collapse
 
cooper09 profile image
cooper09

do you have an email?

Collapse
 
haxzie profile image
Musthaq Ahamad

github.com/haxzie/haxzie.com/issues/3

You can add the screenshots here. I'll try to help 🙂

Collapse
 
rolandcsibrei profile image
Roland Csibrei

Thanks for the article. There's a typo in mutations. Variable1. Have a nice day!

Collapse
 
haxzie profile image
Musthaq Ahamad

Thanks Ronald :)