Pinia 基本用法
官网: pinia.vuejs.org/
相对于以前的 vuex,pinia 具有以下优势
- 更简单的写法,代码更清晰简洁,支持
composition api和options api语法 - 更完善的 typescript 支持,无需创建自定义复杂的包装类型来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断
- 非常轻量,只有 1kb 的大小
使用 pinia
yarn add pinia
or
npm install pinia
main.ts 中挂载 pinia
import { createPinia } from 'pinia'
import { createApp } from 'vue' import App from './app.vue'
createApp(App).use(createPinia()).mount('#app')
定义 store
store 的定义是通过 defineStore 这个函数,它需要一个唯一的名称,该名称可以作为第一个参数传递,也可以用 id 熟悉传递。
import { defineStore } from "pinia";
import { smartState } from "./types";
export const smartStore = defineStore({
id: "smartStore",
state: (): smartState => ({
net_status: false,
net_type: "wifi",
net_link: true,
net_icon: "icon-network_icon-3",
}),
actions: {
setNetStatus(status: boolean, type: string, link: boolean) {
this.net_status = status;
},
},
getters: {
getNetStatus(): string {
return `net_status=${this.net_status}--net_type=${this.net_type}--net_link=${this.net_link}`;
},
},
});
// or
import { defineStore } from "pinia";
import { globaleMenuState } from "./types";
import { watchTvDefault } from "./config/watchTv/index";
export const globaleMenuStore = defineStore("globalMenu", {
state: (): globaleMenuState => ({
display: false,
data: {
watchTV: {
icon: "icon-icon_watch-TV iconfont",
langClassNameTitle: "_watchTV",
subTree: watchTvDefault,
},
},
}),
});
使用 store
import { smartStore } from "../../store/source/index";
import { storeToRefs } from "pinia";
export default defineComponent({
name: "Home",
setup() {
const store = smartStore();
console.log(store);
// state中定义的值
console.log(store.net_status);
// getters
console.log(store.getNetStatus);
// actions
setTimeout(() => {
store.setNetStatus(true, "wifi", true);
}, 2000);
// storeToRefs
const { net_status } = storeToRefs(store);
const net_status_computed = computed(() => store.net_status);
return {
store,
net_status,
};
},
});
上述代码中,useMainStore 实例化后的,我们就可以在 store 上访问 state、getters、actions 等(pinia 中没有 mutations),该 store 是一个 reactive 对象,所以不需要 “.value”,也不能对其进行解构使用,否则失去响应性(类似 props),如果需要对其进行解构使用可以使用 storeToRefs 方法或者配合 computed 方法实现。
$reset
可以通过调用 store 上$reset 的方法将状态重置为初始状态
const store = smartStore();
store.$reset();
$path
$patch 可以同时修改多个值,可以直接传入修改的对象,或者一个函数
const store = smartStore();
store.$path({
net_status: false,
net_link: false,
});
store.$path((state) => {
state.net_status = false;
state.net_link = false;
});
$subscribe 监听 state 变化
该方法的第一个参数接受一个回调函数,该函数可以在 state 变化时触发
const store = smartStore();
const subscribe = store.$subscribe((mutation, state) => {
console.log(mutation);
console.log(state);
});
该回调函数的两个参数其中 state 是 mainStore 实例,而 mutation 打印如下
mutation 对象主要包含三个属性
-
events : 是这次 state 改变的具体数据,包括改变前的值和改变后的值等等数据
-
storeId :是当前 store 的 id
-
type:表示这次变化是通过什么产生的,主要有三个分别是
- “direct” :通过 action 变化的
- ”patch object“ :通过 $patch 传递对象的方式改变的
- “patch function” :通过 $patch 传递函数的方式改变的
取消订阅
可以通过调用 store.subscribe 中传第二个参数{ detached: true },detached 默认为 false。
const subscribe = store.$subscribe(
(mutation, state) => {
console.log(mutation);
console.log(state);
},
{ detached: true }
);
getter
getters 属性的值是一个函数,当该函数是箭头函数时返回参数 state,当 getters 的值是普通函数时,可以通过 this 访问整个 store 实例。
getters: {
getNetStatus1:(state):string=>
`net_status=${state.net_status}--net_type=${state.net_type}-- net_link=${state.net_link}`
,
getNetStatus():string {
return `net_status=${this.net_status}--net_type=${this.net_type}`
}
访问 getters
const store = smartStore();
// getters
console.log(store.getNetStatus1);
console.log(store.getNetStatus);
action
action 支持同步或异步,action 定义的函数可以是普通函数从而可以通过 this 访问整个 store 实例,同时该函数可以传入任意参数并返回任何数据。
actions: {
// 同步
setNetStatus(status:boolean,type:string,link:boolean) {
this.net_status = status;
},
// 异步
async getRpcNetworkStatus(){
rpc_api.NetworkStatus().then((res)=>{
this.net_status = res.status;
})
}
}
调用 action
const store = smartStore();
store.setNetStatus(true, "wifi", true);
监听订阅 action
通过 store.$onAction(),可以监听 action 的动作及结果等
该函数可以接收一个回调函数作为参数,回调函数的参数中有五个属性,具体如下
const onAction = store.$onAction(
({
name, // action 函数的名称
store, // store 实例,这里是 store
args, // action 函数参数数组
after, // 钩子函数,在action函数执行完成返回或者resolves后执行
onError, // 钩子函数,在action函数报错或者rejects后执行
}) => {
console.log(`action 函数的名称===${name}`);
console.log(`store 实例`, store);
console.log(`action 函数参数数组`, args);
after((result) => {
console.log("$onAction after函数", result);
});
onError((error) => {
console.log("错误捕获", error);
});
}
);
取消订阅
onAction 返回的值来手动停止订阅。
const onAction = store.$onAction(caballback,true);
onAction();
pinia 插件
可以通过 pinia.use()方法,添加新属性、添加新选项、添加新方法等。
import { createPinia } from "pinia";
const pinia = createPinia();
pinia.use(() => ({
env: "dev",
}));