What is state management
In theory, each Vue component instance is already "managing" its own reactive state
It is a self-contained unit consisting of the following parts
- State : the data source that drives the entire application;
- View : a declarative mapping to state ;
- Interaction : The possible ways in which the state can change based on user input in the view .
The difference between Vuex and Pinia
Vuex:
1. Composed of state, getters, mutations, actions, modules
2. Modify state through mutations
advantage:
Supports debugging features such as time travel and editing
Suitable for large, high-complexity Vue.js projects
Disadvantages:
server-side rendering, which exposes your application to security vulnerabilities
When the getter is accessed through the method, it will be called every time without caching the result.
Pinia:
1. Composed of state, getters, and actions
2. Modify the state through getters, actions, or through $patch
advantage:
Full TypeScript support: Adding TypeScript is easier than adding TypeScript in Vuex
Extremely lightweight (about 1KB in size)
Store actions are dispatched as regular function calls, rather than using the dispatch method or the MapAction helper function, which is common in Vuex
Support for multiple Stores
Support for Vue devtools, SSR and webpack code splitting
shortcoming:
Debugging features like time travel and editing are not supported
Vuex state management
For those who already have experience in Vue2 projects, Vuex may be more familiar.
Vuex is a state management pattern + library developed specifically for Vue.js applications . It uses a centralized storage to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable manner.
Install:
npm install vuex@next --save
start:
home page:
<template>
<div class="home">
<div>Store:{ {count}}</div>
<ChildViewVue></ChildViewVue>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue';
import ChildViewVue from './ChildView.vue';
import { useStore } from 'vuex';
const store = useStore();
console.log('const store = useStore();', store.state.count)
const count = computed(() => store.state.count)
</script>
Subpage:
<template>
<div class="ChildView">
<button @click="clickChange">修改store</button>
</div>
</template>
<script lang="ts" name="ChildView" setup>
import { ref, watch } from 'vue'
import { useStore } from 'vuex';
const store = useStore();
const clickChange = () => {
let random = Math.floor(Math.random() * 10 + 1)
store.commit('CHANGE_COUNT',random)
}
</script>
store:
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
getters: {},
mutations: {
CHANGE_COUNT(state: { count: any }, data: any) {
state.count = data;
}
},
actions: {},
modules: {}
});
Pinia state management
Pinia is a repository for Vue that allows you to share state across components/pages. If you're familiar with the Composition API, you might think that you can already use a simple export const state = reactive({})
. This is true for a single-page application, but if it's server-side rendered, it exposes your application to security holes.
- Stronger team collaboration conventions
- Integration with Vue DevTools, including timeline, component internal inspection and time travel debugging
- Hot Module Update (HMR)
- Server-side rendering support
npm install pinia
home page:
<template>
<div class="home">
<div>pinia:{ {count}}</div>
<ChildViewVue></ChildViewVue>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue';
import ChildViewVue from './ChildView.vue';
import { changeNum } from "@/store";
import { storeToRefs } from 'pinia'
const store = changeNum()
const { count } = storeToRefs(store)
</script>
Subpage
<template>
<div class="ChildView">
<button @click="clickChange">修改store</button>
</div>
</template>
<script lang="ts" name="ChildView" setup>
import { ref, watch } from 'vue'
import { changeNum } from "@/store";
const store = changeNum()
const clickChange = () => {
let random = Math.floor(Math.random() * 10 + 1)
store.CHANGE_COUNT(random)
}
</script>
store
import { defineStore } from 'pinia';
export const changeNum = defineStore('main', {
state: () => ({ count: 0 }),
getters: {},
actions: {
CHANGE_COUNT(data: any) {
this.count = data;
}
}
});
main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
createApp(App).use(createPinia()).use(router).mount('#app')
Summarize
According to Vue official answer:
Existing users may be more familiar with Vuex , which was the official state management library before Vue. Vuex is now in maintenance mode as Pinia takes on the same responsibilities in the ecosystem and does it better. It still works, but no longer accepts new features. For new applications, it is recommended to use Pinia
In fact, Pinia was originally developed precisely to explore the next version of Vuex, thus incorporating many of the core team's ideas for Vuex 5 . Ultimately, we realized that Pinia already implemented most of what we wanted to deliver in Vuex 5, and decided to make it our new official recommendation.
Compared with Vuex, Pinia provides a more concise and direct API, and provides a combined style API. Most importantly, it provides a more complete type deduction when using TypeScript
All in all, Vuex is currently able to meet our daily project needs. When the next version of Vuex is released, Pinia may be used.