• 一文读懂vue3的Pinia


    什么是Pinia

    用官网的一句话来说:Pinia Vue的专属状态管理库

    Pinia就是为vue3而生,当然也支持vue2

    Pinia VS Vuex

    Pinia在使用上更简单,更适合同组合式apiTypescript一同使用

    安装Pinia

    npm install pinia
    # or
    yarn add pinia
    
    • 1
    • 2
    • 3

    vuemain.js中使用

    import { createApp } from 'vue'
    import App from './App.vue'
    import {createPinia} from "pinia";
    const app = createApp(App)
    
    app.use(createPinia())
    
    app.mount('#app')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用Pinia

    定义store

    store通过defineStore()函数进行定义,可以定义多个store,但是定义每个store的时候必须要传入一个唯一的id作为defineStore()的第一个参数

    import { defineStore } from 'pinia'
    
    export const useUserStore = defineStore('user', {
      state: () => ({ user: {
          name: '张三'
      } }),
      getters: {
        userName: (state) => state.user.name,
      },
      actions: {
        setName(name) {
          this.user.name = name
        },
      },
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    也可以定义组合式api形式的store

    • ref()对应 state
    • computed() 对应 getters
    • function() 对应 actions
    export const useUserStore = defineStore('user', () => {
      const user = ref({
          name: '张三'
      })
      
      const userName = computed(() => {
          return user.value.name
      })
      function setName(name) {
          user.value.name = name
      }
    
      return { user, userName, setName }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在vue组件中使用store

    <template>
     <div>
    	<div>用户名: {{userName}}div>
         
    	<button @click="handleClick">设置用户名button>
     div>
    template>
    
    <script lang="ts" setup>
    
    import {useUserStore} from "../stores";
    import {storeToRefs} from "pinia";
    
    const store = useUserStore()
    // 将store中的state或者getter转为响应式变量
    const {userName} = storeToRefs(store)
    // 将store中的action解构出来
    const {setName} = store
    
    const handleClick = () => {
    	increment('李四')
    }
    script>
    <style scoped lang="scss">
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    Pinia之state

    state在store里面是一个返回初始状态的函数

    import { defineStore } from 'pinia'
    
    interface User {
      name: string
      sex: number
    }
    const useUserStore = defineStore('user', {
      // 如果使用的是ts,使用箭头函数可以自动推理出state返回状态的类型
      state: () => {
        return {
          isTest: false
          count: 1,
          userList: [] as User[],
        }
      },
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    访问state
    const store = useUserStore()
    
    store.count++
    
    • 1
    • 2
    • 3
    重置store中的state

    调用$reset()重置之后,state里的状态会全部恢复为初始值

    store.$reset()
    
    • 1
    修改state中的状态

    除了上面store.count++直接修改这种方式,还可以使用$patch函数同时修改多个状态

    store.$patch({
      count: store.count + 1,
      isTest: true,
    })
    // 传入一个函数
    store.$patch((state) => {
      state.count = state.count + 1,
      state.isTest = true
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    订阅state

    通过store$subscribe函数可以监听state 的变化

    store.$subscribe((mutation, state) => {
     console.log(mutation);
     console.log(state);
    })
    
    • 1
    • 2
    • 3
    • 4

    mutation为修改state的方式,主要有三个属性

    • typedirect | patch object | patch function
      • direct:通过等号直接赋值的方式修改state的状态时
      • patch object :通过$patch函数修改并且传入的参数为一个对象时
      • patch function:通过$patch函数修改并且传入的参数为一个函数时
    • storeId:定义当前store时传入的唯一id
    • payloadtypepatch object 时,传入的对象

    Pinia之getter

    getter完全等同于storestate的计算属性,推荐使用箭头函数来定义getter,并将state作为第一个参数。

    getter内部可以通过this方位到整个store

    定义getter
    import { defineStore } from 'pinia'
    export const useUserStore = defineStore('user', {
      state: () => ({ user: {
          name: '张三'
      } }),
      getters: {
        userName: (state) => state.user.name,
      },
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    组合式api的形式定义getter
    export const useUserStore = defineStore('user', () => {
      const user = ref({
          name: '张三'
      })
      // 相当于getter中定义userName
      const userName = computed(() => {
          return user.value.name
      })
      return { user, userName }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    向getter传参

    访问getter时不能传递任何参数,但是可以通过使getter返回一个接收参数的函数的形式来接收参数

    getters: {
        userName: (state) => {
        	return (before) => before + state.user.name
        },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    访问带参getter

    <script>
    export default {
      setup() {
        const store = useUserStore()
        return { getUserName: store.userName }
      },
    }
    script>
    
    <template>
      <p>{{ getUserName('Hi,') }}p>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Pinia之action

    action相当于组件的method,在store中定位为一个函数(可以是异步函数),主要用于处理业务逻辑,在action内部同样可以通过this访问的整个store的属性

    import { defineStore } from 'pinia'
    
    export const useUserStore = defineStore('user', {
      state: () => ({ user: {
          name: '张三'
      } }),
      actions: {
        setName(name) {
          this.user.name = name
        },
      },
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    访问action
    export default {
      setup() {
        const store = useUserStore()
        store.setName('李四')
        return { }
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    订阅action

    通过store$onAction()函数来监听action执行的相关信息.

    $onAction()接收两个参数,第一个参数为一个钩子函数,会在action执行之前调用此钩子函数;第二个参数是一个boolean类型的参数,当前组件被销毁是传入的钩子函数是否继续执行,默认为false

    const store = useUserStore()
    store.$onAction(({name, store, args, after, onError})=>{
    	console.log(`${name} 函数准备开始执行`)
    	console.log(`${name} 函数的参数为:${args}`)
    	after(() => {
    		console.log(`${name} 函数执行完成`)
    	})
    })
    
    // 手动删除监听器
    unsubscribe()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    【经验之谈】关于维修电子设备的几点建议和经验
    RV-GAN:使用新的多尺度生成对抗网络分割眼底照片中的视网膜血管结构
    NEFU linux实验二
    Hive考试练习题(参考题解)
    【SQL】MySQL中的SQL优化、explain执行计划
    参数估计和假设检验的区别与联系
    RMAN-08120的处理
    mulesoft Module 7 quiz 解析
    I.MX6UL的uboot移植
    Vue2 零基础入门 Vue2 零基础入门第五天 5.1 动态组件 && 5.2 插槽
  • 原文地址:https://blog.csdn.net/BDawn/article/details/127894405