(二)Pinia(解构store--Actions-- getters )

1,129 阅读1分钟

解构store

Pinia是不允许直接解构是会失去响应性的

解决方案可以使用 storeToRefs
import { storeToRefs } from 'pinia'
 
const Test = useTestStore()
 
const { current, name } = storeToRefs(Test)

其原理跟toRefs 一样的给里面的数据包裹一层toref

源码 通过toRaw使store变回原始数据防止重复代理

循环store 通过 isRef isReactive 判断 如果是响应式对象直接拷贝一份给refs 对象 将其原始对象包裹toRef 使其变为响应式对象

image.png

Actions(支持同步异步)

同步和简单的异步

index.js

import { defineStore } from 'pinia'

export const useNameStore = defineStore('Name',{
  state: () => {
    return {
      name: '小1111李',
      age:'18'
    }
  },
  getters: { // computed  修饰一些值
    
  },
  actions: { // methods  可以做同步  异步都可以做  提交到state
    changeName () {
      this.name = '我修改了名字'
      console.log(this);
    },
    changeAge () {
      setTimeout(() => {
        this.age = 10000
      },3000)
    }
  }

})
组件.js
<script setup>
import {useNameStore } from '../stores/index'

const Name = useNameStore()
const onAge = () => {
  setTimeout(() => {
    Name.age++
  }, 1000)
  Name.changeName()
  Name.changeAge()
}
</script>

<template>
  <div>
pina:{{ Name.name  }} + {{ Name.age }}
<button @click="onAge">点击修改age</button>
  </div>
</template>

异步 可以结合async await 修饰

import { defineStore } from 'pinia'
import { Names } from './store-naspace'
 
type Result = {
    name: string
    isChu: boolean
}
 
const Login = (): Promise<Result> => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({
                name: '小满',
                isChu: true
            })
        }, 3000)
    })
}
 
export const useTestStore = defineStore(Names.TEST, {
    state: () => ({
        user: <Result>{},
        name: "123"
    }),
    actions: {
        async getLoginInfo() {
            const result = await Login()
            this.user = result;
        }
    },
})

template

<template>
     <div>
         <button @click="Add">test</button>
          <div>
             {{Test.user}}
          </div>    
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {
     Test.getLoginInfo()
}
 
</script>
 
<style>
 
</style>

多个action互相调用getLoginInfo  setName

    state: () => ({
        user: <Result>{},
        name: "default"
    }),
    actions: {
        async getLoginInfo() {
            const result = await Login()
            this.user = result;
            this.setName(result.name)
        },
        setName (name:string) {
            this.name = name;
        }
    },

getters

1.使用箭头函数不能使用this this指向已经改变指向undefined 修改值请用state

主要作用类似于computed 数据修饰并且有缓存

    getters:{
       newPrice:(state)=>  `$${state.user.price}`
    },

2.普通函数形式可以使用this

    getters:{
       newCurrent ():number {
           return ++this.current
       }
    },

3.getters 互相调用

    getters:{
      newCurrent ():number | string {
          return ++this.current + this.newName
      },
      newName ():string {
          return `$-${this.name}`
      }
   },