Vue3 学習 - Pinia 状態管理

パイナップル

ストアを定義する

import {
    
     defineStore } from 'pinia'
export const useStore = defineStore('main', {
    
    })

このnameはidとも呼ばれ、必要であり、ストアを devtools に接続するために Pinia によって使用されます。

返された関数use... の名前付けは、使い慣れたものにするためのコンポーザブル全体の規則です。

ストアを使用する

import {
    
     useStore } from '@/stores/counter'
const storeObj = useStore()
console.log(storeObj.count)

ストアがインスタンス化されると、ストアで定義されたプロパティに直接アクセスできるようになりますstategettersactions

storeは でラップされたオブジェクトですreactive。つまり、 getter の後に記述する必要はありません.value

setupようにpropsそれを分解することはできません

ストアの応答性を維持しながらストアからプロパティを抽出するには、次を使用する必要があります。storeToRefs()

import {
    
     useStore } from '@/stores/counter'
const {
    
     count } = useStore()
console.log(count)//失去响应

#解决
import {
    
     storeToRefs } from 'pinia'
const {
    
     count }  = storeToRefs(useStore())
console.log(count.value)

Pinia では、状態は初期状態を返す関数として定義されます。

const useStore = defineStore('main', {
    
    
    state: () => {
    
    
        return {
    
    count: 0}
})

「状態」にアクセスする

const storeObj = useStore()
store.count++

リセット状態

const storeObj = useStore()
storeObj.$reset()

状態を変更する

悪によって変更可能:store.count++

$patch メソッドを呼び出すことができます

storeObj.$patch({
    
    
    otherProp: 'main'//其他属性
    count: storeObj.count + 1
})

または

storeObj.$patch((state) => {
    
    
    state.item.push({
    
    name: 'RenNing', age: 18})
    state.count = ++state.count
})

$patchこのメソッドは、コレクション内の一部のオブジェクトをバッチ変更する関数も受け入れます。

交換するstate

store.$state = {
    
     counter: 666, name: 'Paimon' } //{ counter: 666, name: 'Paimon' }
store.$state = {
    
    }

元の定義済み属性に対してのみ、未定義のデータが追加されますが、機能しません

購読ステータス

store メソッドを通じて$subscribe()状態とその変更を表示する

通常watch()よりも使用する$subscribe()利点は、サブスクリプションがパッチ後に 1 回だけトリガーされることです。

storeObj.$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 // 补丁对象传递给 to cartStore.$patch()

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

デフォルトでは、状態サブスクリプションは、それを追加したコンポーネントにバインドされます。

コンポーネントがアンマウントされると、それらは自動的に削除されます。

コンポーネントをアンマウントした後も保持したい場合は、{ detached: true }2 番目の引数として渡して、現在のコンポーネントの状態サブスクリプションを切り離します。

storeObj.$subscribe(callback, {
    
    detached: true})

piniaインスタンスの全体のステータスを表示できます。

watch(
  pinia.state,
  (state) => {
    // 每当它发生变化时,将整个状态持久化到本地存储
    localStorage.setItem('piniaState', JSON.stringify(state))
  },
  { deep: true }
)

ゲッター

の属性defineStore()で定義されますgetters

アロー関数の使用を促進するために、最初の引数として「state」を受け入れます

export const useStore = defineStore('count', {
    
    
    state: () =>{
    
    {
    
    count: 1}},
    getters: {
    
    
        //方法一
        doubleCount: (state) => {
    
    return state.count * 2}//方法二
        doublePlusOne(): number {
    
     return this.counter * 2 + 1 },
    }
})

パラメータをゲッターに渡します

# 定义
getters: {
    
    
	getUserId(state) =>{
    
    
        const arr = state.foo.filter(....)
        return (userId) => arr.find(id => userId == id)
    }
}
#使用
{
    
    {
    
    getUserId(2)}}

これを行うと、ゲッターはキャッシュされなくなり、単に呼び出す関数になります。

ただし、一部の結果をゲッター自体の内部にキャッシュすることはできます。

他店のゲッターに聞いてみる

import {
    
    useOtherStore} from './other-sotre'
getters: {
    
    
    otherGetter(state) {
    
    
        const otherStore = useOtherStore()
        return state.localDate + otherStore.data
    }
}

セットアップがありません()

import {
    
     mapState } from 'pinia'
computed:{
    
    
    ...mapState(useCounterStroe, ['doubleCount'])
}

行動

コンポーネント内のメソッドに相当します。ビジネスロジックの定義に適しています

export const useStore = defineStore('main', {
    
    
    actions: {
    
    
        increment() {
    
    this.count++},
        async getApi() {
    
    
            try{
    
    
                let res = await post('url',options)
            }catch{
    
    
                
            }
        }
    },
    
})

getterと同様に、オペレーションには次の方法でthisアクセスできます。

actions非同期にすることもできます

移行

アクションはメソッドと同様に呼び出されます。

useStore.getApi()

setup() には適用されません

mapActions()アクション プロパティは、次を使用してコンポーネント内のメソッドにマッピングできます。

import {
    
     mapActions } from 'pinia'
import {
    
     getApi } from '../stores/useStore.js'
methods:{
    
    
    ...mapActions(getApi)
}

アクションを購読する

次を使用してstore.$onAction()アクションとその結果をサブスクライブします

const unsubscribe = someStore.$onAction(
  ({
    
    
    name, // action 的名字
    store, // store 实例
    args, // 调用这个 action 的参数
    after, // 在这个 action 执行完毕之后,执行这个函数
    onError, // 在这个 action 抛出异常的时候,执行这个函数
  }) => {
    
    
    // 记录开始的时间变量
    const startTime = Date.now()
    // 这将在 `store` 上的操作执行之前触发
    console.log(`Start "${
      
      name}" with params [${
      
      args.join(', ')}].`)

    // 如果 action 成功并且完全运行后,after 将触发。
    // 它将等待任何返回的 promise
    after((result) => {
    
    
      console.log(
        `Finished "${
      
      name}" after ${
      
      
          Date.now() - startTime
        }ms.\nResult: ${
      
      result}.`
      )
    })

    // 如果 action 抛出或返回 Promise.reject ,onError 将触发
    onError((error) => {
    
    
      console.warn(
        `Failed "${
      
      name}" after ${
      
      Date.now() - startTime}ms.\nError: ${
      
      error}.`
      )
    })
  }
)

// 手动移除订阅
unsubscribe()

メソッドの呼び出し時または呼び出し後にトリガーされます

デフォルトでは、アクション サブスクリプションは、アクション サブスクリプションを追加したコンポーネントにバインドされ、アクション サブスクリプションは、アクション サブスクリプションを追加したコンポーネントにバインドされます。

コンポーネントをデタッチした後も保持したい場合は、true現在のコンポーネントのデタッチ アクション サブスクリプションに 2 番目の引数として渡します。

// 此订阅将在组件卸载后保留
someStore.$onAction(callback, true)

おすすめ

転載: blog.csdn.net/weixin_46211267/article/details/132148509