Why Pinia vs Vuex for Vue 3? [closed] - vue.js

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 months ago.
This post was edited and submitted for review 7 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I am a Vue.js developer who is coming up to speed with the the new features added to Vue 3, from Vue 2, namely the Composition API (added in Vue 3).
For State Management, it appears that along with the release of Vue 3, the community is shifting from using Vuex to Pinia.
What is the difference between Pinia vs Vuex? Conceptually, what has changed from Vue 2 to Vue 3, that makes Pinia a better fit for Vue 3?
Thank you.

In short, Pinia's API is much simpler and intuitive. It makes using stores a breeze, even for junior devs.
It brings the benefits of Composition API, but has a structure which greatly resembles the Options API, which you're probably familiar with:
has a reactive state, equivalent of data function in Options API
has getters, equivalent of computed in Options API
has actions, equivalent of methods in Options API
does not have mutations, as any change to state now registers an implicit mutation, regardless of where it's performed
Additionally, in Pinia:
actions are no longer necessarily async, they can be either
actions don't need (and don't have) the first param (action context) as you no longer need commit, dispatch, rootGetters, rootState
other stores can now be invoked directly in any actions/getters, even allowing cyclic dependencies; this reduces the need to nest stores, although still possible
all stores are now dynamically registered at runtime (when they are invoked for the first time; the store starts empty)
inside actions and getters functions, this is the current store and provides direct access to all state props, actions and getters
you also have typed direct access to all actions, getters and state props on the object returned by the function (e.g: useSomeStore) returned by defineStore(); it's all TypeScript friendly, no workarounds or type casting required.
More in-depth explanations and reasoning on the dedicated page to differences between the two plugins.
According to declarations by plugin authors, Vuex 5 will have a similar API to Pinia's and they are likely to merge at some point.
As outlined in comments by Tony, Pinia is now the officially recommended state management solution by Vue team.
Vuex is now in maintenance mode. It still works, but will no longer receive new features. It is recommended to use Pinia for new applications. -- [added by Evan You in dec 2021].
Ref:
"what has changed from Vue 2 to Vue 3, that makes Pinia a better fit for Vue 3?"
Pinia was designed for usage in setup(). So much so, that it has a dedicated page on how to use it outside of setup().
More importantly, you are implying Vuex is a better fit for Vue2 projects.
Technically, that is false.
Both plugins offer the same functionality but Vuex has more boilerplate and, overall, a less intuitive syntax. Therefore it requires better trained engineers, for longer periods of time.
If you choose Vuex, your project costs will grow proportionally with your project's complexity, without any benefits.

