Pinia库的使用及问题分析

Pinia 是一个用于 Vue 的状态管理库,类似 Vuex, 是 Vue 的另一种状态管理方案
Pinia 支持 Vue2 和 Vue3

引用尤雨溪的话:

pinia会替代vuex吗

很大概率,都是core team成员,讨论结果未来形态会很像pinia,新东西都写在pinia里,如果开发一个新项目,如果使用ts,推荐使用pinia。

官网链接:官方文档

Github链接: Github

Pinia和Vuex比的优势

Pinia的使用

安装Pinia

# 使用 npm
npm install pinia@next // v2:应用于vue3中
npm install pinia@latest // v1: 应用于v2中
# 使用 yarn
yarn add pinia@next

提示:pinia@next安装将会安装v2的版本,如果你想要在vue2中使用,需要安装v1:pinia@latest @vue/composition-api. 这里不做介绍了。

创建一个pinia(根储存)并挂载到app上

// vue3中
import { createPinia } from 'pinia'

app.use(createPinia())

// vue2中
import { createPinia, PiniaPlugin } from 'pinia'

Vue.use(PiniaPlugin)
const pinia = createPinia()

new Vue({
  el: '#app',
  // other options...
  // ...
  // note the same `pinia` instance can be used across multiple Vue apps on
  // the same page
  pinia,
})

如何定义一个store?

pinia通过使用一个方法defineStore()来定义store,但是要注意的,store必须要有唯一的名字。

import { defineStore } from 'pinia'

// useStore could be anything like useUser, useCart
// the first argument is a unique id of the store across your application
export const useStore = defineStore('main', {
  // other options...
})

// 或者

export const useStore = defineStore({
	// id: 必须的,在所有 Store 中唯一
  id: 'main',
  // 其他配置
})

使用store

// demo.vue

State

最简单的使用方式state

const store = useStore()

store.counter++

// 重置state
const store = useStore()

store.$reset()

同vuex一样,在使用的时候也可以直接使用mapState遍历state属性(只读)

import { mapState } from 'pinia'

export default {
  computed: {
    // gives access to this.counter inside the component
    // same as reading from store.counter
    ...mapState(useStore, ['counter'])
    // same as above but registers it as this.myOwnName
    ...mapState(useStore, {
      myOwnName: 'counter',
      // you can also write a function that gets access to the store
      double: store => store.counter * 2,
      // it can have access to `this` but it won't be typed correctly...
      magicValue(store) {
        return store.someGetter + this.counter + this.double
      },
    }),
  },
}

通过mapWritableState()函数可以对state进行修改

import { mapWritableState } from 'pinia'

export default {
  computed: {
    // gives access to this.counter inside the component and allows setting it
    // this.counter++
    // same as reading from store.counter
    ...mapWritableState(useStore, ['counter'])
    // same as above but registers it as this.myOwnName
    ...mapWritableState(useStore, {
      myOwnName: 'counter',
    }),
  },
}

这里注意这个方法对数组元素不生效,官网说明如下图:

使用$patch可以进行state值的更新,并且支持多个值同时操作。

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

通过$subscribe() 完成对值变化的监听。

cartStore.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  // same as cartStore.$id
  mutation.storeId // 'cart'
  // only available with mutation.type === 'patch object'
  mutation.payload // patch object passed to cartStore.$patch()

  // persist the whole state to the local storage whenever it changes
  localStorage.setItem('cart', JSON.stringify(state))
})

通过localStorage还可以对值进行一个储存,避免被刷新。
对整个pinia state进行监听的话,使用如下:

watch(
  pinia.state,
  (state) => {
    // persist the whole state to the local storage whenever it changes
    localStorage.setItem('piniaState', JSON.stringify(state))
  },
  { deep: true }
)

Getters

Pinia 中的 Getters 作用与 Vuex 中的 Getters 相同,但使用略有差异。
Pinia 中的 Getters 直接在 Store 上读取,形似 Store.xx,就和一般的属性读取一样。

Getters的基本使用

Getter 第一个参数是 state,是当前的状态,也可以使用 this.xx 获取状态。
Getter 中也可以访问其他的 Getter, 或者是其他的 Store。
例子:

// 修改 store.js
import { defineStore } from "pinia";

import { otherState } from "@/store/otherState.js";

export const useStore = defineStore({
  id: "myGlobalState",
  state: ()=> ({
    count: 2
  }),
  getters: {
    // 一个基本的 Getter: 计算 count 的平方
    // 使用参数
    countPow2(state) {
      return state.count ** 2;
    },
    // 使用 this
    /* 
    countPow2() {
      return this.count ** 2;
    }, 
    */
    // 简单的 Getter 直接使用箭头函数
    // countPow2: state=> state.count ** 2

    // 获取其它 Getter, 直接通过 this
    countPow2Getter() {
      return this.countPow2;
    }

    // 使用其它 Store
    otherStoreCount(state) {
      // 这里是其他的 Store,调用获取 Store,就和在 setup 中一样
      const otherStore = useOtherStore();
      return state.count;
    },
  }
});

// otherState.js
import { defineStore } from "pinia";

export const useStore = defineStore({
  id: "otherState",
  state: ()=> ({
    count: 5
  }),
});

actions

Pinia 没有 Mutations,统一在 actions 中操作 state,通过this.xx 访问相应状态
虽然可以直接操作 Store,但还是推荐在 actions 中操作,保证状态不被意外改变
action 和普通的函数一样
action 同样可以像 Getter 一样访问其他的 Store,同上方式使用其它 Store

// store.js
export const useStore({
  state: ()=> ({
    count: 2,
    // ...
  })
  // ...
  actinos: {
    countPlusOne() {
      this.count++;
    },
    countPlus(num) {
      this.count += num;
    }
  }
})

如何实现一个?

针对这个pinia的使用,前面讲了这么多api的使用,这些也都是在官网中有介绍的,下面在项目中实际来用下这个库


遇到的问题

import VueCompositionAPI from "@vue/composition-api";
import { createPinia } from "pinia";
Vue.use(VueCompositionAPI);
// 这里注意:使用之前必选要先注册VueCompositionAPI
const pinia = createPinia();
展开阅读全文

页面更新:2024-05-04

标签:函数   属性   定义   状态   参数   操作   文档   方式   链接   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top