浅尝大菠萝Pinia

1、pinia简介

Pinia(发音为 /piːnjʌ/,类似于英语中的“peenya”)是最接近有效包名 piña(西班牙语中的_pineapple_)的词。

Pinia 是由 Vue.js 团队成员开发,新一代的状态管理器,即 Vuex5.x

浅尝大菠萝Pinia_第1张图片

特点:

  • 对 Vue 2 和 Vue 3 都有效

  • 完整的 typescript 的支持

  • 只有 state, getter 和 action ,去掉了mutations,简化状态管理库

  • actions 支持同步和异步方法修改 state 状态

  • 不再有模块嵌套,只有 Store 的概念,Store 之间可以相互调用

  • 足够轻量,压缩后的体积只有1.6kb

  • 使用插件扩展 Pinia 功能

2、使用方式

安装

npm install pinia

创建 Store

新建 src/store 目录并在其下面创建 index.js,导出 store

import { createPinia } from 'pinia'
const store = createPinia()
export default store

 在 main.js 中引入并使用

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'

const app = createApp(App)
app.use(store)
app.mount('#app')

3、State

store 的核心部分。 我们通常从定义应用程序的状态开始。 在 Pinia 中,状态被定义为返回初始状态的函数。 Pinia 在服务器端和客户端都可以工作。

定义state

import { defineStore } from 'pinia'

export const useUserStore = defineStore({
    id: 'user', // id必填,且需要唯一
    state: () => {
        return {
            name: '牛牛'
        }
    }
})

获取state

import {useUserStore} from "@/store/user";
const userStore = useUserStore()
const name = computed(() => userStore.name)

修改state

(1) 直接修改

userStore.name = '芳芳'

优点:最简单直接的修改方法,代码少。

缺点:只能一次修改一个,不能修改多个。全局的状态管理还是不要直接在各个组件处随意修改状态,应放于 action 中统一方法修改

(2)通过storeToRefs转为ref后修改

 const {name} = storeToRefs(userStore)
 name.value = '芳芳'

不使用storeToRefs 直接解构会失去响应式,导致修改失败

优点:可以解构store中的内容,代码也不多。

缺点:不能一次修改多个,而且还需要引入storeToRefs,比第一种方法多了一点代码。

(3)$patch

可传对象或函数

  userStore.$patch({
    name: '芳芳'
  })
// 不能直接修改原来的state,对state中的数组或对象不能增加或删除,只能创建新的对象进行赋值。
userStore.$patch(state=>{
    state.name='芳芳'
  })
// 可以一次修改多个,可以修改原来的state,对state中的数组或对象可以使用方法修改

(4)action

action 里可以直接通过 this 访问

// store中
import { defineStore } from 'pinia'

export const useUserStore = defineStore({
    id: 'user', // id必填,且需要唯一
    state: () => {
        return {
            name: '牛牛'
        }
    },
    actions: {
        updateName(name) {
            this.name = name
        }
    }
})
// 具体使用
 userStore.updateName('芳芳')

 重置state

const reset = () => {
  userStore.$reset()
}

4、Getters

等同于 Store 状态的计算值

 getters: {
        fullName1: (state) => {
            return state.name = state.name + '放大镜'
        },
        fullName2 () {
            return this.name = '芳芳放大镜'
        }
    },

5、Action

相当于组件中的 methods,适合定义业务逻辑

  • action 可以像写一个简单的函数一样支持 async/await 的语法,让你愉快的应付异步处理的场景。

  • action 间的相互调用,直接用 this 访问即可。

  • 在 action 里调用其他 store 里的 action 也比较简单,引入对应的 store 后即可访问其内部的方法了。

 changePwd(value) {
            const pwdStore = usePwdStore()
            pwdStore.changePwd(value)
            this.pwd = pwdStore.getPwd
        }

6、Plugins

由于是底层 API,Pania Store 完全支持扩展。以下是可以扩展的功能列表:

  • 向 Store 添加新状态

  • 定义 Store 时添加新选项

  • 为 Store 添加新方法

  • 包装现有方法

  • 更改甚至取消操作

  • 实现本地存储等副作用

  • 仅适用于特定 Store

Pinia 插件是一个函数,接受一个可选参数 contextcontext 包含四个属性:app 实例、pinia 实例、当前 store 和选项对象。

函数也可以返回一个对象,对象的属性和方法会分别添加到 state 和 actions 中。

export function myPiniaPlugin(context) {
  context.app // 使用 createApp() 创建的 app 实例(仅限 Vue 3)
  context.pinia // 使用 createPinia() 创建的 pinia
  context.store // 插件正在扩展的 store
  context.options // 传入 defineStore() 的选项对象(第二个参数)
  // ...
  return {
    hello: 'world', // 为 state 添加一个 hello 状态
    changeHello() { // 为 actions 添加一个 changeHello 方法
      this.hello = 'pinia'
    }
  }
}

然后使用 store.use() 将此函数传递给 pinia 就可以了

这对于添加全局对象(如路由器\ toast 管理器)很有用。

还可以在定义 store 时创建新选项,以便以后从插件中使用它们。

例如,您可以创建一个 debounce 选项,允许您对任何操作进行去抖动:

defineStore('search', {
  actions: {
    searchContacts() {
      // ...
    },
  },

  // 稍后将由插件读取
  debounce: {
    // 将动作 searchContacts 防抖 300ms
    searchContacts: 300,
  },
})

然后插件可以读取该选项以包装操作并替换原始操作:

if (context.options.debounce) {
        // 我们正在用新的action覆盖这些action
        return Object.keys(context.options.debounce).reduce((debouncedActions, action) => {
            debouncedActions[action] = debounce(
                context.store[action],
                context.options.debounce[action]
            )
            return debouncedActions
        }, {})
    }

7、vuex

浅尝大菠萝Pinia_第2张图片

在 Vuex store(仓库)中,有4个主要组件。

1. State

这只是一个包含实际状态的对象。我们可以在开发工具中看到这个状态,如果想保留这个状态用于缓存或其他目的,也可以保存这个对象。

2. Actions

Actions 是执行异步任务的函数。它们是由关键字dispatch发起的。

Actions 通常会请求一个外部 API 或做一些其他的异步工作。它还负责调用适当的 mutation 来实际改变状态。这说明 actions 本身并没有改变状态,而是 commit 变化,让 mutation 来改变状态。

3. Mutations

Mutation 是唯一会真正同步改变状态的函数。Mutations 使用关键字commit。

4. Getters

Getters可以被认为是计算过的属性,应该被用来从状态中获得一个修改过的响应。

const store = createStore({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

8、总结

Pinia 整体来说比 Vuex 更加简单、轻量,但功能却更加强大,也许这就是它取代 Vuex 的原因吧~

完整demo代码:来自东北的大黑猫 / my-pinia-demo · GitCode


参考文档

介绍 | Pinia 中文文档

大菠萝?Pinia已经来了,再不学你就out了 - 掘金

还有人没尝过 Pinia 吗,请收下这份食用指南! - 掘金

测试一下Pinia,Vuex 要出局了?_@大迁世界的博客-CSDN博客

28 vue3 Pinia修改state的三种方法(直接修改,$patch,actions)_Jay丶千珏的博客-CSDN博客

Pinia修改State的四种方式_web前端小学生的博客-CSDN博客

你可能感兴趣的:(pinia,vuex5,javascript,前端,vue.js)