I want to take a moment to answer my own question, after doing some research and giving a talk on this at the Vuejs LA Meetup (Los Angeles). Thanks also to the others who already answered to help with this response.
TLDR: In Vue 2 you -could not- easily control the shared Global State using "just Vue," so you needed Vuex to manage Global State shared throughout your app. (You can manage a component's local state, but not "Global State" that is the shared state across your app, without using something like Vuex.) In Vue 3, using the Composition API, you -can- create a place to manage Global State, so you can very easily just "roll your own" State Management system. So now, in Vue 3, yes, you basically can do this on your own, but you might as well use a standard one everyone is using, Pinia.
Full Explanation: For those who are coming up to speed with Vue 3, the big addition is the Composition API. For Vue 3, Vue 2 basically got re-branded the "Options API" and now there is an additional "Composition API." Please don't confuse "new" with "better." The Composition API is not better. It's just different. The Options API (aka, the Vue2 way of doing things is still fantastic -- and you should continue to use it).
The main difference between with Options API and the Composition API is organizational. The Options API (again, aka The Vue 2 Way) helps you organize your code a certain standard way -- basically one of the best features of Vue is the clean organization of each component. Those 3 <template>/<script>/<styles> blocks in each .vue component make it a pleasure to use Vue.
The Composition API was basically created for the occasion that you need to break out of that paradigm. Imagine you need to have the same logic, like Search, in the <script> section of your code. But you need the Search ability in 3 places. Instead of having the same redundant code three times, you can now extract that Search code to a new file, call it something like my-search.js, and access that search code from one place by importing its functionality into each of your components, staying DRY. Moreso, using the Composition API you can do this while maintaining reactivity (in Vue 2, you could have an external file, but you were basically "leaving Vue" and that was a problem). Now, using the Composition API in Vue 3, you can create a separate area to focus on shared logic, like my-search.js, and Vue continues to be aware of it, so you don't break reactivity.
In Vue 2, the community solved this Global State Management issue by creating Vuex. It was a plugin that allowed you to control state outside of the components, i.e., control Global State while remaining reactive (i.e., it did not break state).
Let's apply this new ability given to us by the Composition API to Managing Global State. If you can create a new external.js file that remains functional within your Vue app, that retains state, you can easily write your own Global State Manager (replicating what Vuex does). Imagine creating a file called global-state.js and making all of your Global State updates there. The Composition API makes this super easy to do.
So now, because of the Composition API in Vue 3, we basically do not need any external state management tool. That is why, when Vue 3 launched, every forum post was asking questions like, "Why do we even need Vuex anymore?" In Vue 3, we don't need Vuex anymore because we can Manage Global State on our own using the Composition API.
So last, why Pinia? Well, basically, standards. We could all roll our own, but we might as well use a light-weight plugin that is standardized (I would bet that Pinia is written using the Composition API — please correct me if I'm wrong here). Moreso, because it's a standardized process, and the new community-backed way of handling Global State Management, it comes with the bonus of integrating well into the rest of the Vue ecosystem of tools, like Vue DevTools, and has its own plugin system.
Hope that helps answer the original questions I was asking, focused on the concept: "Conceptually, what has changed from Vue 2 to Vue 3, that makes Pinia a better fit for Vue 3."

Related

Vue composition API vs Vuex (benefits of each and finding what is suitable for us)

I am completely familiar with Vuex but I don't know anything about Vue composition API. what is it all about, What's the difference between it and Vuex? Which gap in Vuex does it cover and when and where is better to use each of them?
thanx for the help.
First of all, vuex is a library and a pattern to perform state management.
vue composition api is a new vue-native (as of version 3; still a component library for version 2.x) way of working with components and state strongly based on composition functions, which would eventually make the code more readable, better organized, with better performance, and easier to maintain.
As per its RFC:
"Instead of relying on the magical this context, a composition function relies only on its arguments and globally imported Vue APIs. You can reuse any part of your component logic by simply exporting it as a function."
I think that's the key point around which the rest is organized.

Why is the word "API" used in the Composition API in Vue 3?

I have been reading about the new Composition API that is about to be introduced in Vue 3 which is set to release this year.
While I have been studying and exploring about the topic, I fail to understand why the word "API" is used. As far as I know, an API is used for sending/fetching data between the browser/app and a server.
Also, the Composition API is set to be an optional replacement for the already existing Options API in Vue 2. Even here, I do not understand the use of the word "API" in Options API.
Can someone please explain?
An API is not restricted to interfacing with servers. In general, they are well defined layers that give you intuitive access to things that are more complex. You're constantly interfacing with things every day; imagine the steering wheel of a car being the interface to the front wheels.
The API is how you interact with Vue. It's an agreement for how your code interacts with the underlying logic in Vue. The team have introduced the Composition API because they believe it will help in creating cleaner, faster and more maintainable code.
The Options API is so called because you pass options in an Object when instantiating a Vue component. The Composition API is so called because you use composition functions to add functionality to a Vue component.

Using Aurelia Store what is the best way to copy your state within Actions?

What are some ways in which to deep clone my state inside an Action?
Possible solutions I’ve seen are Immer.js, JSON.parse(JSON.stringify), or create a recursive function which does a deep clone. I was even thinking of recreating what Redux does and create Reducers and combine them for my entire state but there are reasons which I decided against it. I like in Aurelia store how I can push Actions to the store, inside each Custom Element’s bind() method. I believe this is a better way because it promotes high cohesion and low coupling. Whereas with Redux I had all my Actions and Reducers centralized with the store.
I’ve never used Immer.js and I was wondering what are some Pros and Cons of using it?
I like the idea of using JSON.parse(JSON.stringify) because it ensures my state is serializable at all times. Which will be good if I want to persist my state to some type of storage. It allows me to identify problems early like when I tried to use Set and Map object types and I quickly found out that those don’t serilize/deserialize with the above methods. But I’m wondering if my store grows too large will JSON.parse(JSON.stringify) become too slow?
Then there is the option of just creating a recursive function which copies my state. Has anyone tried this?
Thanks
EDIT - September 26, 2018
I also asked this question on the aurelia discourse forum and received some helpful responses there.
https://discourse.aurelia.io/t/using-aurelia-store-what-is-the-best-way-to-copy-your-state-within-actions/

Using Vuex in Vuejs application

I am new to Vue.js. I learned about a concept known as vuex. Please could anyone provide me explanation as to when should I use vuex.
If you’re working on a rather simple application or if all you do is to replace some parts of your (server rendered) application with some Vue.js magic, you might actually be fine not using Vuex at all.
On the other hand, if you’re working on a large scale single page app, you may encounter situations where you need the same data at two completely different places in your application. This is the point at which a centralized state management tool like Vuex oftentimes makes a lot of sense.
You can find more on : https://markus.oberlehner.net/blog/should-i-store-this-data-in-vuex/
If you have been through the documentation of Vuex on the first page you would have seen a headline When Should I Use It?. That gives a perfect view of when to use Vue.
You can use Vuex in any type of applications, small, medium or large scale. That's totally up to you. But it too overwhelming to use it in a small project because you have to write down a lot of code to get started with. Which can be easily maintained by the component state.
But it comes handy when the application is large. Managing state outside the Vue component will be a necessity and Vuex will be the natural next step for you.
Vuex is a flux implementation specifically for vue, and is officially supported by vue.js.
Well let's talk some plain English. In general, while developing a front end application using component driven frameworks like angular, react, vue, etc,. we need to start with developing components as they are basic as well as complex building block of the application. Usually a small/mid size project will have 5-10 components. And could go to any number in larger applications . These components would at many places need to communicate with each other so as to pass data.
The flow of data can go in one of the three directions:
Parent Component to Child component
Child Component to Parent component
Sibling Components
In order to achieve one, two or all the three of the above, there are ways to let the data flow. Some of the ways in vue.js are props(parent to child), events($emit, $on - child to parent), services(event driven) and vuex.
So let's just talk about vuex for now, i.e., when should you go for vuex and not other above mentioned methods.
When number of components are high. It would be a big pain if each component will have to maintain their own data in application level. Vuex solves it with state(storing state) and getters(getting state).
When you want to share data between siblings components. Props and Events would be the last thing you would want to do. Vuex just makes it easy. One of the sibling component will mutate the global state and other can just get it using getters (try mapGetters in computed properties of the component)
When too many components are updating the data. That's where vuex's mutations comes handly. Mutations are always synchronous. In case you want to work with async tasks then use actions.
Well this list can on and on...
Personally I like to follow this:
When the number of components and communication between them is high. Use vuex to manage state more conveniently and to make life easier.
I hope it helps.
Vuex is used to pass/store data between components so that it can be used or edited anywhere within your application.
You need to weigh up the benefits of using Vuex over the extra work that is required to set it up. It can be a very valuable tool when your application gets quite large but on the other hand when working with a small application the amount of time/effort/code to get it set up might out weigh the benefits of actually using it.
Using a centralised data store such as vuex is only really needed in a large scale app where you need to access data at different stages throughout the app.
Here is a quick link that further explains:
https://vuex.vuejs.org/
There is also centralised state management that is not vuex that can be useful when working with smaller scale apps which is detailed in this link
https://v2.vuejs.org/v2/guide/state-management.html

Architetural Considerations for VueJS project: Implementing Vuex

Our front-end team is presently working on a Reporting application with the following features:
Dashboards
Portfolio Analysis Tool (search form that returns grid-based results)
Automated Reports page
We've decided to architect the above using VueJS with the Webpack boilerplate (via Vue-Cli) and are trying to design to have common components:
A report component
Has title, description, type (grid, visualization, etc.) and some setting parameters
A report list component
Has a title and an array of report components as its properties
A dashboard that has an array of report list components arranged in a grid
Some requirements
A dashboard component can have 4 or more report list components, each with multiple reports that can be selected for view by the user from a report list select menu. Each report component can have one or more setting parameters that the user can manipulate and submit to re-render the report. A report can be a grid (ag-grid in our case) or a visualization-based report. Lastly, there is also authentication via Auth0.
Questions
Does it make sense to use Vuex to manage state for all our components and related interactions?
Does it sound like the application is a good use-case for Vuex?
If so, why? Is it better than using component to component communication via the built in Vue mechanisms (for parent-child, sibling-sibling components)?
Thank you in advance for helping us make a decision.
Vuex is useful when you have multiple components that need the same state. In your case, you're displaying reports in lots of different places and formats. This is a great use case for Vuex in my opinion.
Now, i don't know if your team is familiar with Vue, but passing data via props is a PITA. Especially if the components that need the data are spread far away in the component hierarchy, and deeply nested, which they usually are. Anyone who's been thru the gauntlet of passing props and emitting events up multiple levels will tell you that.
With Vuex, it's a single function call to get your data, from ANYWHERE in the component hierachy. It's a breath of fresh air.
I voted to close this question, because the answer is highly opinionated.
I've built multiple projects with Vue, some with dozens of components and many multiple thousands of lines of code. I've never once felt the level of complexity rose to the level that I needed Vuex.
You've described an application with half a dozen components.
I've definitely abstracted my logic out into custom objects, but that's just javascript.
YMMV.