Pinia学习笔记

文章目录

  • Pinia优势
  • Pinia 基本使用
  • defineStore 定义一个 Store
  • storeToRefs 解构store
  • 改变状态
  • 替换state
  • 订阅状态

Pinia优势

Pinia是一个全新的Vue状态管理库,是Vuex的代替者,尤雨溪强势推荐

  • Vue2Vue3 都能支持
  • 抛弃传统的 Mutation ,只有 state, getteraction ,简化状态管理库
  • 不需要嵌套模块,符合 Vue3Composition api,让代码扁平化
  • TypeScript支持
  • 代码简介,很好的代码自动分割

Pinia 基本使用

1.安装Pinia: npm i pinia

2.挂载Pinia

// main.js
import {createPinia} from "pinia";

const pinia = createPinia();

app.use(pinia);

3.使用defineStore创建一个store

// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  // 也可以定义为
  // state: () => ({ count: 0 })
  actions: {
    increment() {
      this.count++
    },
  },
})

4.在组件中使用

<template>
  <div>
    <h1>{{counter.count}}</h1>
  </div>
</template>

<script setup>
import { onMounted } from 'vue';

import { useCounterStore } from "../stores/counter";

const counter = useCounterStore();

onMounted(() => {
  counter.count++;
  // 带自动补全 ✨
  counter.$patch({ count: counter.count + 1 });
  // 或使用 action 代替
  counter.increment();
});
</script>

defineStore 定义一个 Store

Store 是使用 defineStore() 定义的,并且它需要一个唯一名称,作为第一个参数传递:

import { defineStore } from 'pinia'

// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {
  // other options...
})

这个 name,也称为 id,是必要的,Pinia 使用它来将 store 连接到 devtools。 将返回的函数命名为 use... 是跨可组合项的约定,以使其符合你的使用习惯。

storeToRefs 解构store

store 是一个用reactive 包裹的对象,这意味着不需要在getter 之后写.value,但是,就像setup 中的props 一样,我们不能对其进行解构。

为了从 Store 中提取属性同时保持其响应式,您需要使用storeToRefs()。 它将为任何响应式属性创建 refs。 当您仅使用 store 中的状态但不调用任何操作时,这很有用:

import { storeToRefs } from 'pinia'

export default defineComponent({
  setup() {
    const store = useStore()
    // `name` 和 `doubleCount` 是响应式引用
    // 这也会为插件添加的属性创建引用
    // 但跳过任何 action 或 非响应式(不是 ref/reactive)的属性
    const { name, doubleCount } = storeToRefs(store)

    return {
      name,
      doubleCount
    }
  },
})

改变状态

除了直接用 store.counter++ 修改 store,你还可以调用 $patch 方法。 它允许您使用部分“state”对象同时应用多个更改:

store.$patch({
  counter: store.counter + 1,
  name: 'Abalam',
})

$patch 方法也接受一个函数来批量修改集合内部分对象的情况:

cartStore.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.hasChanged = true
})

替换state

您可以通过将其 $state 属性设置为新对象来替换 Store 的整个状态:

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

订阅状态

可以通过 store$subscribe() 方法查看状态及其变化,类似于 Vuexsubscribe 方法。 与常规的 watch() 相比,使用 $subscribe() 的优点是 subscriptions 只会在 patches 之后触发一次。

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

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

默认情况下,state subscriptions 绑定到添加它们的组件(如果 store 位于组件的 setup() 中)。 意思是,当组件被卸载时,它们将被自动删除。 如果要在卸载组件后保留它们,请将 { detached: true } 作为第二个参数传递给 detach 当前组件的 state subscription

export default {
  setup() {
    const someStore = useSomeStore()

    // 此订阅将在组件卸载后保留
    someStore.$subscribe(callback, { detached: true })

    // ...
  },
}

你可能感兴趣的:(学习,笔记)