https://pinia.vuejs.org/
Pinia是一个全新的Vue状态管理库,是Vuex的代替者,尤雨溪强势推荐
- Vue2 和 Vue3 都能支持
- 抛弃传统的 Mutation ,只有 state, getter 和 action ,简化状态管理库
- 不需要嵌套模块,符合 Vue3 的 Composition api,让代码扁平化
- TypeScript支持
- 代码简洁,很好的代码自动分割
npm init vite@latest
npm install pinia
yarn add pinia
// src/main.ts
import { createPinia } from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount('#app')
// src/store/index.ts
import { defineStore } from "pinia";
export const mainStore = defineStore("main", {
state: () => {
return {
msg: "hello world",
};
},
getters: {},
actions: {},
});
注:这是官网上提供的常规写法,我个人还是更偏向于下面这种写法:
// src/store/index.ts
import { defineStore } from "pinia";
interface State {
msg: string;
count: number;
}
const defaultState:State = {
msg: "hello world!"
}
export const mainStore = defineStore("main", {
state: () => {
return defaultState;
},
getters: {},
actions: {},
},
});
// src/components/HelloWorld.vue
{{store.msg}}
当store中的多个参数需要被使用到的时候,为了更简洁的使用这些变量,我们通常采用结构的方式一次性获取所有的变量名
// src/components/HelloWorld.vue
正常获取--{{store.count}}
ES传统方式解构,count不会响应式更新--{{count}}
{{store.msg}}
点击按钮,count的值+1,可以看到传统方式解构,count不会响应式更新。那要怎么解构呢?Pinia给我们提供了一个解构方法:
// src/components/HelloWorld.vue
正常获取--{{store.count}}
Pinia中的storeToRefs方法解构,count可以响应式更新--{{count}}
{{store.msg}}
通过基础数据修改方式去修改多条数据也是可行的,但是在
pinia
官网中,已经明确表示$patch
的方式是经过优化的,会加快修改速度,对性能有很大好处,所以在进行多条数据修改的时候,更推荐使用$patch
$patch
方法可以接受两个类型的参数,函数 和 对象
changeState
方法import { defineStore } from "pinia";
import { reactive } from "vue";
interface State {
msg: string;
count: number;
}
const defaultState:State = {
msg: "hello world!",
count: 0,
}
export const mainStore = defineStore("main", {
state: () => {
return defaultState;
},
getters: {},
actions: {
changeState() {
this.count++;
this.msg = this.msg === "hello world!" ? "你好 世界!" : "hello world!";
},
},
});
store.方法名
Pinia 中的 getter 和 Vue 中的计算属性几乎一样,在获取 State值之前做一些逻辑处理。
getter中的值有缓存特性,如果值没有改变,多次使用也只会调用一次
import { defineStore } from "pinia";
import { reactive } from "vue";
interface State {
msg: string;
count: number;
}
const defaultState = reactive({
msg: "hello world!",
count: 0,
})
export const mainStore = defineStore("main", {
state: () => {
return defaultState;
},
getters: {
getState(state) {
console.log('getter被调用');
return `${state.msg}---${state.msg}`
}
},
actions: {
changeState() {
this.count++;
this.msg = this.msg === "hello world!" ? "你好 世界!" : "hello world!";
},
},
});
Getter 获取数据
{{store.getState}}
{{store.getState}}
{{store.getState}}
{{store.getState}}
{{store.getState}}
import { defineStore } from "pinia";
interface State {
msg: string;
count: number;
}
const defaultState: State = {
msg: "hello world!",
count: 0,
}
export const mainStore = defineStore("main", {
state: () => {
return defaultState;
},
getters: {
getState():string {
console.log('getter被调用');
return `${this.msg}---${this.msg}`
}
},
actions: {
changeState() {
this.count++;
this.msg = this.msg === "hello world!" ? "你好 世界!" : "hello world!";
},
},
});
在
Pinia
中,可以在一个store
中import
另外一个store
,然后通过调用引入store
方法的形式,获取引入store
的状态
// src/store/music.ts
import { defineStore } from "pinia";
interface State {
list: string[];
}
const defaultState: State = {
list: ['晴天', '枫', '以父之名', '手写的从前', '明明就', '半岛铁盒', '稻香', '最长的电影']
};
export const musicStore = defineStore("music", {
state: () => {
return defaultState;
},
getters: {},
actions: {},
});
// src/store/index.ts
import { defineStore } from "pinia";
import {musicStore} from './music'
interface State {
msg: string;
count: number;
}
const defaultState: State = {
msg: "hello world!",
count: 0,
}
export const mainStore = defineStore("main", {
state: () => {
return defaultState;
},
getters: {
getState():string {
console.log('getter被调用');
return `${this.msg}---${this.msg}`
},
// 另一个Store引用,获取musicStore中的list
getMusicStoreList(): string[] {
return musicStore().list
}
},
actions: {
changeState() {
this.count++;
this.msg = this.msg === "hello world!" ? "你好 世界!" : "hello world!";
},
},
});
Store 互相调用
- {{item}}
总得来说,Pinia 就是 Vuex 的替代版,可以更好的兼容 Vue2,Vue3以及TypeScript。
在Vuex的基础上去掉了 Mutation,只保留了 state, getter和action。
Pinia拥有更简洁的语法, 扁平化的代码编排,符合Vue3 的Composition api