Repository navigation
Conversation
Pinia 2 runs on both Vue 2.7 and Vue 3, so the stores can move ahead of the Vue 3 upgrade. The stores take the shape they have in the Vue 3 branch: plain state that components read with mapState and assign directly, with actions only where there is logic (select/deSelect). Wherever a component calls a store directly, it passes its own $pinia: the sidebar, toolbar and listing are separate Vue roots on one page, and outside setup() and the lifecycle hooks Vue 2.7 has no current instance, so a bare useStore() would fall back to whichever root booted last. vue-demi, through which Pinia 2 reaches Vue, ships its Vue 3 build as the default and only switches to the 2.7 build in its postinstall. webpack and Vitest resolve it to the 2.7 build directly, so an install that skips scripts still builds. Both of those are Vue 2 only and go with the move to Vue 3.
The count was tracked separately and decremented on every deSelect, even for an id that was never selected, so it could drift away from the list. It is now a getter over the selected ids, and select() no longer adds an id twice.
No editor component reads the editor store (the slim-sidebar flag it held is driven from the sidebar's own store), so the editor root no longer needs Pinia. The listing 'type' module was a leftover Vuex module that nothing imported.
Every other component reads its store state through mapState. The toggler was the one reading it through useGeneralStore(this.$pinia) in a computed, with a fallback to false that the boolean state no longer needs.
Vondry
force-pushed
the
refactor/vuex-to-pinia
branch
from
October 26, 2026 07:26
422ee47 to
9484de6
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Next step in splitting #3751 towards Vue 3: Vuex 3 is replaced with Pinia 2, which runs on both Vue 2.7 and Vue 3. The admin stays on Vue 2.7 and the Options API, so templates are unchanged.
The store files are identical to #3751. Afterwards, the store part of #3751 is only: bump
piniato 3, switch toapp.use(createPinia()), and optionally move components touseXStore()in<script setup>.What changed
store/modules/*(state, getters, mutations, actions) becomes one typeddefineStorefile: listing, sidebar and toolbar. Pass-through getters and mutations are gone: components read withmapStateand assign state directly. Onlyselect/deSelectremain as actions.this.$piniawhen they call a store outsidemapState(useXStore(this.$pinia)). The toolbar, sidebar and listing are separate Vue roots with their own Pinia, and in Vue 2.7 watchers and handlers a bareuseXStore()would use the Pinia of whichever root booted last. Covered bytests/unit/store/multi-root.spec.ts.vue-demiis aliased to its 2.7 build in webpack and Vitest, so installs that skip postinstall scripts still compile.Commits
22cf6504refactor: replace Vuex with Pinia: straight port, no behaviour change875e9f82fix(listing): derive the selected count from the selection: the count could drift from the selected ids; it's now a getter, andselect()skips duplicates (as in Migrate to Vue 3 Composition API and TypeScript #3751)1cf1e213chore: remove unused stores: the editor store and the listingtypemodule were never read84905137refactor(sidebar): read the slim flag with mapState: the one component not usingmapStatefor reads422ee47ddocs(listing): mark the order computed in SelectBox as dead code: a leftover of the unfinished drag-and-drop sorting, kept as isNote for extensions
Components inside the
#listing,#toolbar,#bolt--sidebarand#editorroots no longer getthis.$store.Testing
Walkthrough in the admin, with the live Pinia state of each root in the overlay: toolbar colour, sidebar slim toggle across a reload, row size across a reload, row and select-all selection with the bulk count, sidebar toggle leaving the listing selection alone, and the editor booting without a store.
bolt-vuex-to-pinia-walkthrough.mp4