Pinia:vue新一代状态管理插件
也就是更新版本的vuex(仓库)
官方文档:pinia.web3doc.top/introductio…
为什么要使用 Pinia?
Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。 如果您熟悉 Composition API,您可能会认为您已经可以通过一个简单的 export const state = reactive({}). 这对于单页应用程序来说是正确的,但如果它是服务器端呈现的,会使您的应用程序暴露于安全漏洞。 但即使在小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处:
-
dev-tools 支持
- 跟踪动作、突变的时间线
- Store 出现在使用它们的组件中
- time travel 和 更容易的调试
-
热模块更换
- 在不重新加载页面的情况下修改您的 Store
- 在开发时保持任何现有状态
-
插件:使用插件扩展 Pinia 功能
-
为 JS 用户提供适当的 TypeScript 支持或 autocompletion
-
服务器端渲染支持
如何使用Pinia
1.安装
npm install pinia
2.在main.js文件中引入:
import {createPinia} from "pinia"
let app=createApp(App)
app.use(createPinia())
3.创建一个store文件夹(也就是仓库)
在store文件夹中的js文件中引入pinia,注册仓库
import { defineStore } from 'pinia'
//导出仓库usestore
//注意:这里的usestore是由自己定义的,可以随便写
//但是官方建议我们定义的时候尽量用use开头命名,
//方便大家知道看见了这个名字,就知道它是一个定义的仓库
export const usestore =defineStore("注册的仓库名",{
state:()=>{
return {
仓库存储的数据
例如:msg:100
} }
})
4.在组件中使用:
<script setup>
//引入前面导出的仓库
import useStore from "../store/index.js"
//仓库
let store=useStore()
console.log(store.msg,111)
</script>
5.修改仓库状态
1.单个修改仓库(就是修改一次,刷新一次)
let fn=function(){
//直接修改就行了
store.msg="修改的值"
//注意:这里的数据msg不是响应式数据
//需要将它转化为响应式数据,才可以刷新页面
//toRef、toRefs
}
2.重置仓库
//回到初始的状态
//将状态 重置 到其初始值
store.$reset()
3.批量修改仓库(修改多个,只用一次刷新)
//第一种写法
store.$patch({
msg:20,
count:30
//注意:在这里修改仓库里面没有的值,是不会报错的
//但是也不会向仓库里面添加这个没有的值
//也就是说不能通过这个给仓库添加成员
})
//第二种写法:通过函数修改
store.$patch(()=>{
store.msg="chongq"
})
问题:单个修改与批量修改有什么区别?
答:状态刷新一次,可以批量修改
6.订阅修改:
//可以通过 store 的 $subscribe() 方法查看状态及其变化,通过patch修改状态时就会触发一次
store.$subscribe((mutation, state) => {
// 每当它发生变化时,将整个状态持久化到本地存储
localStorage.setItem('test', JSON.stringify(state))
})
案例:
7.Getter
Getter 完全等同于 Store 状态的 计算值。 它们可以用 defineStore() 中的 getters 属性定义。 他们接收“状态”作为第一个参数以鼓励箭头函数的使用:(ps:虽然鼓励但是依然提供了非es6玩家的使用方式 内部可以用this代表state)
//store/index.js文件
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
})
//组件中直接使用: <p>Double count is {{ store.doubleCount }}</p>
8.Actions
在pinia中没有提供mutaion 因为Actions就够了(它可以异步同步的统一修改状态)
之所以提供这个功能 就是为了项目中的公共修改状态的业务统一
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
actions: {
increment() {
this.counter++//1.有this
},
randomizeCounter(state) {//2.有参数 想用哪个用哪个
state.counter = Math.round(100 * Math.random())
},
randomizeCounter(state) {
//异步函数
axios("/test").then(res=>{
state.counter = res.data.length
})
}
},
})
//组件中的使用:
setup() {
const store = useStore()
store.increment()
store.randomizeCounter()
}
案例:
9.模块化
一个文件一个小仓库,仓库之间可以相互访问数据 不同组件也可以访问任意小仓库数据
//store/car.js文件
export const car = defineStore('car', {
state: () => ({
counter: 0,
}),
actions: {
}
})
//store/userinfo.js文件
export const userinfo = defineStore('userinfo', {
state: () => ({
counter: 0,
}),
actions: {
fn(state){state.counter=100}
}
})
//A组件可以用car,userinfo两个仓库的数据
import {car} from "@/store/car.js"
import {userinfo} from "@/store/userinfo.js"
let store1=car()
store1.counter
let store2=userinfo()
store2.counter
//car仓库使用userinfo仓库跟组件一样的使用方式
import {userinfo} from "@/store/userinfo.js"
let store2=userinfo()
store2.counter
store2.fn()