Vue.js/Vuex to Pinia migration

Introduction
The intent of this article is to support mediawiki migration from Vuex to Pinia in internal projects that provide an opportunity to do so. Currently there is no need to upgrade existing project that are already in production and this update should just be performed on new project that have yet to be published or are at early stage of development.

The front end team has decided to use Pinia going forward, has it is now been recommended by the Vue core team as the successor of Vuex.

Migration in summary
The migration between this two stores is quite simple and it can even happen in stages where both store co-exist in the same application while the migration is in place.

The migration steps are:


 * Add Pinia to your current Vue instance
 * Create a Pinia store for each Vuex module
 * Update other Vuex store to use Pinia
 * Update the components to use Pinia
 * Update store unit tests

In the following sections we are going to covering in details the step required to perform the migration. A first migration was already implemented in the following patch.The linked patch shows how to implement a partial migration with both Vuex and Pinia working side by side.

Pinia's official website also include a great migration guide, and this article should just be used a supplement of that guide as there are parts specific to Mediawiki or not included in the official migration (like unit test)

Add Pinia to your current Vue instance
Pinia has been added into core with the following task T326174. Pinia can be added to your existing Vue application by using the following code:

Create a store for each module you had
The main difference between Vuex and Pinia is that the latter expects you to create multiple stores. Do not worry, you can still create the nested structure you previously could achieve with Vuex.

Create folders and files
Create a folder called stores (as Pinia expects multiple stores) and add files within that folder as shown below. The difference in name Store for Vuex and Stores for Pinia also help to us to be able to clearly achieve a "step migration".

Update the store module
I suggest to update a single module at the time and start from the smaller one (do not start from root). The main documentation includes step by step tutorial on how to update the module, so I am not going to repeat that here, but just mention the most important points.


 * 1) Remove "context" from all Actions
 * 2) Get rid of mutations (they will just become private functions or actions)
 * 3) Make sure actions are NOT arrow functions. This will make the "this" undefined!
 * 4) change the function name to align with pinia standards useModuleNameStore

The following link showcase the migration of a single module by showing the comparison of the two files: Event module file migration

Update other Vuex modules to use Pinia
While achieving a step migration, you will find yourself in situation where one store (Vuex) need to call the other (Pinia). In this section we are going to see how to achieve this.

Call Pinia from a Vuex store
To update the above action call, we need to fist import the newly created store and then call it. The code after a step migration will look like this:

Update the components to use Pinia
Pinia is ready to be used within our component as it has been initialised in our Vue instance and exposes a module ready to be used. As with before, i would first read the official documentation and use this as additional support. The steps that should be followed for the migration in your components are:


 * 1) Search and replace all instances of "mapActions", "mapGetters", "mapState", "mapMutations" to "mapVuexActions", "mapVuexGetters" and so on..
 * 2) Import the Pinia store in the component that require it
 * 3) Import Pinia's methods as required mapPiniaActions, mapPiniaGetters...
 * 4) Replace the code appropriately to use the correct store.

An example migration can be seen in this patch.

Let's create a simple example to demonstrate the migration steps:

The above code is going to be changed with the following: