前言
最近发现vue中出了个Pinia
,与vuex
一样用来管理状态的。提前简单学习一下,免得以后用到了不会😂
Pinia官网: Pinia
以下内容都是基于vue3
的
基本使用
安装
npm install pinia@next
注:npm
不好使的话,可以用cnpm
试一下
在main.js文件中创建一个 pinia(根存储)并将其传递给应用程序
import { createPinia } from 'pinia';
app.use(createPinia());
基本格式
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user',
state: () =>({}),
getters: {},
actions: {}
})
store
Store 是一个保存状态和业务逻辑的实体,可以自由读取和写入,并通过导入后在 setup 中使用
创建
//userStore.js
// 导入 pinia
import { defineStore } from 'pinia';
// defineStore 调用后返回一个函数,调用该函数获得 Store 实体
export const userStore = defineStore({
// id:必须的,保证在Store中唯一
id: 'userStore',
// state:返回对象的函数
state: () => ({
id: '001',
name: '张三'
})
});
使用
<template>
<div>
名称:{{ store.name }}
</div>
</template>
<script>
// 导入 store
import {userStore} from './module/userStore';
export default {
setup() {
// 获取store
const store = userStore();
return {
store
};
}
};
</script>
<style scoped lang="scss">
</style>
Getters
类似vue中的计算属性,可用于获取值
// 导入 pinia
import { defineStore } from 'pinia';
// defineStore 调用后返回一个函数,调用该函数获得 Store 实体
export const userStore = defineStore({
// id:必须的,保证在Store中唯一
id: 'userStore',
// state:返回对象的函数
state: () => ({
list: [
{id: 1,name: '张三'},
{id: 2,name: '李四'}
]
}),
getters: {
// 无参,直接返回值
getUserList(state) {
return state.list;
},
// 有参,有参数时必须返回一个函数
getNameById(state) {
return (id) => {
let item = state.list.find(e => e.id == id);
return item ? item.name : '';
};
}
}
});
<template>
<div>
<div>用户列表:</div>
<div v-for="user in store.getUserList" :key="user.id">
<div>id:{{ user.id }},名称:{{ user.name }}</div>
</div>
<hr>
<div>id为1的用户是:{{ store.getNameById(1) }}</div>
</div>
</template>
<script>
// 导入 store
import {userStore} from './module/userStore';
export default {
setup() {
// 获取store
const store = userStore();
return {
store
};
}
};
</script>
<style scoped lang="scss">
</style>
Actions
Actions
用于修改store
的状态
actions: {
// 修改名称
editName(id,newName) {
let item = this.list.find(e => e.id == id);
item.name = newName;
}
}
<template>
<div>
<div>用户列表:</div>
<div v-for="user in store.getUserList" :key="user.id">
<div>id:{{ user.id }},名称:{{ user.name }}</div>
</div>
<hr>
<div>id为1的用户是:{{ store.getNameById(1) }}</div>
<hr>
<div>修改id为1的用户的名称:张五</div>
<el-button type="primary" @click="edit(1,'张五')">修改</el-button>
<div>修改后的名称:{{ newName }}</div>
</div>
</template>
<script>
// 导入 store
import {userStore} from './module/userStore';
import {ref} from 'vue';
export default {
setup() {
// 获取store
const store = userStore();
let newName = ref('');
// 修改名称
const edit = (id,name) => {
store.editName(id,name);
newName.value = store.getNameById(1);
};
return {
store,
newName,
edit
};
}
};
</script>
<style scoped lang="scss">
</style>
备注: 发现了个问题,有知道原因的大佬麻烦解释一下
如果注释掉 <div>修改后的名称:{{ newName }}</div>
这一行代码,点击修改按钮后,页面的数据并没有响应式的更新。而有 <div>修改后的名称:{{ newName }}</div>
这一行代码时,因为newName
是响应式的,newName
值改变后,页面数据会更新,同时也更新了其他数据。
异步缓存数据
有时候会有这样的需求,比如在一开始登录的时候,调接口将一些数据缓存到本地,方便数据的使用
import { defineStore } from 'pinia'
//接口API
import {
UnitDescApi,
BasicShiftSystemApi,
} from '@/base/consts/api/basic'
export const useWorkCenterStore = defineStore({
id: 'work-center-page',
state: () => ({
//单位类型
unitTypeList: [],
//班制类型
shiftSystemTypeList: [],
}),
getters: {
//获取单位类型
getUnitTypeList(state) {
return state.unitTypeList
},
// 获取班制类型
getShiftSystemTypeList(state) {
return state.shiftSystemTypeList
},
},
actions: {
//修改单位类型
editUnitTypeList(list) {
this.unitTypeList = list
},
//修改班制类型
editShiftSystemTypeList(list) {
this.shiftSystemTypeList = list
},
},
})
// 获取单位类型
const getUnitTypeList = async () => {
return new Promise((resolve, reject) => {
UnitDescApi.listPage({
pageNumber: 1,
pageSize: 1000,
status: 1,
})
.then(res => {
console.log('缓存厂单位类型成功')
resolve(res.data.records)
})
.catch(() => {
console.log('缓存单位类型失败')
reject()
})
})
}
// 获取班制类型
const getShiftSystemTypeList = async () => {
return new Promise((resolve, reject) => {
BasicShiftSystemApi.list()
.then(res => {
console.log('缓存厂班制类型成功')
resolve(res.data.filter(e => e.status == 1))
})
.catch(() => {
console.log('缓存班制类型失败')
reject()
})
})
}
// 初始化获取所有的类型数据
export const initWorkCenterStoreData = async () => {
const store = useWorkCenterStore()
//单位类型
store.editUnitTypeList(await getUnitTypeList())
//班制类型
store.editShiftSystemTypeList(await getShiftSystemTypeList())
}