Pinia学习

一,前言

1.piniavuex一样是vue的状态管理器,从vue2升级到vue3加入了组合式API的概念后,vue已经主推pinia作为状态管理器

2.与 Vuex 相比,Pinia 提供了一个更简单的 API,也提供了符合组合式 API 风格的 API,最重要的是,搭配 TypeScript 一起使用时有非常可靠的类型推断支持

二,相对于vuex的优点

1.抛弃了Mutations的操作,简化了代码,本身比vuex更轻量级

2.抛弃了module,没有嵌套,使代码更扁平化

3.有完整的TypeScript支持

三,安装

1.使用任意包管理工具安装pinia

npm install pinia

四,初始化+注册

1.和vuex一样,需要初始化一个pinia实例(store实例),注册到vue中,

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import app from "./App.vue"

const pinia = createPinia() //无需入口文件,扁平化
const app = createApp(App)
app.use(pinia )

2.注意,不同于vuex,初始化时无需入口文件,只要调用createPinia之后即可,之后定义的store,可以任意使用,整体更扁平化

3.同vuexpinia 在全局中也只有一个store实例,在组件外使用时useXxxStore时,需考虑要在实例已经注册之后,在组件内部使用时一定是注册后的,可放心使用

五,store介绍

1.一个完整的store包含3个配置项

(1)状态:state
(2)计算属性:getters
(3)异步修改:actions
(4)同步修改:mutations 弃用
(5)模块化:modules 弃用

六,定义store

1.要定义一个store,需要使用pinia提供的API: defineStore

2.defineStore第一个参数需要是独一无二的值作为该storeid和命名,这也反映了在pinia中每个store都需要命名,

3.defineStore第二个参数可以是OptionAPISetup 函数,定义storestate,actiongetters

(1)Option API 的定义方式基本上和vuex一样,

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    double: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

(2)Setup 函数的使用方式整体像使用hook,使用组合式api,使用ref等定义变量

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  function increment() {
    count.value++
  }

  return { count, increment }
})

七,state

1.定义state

const useStore = defineStore("storeId", {
	//为了完整类型推理,推荐使用箭头函数
	state:()=>{
	 	// 所有这些属性都将自动推断出它们的类型
		userName:"",
		userId:"",
	}
})

2.访问state

const store = useStore()

store.userName

3.修改state

(1)访问时修改

const store = useStore()

store.userName = 'abc'

(2)使用$patch,可支持同一时间更改多个属性

const store = useStore()

store.$patch({
	userName: store.userName + "d",
	userId: '123',
})

//当是复杂类型数据的push,splice等时,用上面的方面需要创建一个新的集合,可以使用下面方法
store.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
})

4.重置state,注意重置整个state为初始值

const store = useStore()

store.$reset()

5.订阅state,当state改变时,调用callback函数,参数如下

cartStore.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  // 和 cartStore.$id 一样
  mutation.storeId // 'cart'
  // 只有 mutation.type === 'patch object'的情况下才可用
  mutation.payload // 传递给 cartStore.$patch() 的补丁对象。

  // 每当状态发生变化时,将整个 state 持久化到本地存储。
  localStorage.setItem('cart', JSON.stringify(state))
})

默认情况下,state subscription 会被绑定到添加它们的组件上 (如果 store 在组件的 setup() 里面)。这意味着,当该组件被卸载时,它们将被自动删除。如果你想在组件卸载后依旧保留它们,可将 { detached: true } 作为第二个参数,以将 state subscription 从当前组件中分离

<script setup>
const someStore = useSomeStore()
// 此订阅器即便在组件卸载之后仍会被保留
someStore.$subscribe(callback, { detached: true })
</script>

八,getter

1.定义getter,使用箭头函数定义,第一个参数是state

const useStore = defineStore("storeId", {
	state:()=>{
		userName:"",
		userId:"",
	},
	getters:{
		bigName:(state) => state.userName + 'big'
	}
})

2.你可以在getter使用this访问整个store实例 ,因此我们可以在getter里访问其他getter

const store = defineStore("storeId", {
	state:()=>{
		userName:"",
		userId:"",
	},
	getters:{
		bigName:(state) => state.userName + 'big',
		bigName2:(state) => state.userName + this.bigName,
	}
})

3.我们可以像访问state一样,访问getter

<div>{{ store.bigName }}</div>

4.在访问getter时,我们可以向getter传递参数,注意,本身getter是不支持传参的,我们可以通过返回一个函数,该函数可以接受任意参数

const store = defineStore("storeId", {
  state: () => {
    userName: "",
      userId: "",
	},
  getters: {
    getUserById: (state) => {
      return (userId) => state.users.find((user) => user.id === userId)
    },
  }
})

九,action

1.同vuex,我们在action里定义方法,同时支持同步或异步方法,可使用async函数

const store = defineStore("storeId", {
  state: () => {
      userName: "",
      userId: "",
	},
  actions:{
  	 increment() {
      this.userName =  123
    },
    async fn(){
      await ....
    }
   }
})

2.我们可以在actions函数中,使用this访问整个store实例,要访问自身storestate,只要使用this.stateProp就行,要访问其他store,在函数中引入这个store即可

3.使用actions里的函数,也摈弃了vuexdispatch方法,只要像调用一个函数一样调用actions里的函数就可以了

<script setup>
const store = useCounterStore()
// 将 action 作为 store 的方法进行调用
store.randomizeCounter()
</script>

<template>
  <!-- 即使在模板中也可以 -->
  <button @click="store.randomizeCounter()">Randomize</button>
</template>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值