欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue使用Pinia輕松實(shí)現(xiàn)狀態(tài)管理

 更新時(shí)間:2023年06月08日 10:45:36   作者:格斗家不愛在外太空沉思  
pinia,一個(gè)基于Vue3的狀態(tài)管理庫(kù),它可以幫助開發(fā)人員管理Vue應(yīng)用程序的狀態(tài),本文主要為大家介紹了Pinia的用法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

pinia,一個(gè)基于Vue3的狀態(tài)管理庫(kù),它可以幫助開發(fā)人員管理Vue應(yīng)用程序的狀態(tài),Pinia使用Vue3的Composition API提供了更簡(jiǎn)單,靈活的狀態(tài)管理方式,通過(guò)創(chuàng)建store來(lái)管理應(yīng)用程序的狀態(tài),還提供了插件和工具來(lái)幫助開發(fā)人員更輕松的使用它。

Pinia對(duì)比VueX

之前我們?cè)趘ue2的時(shí)候使用的狀態(tài)管理庫(kù)是VueX,在Vue3中想使用VueX,需要使用到VueX4版本,而在Vue3組合式API下設(shè)計(jì)了全新的狀態(tài)管理庫(kù):Vuex5,也就是Pinia(已經(jīng)被納入官方了)

那Pinia相比VueX有什么優(yōu)勢(shì)呢?

在當(dāng)時(shí)pinia的作者就作出了這么一個(gè)提案:

  • pinia都支持在vue2和vue3中使用
  • 在vuex想修改數(shù)據(jù)狀態(tài)需要mutations,而pinia去掉了mutations,只有state,getters和actions。修改數(shù)據(jù)狀態(tài)直接在actions里操作,pinia推崇使用類似于 JavaScript 對(duì)象的方式來(lái)更新狀態(tài),即直接對(duì) state 進(jìn)行修改,可以減少代碼量,并且降低了出錯(cuò)的可能性
  • pinia中沒(méi)有嵌套模塊,在vuex中我們可能會(huì)用到大量的模塊,一層套一層,使?fàn)顟B(tài)管理變得復(fù)雜,也有可能會(huì)造成命名沖突,在Composition API下pinia中可以定義多個(gè)store,然后將多個(gè)store組合在一起,變得更加靈活
  • 完整的TypeScript支持,vuex對(duì)ts的類型檢查,類型推斷和泛型的支持都不太友好,模塊命名空間的支持也不夠完善

除此之外兩者的api都是相同的,使用的方式也是相同的,關(guān)于vuex的使用可以看看之前寫的vuex文章

Pinia的使用

安裝pinia

使用pinia需要先安裝,可以通過(guò)yarn或者npm安裝

yarn add pinia 
# or with npm 
npm install pinia

在vue2中使用,你還需要安裝一個(gè)插件并pinia在應(yīng)用程序的根目錄注入創(chuàng)建的,如果vue版本<2.7,還需要安裝 composition api: @vue/composition-api

安裝完之后在入口文件引入pinia的createPinia方法并調(diào)用得到pinia的實(shí)例,然后掛載到vue實(shí)例上

import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
//創(chuàng)建pinia實(shí)例
const pinia = createPinia();
const app = createApp(App);
//掛載到vue實(shí)例上
app.use(pinia);
app.mount("#app");

定義store容器

在src目錄下創(chuàng)建store目錄來(lái)存放pinia容器相關(guān)代碼,在里面新建了一個(gè)index.ts文件,在index.ts文件里首先要定義一個(gè)容器,定義容器使用defineStore來(lái)定義,主要接收兩個(gè)參數(shù),一個(gè)是容器的名字(唯一),另一個(gè)是容器的對(duì)象,最后將容器導(dǎo)出,就可以在組件中使用了

import { defineStore } from "pinia";
export const useTestStore = defineStore("test", {
  /**
   * 類似組件中的data,存儲(chǔ)全局狀態(tài)
   * 必須是箭頭函數(shù),避免數(shù)據(jù)狀態(tài)污染
   */
  state: () => {
    return {
      message: "hello world",
      count:0,
    };
  },
  /**
   * 類似組件中的computed
   */
  getters: {},
  /**
   * 類似組件中的methods,封裝業(yè)務(wù)邏輯,修改state
   */
  actions: {},
});

在組件中導(dǎo)入并使用容器

state的使用

在組件中導(dǎo)入容器并且調(diào)用,得到容器的實(shí)例,就可以直接使用state里的數(shù)據(jù)或者在模板中展示

<script setup lang="ts">
import { useTestStore } from "./store";
const store = useTestStore();
</script>
<template>
  <div>{{ store.message }}</div>
</template>
<style scoped>
</style>

也可以使用解構(gòu)的方式拿到和使用數(shù)據(jù),但是這樣拿到的數(shù)據(jù)不是響應(yīng)式的,修改的時(shí)候頁(yè)面上是不會(huì)發(fā)生變化的

<script setup lang="ts">
import { useTestStore } from "./store";
const store = useTestStore();
//解構(gòu)state
const { message, count } = store;
const countAdd = () => {
  store.count++;
};
</script>
<template>
  <div>
    <div>{{ store.message }}</div>
    <div>{{ store.count }}</div>
    <hr />
    <div>{{ "解構(gòu)后:" + message }}</div>
    <div>{{ "解構(gòu)后:" + count }}</div>
    <button @click="countAdd">count++</button>
  </div>
</template>
<style scoped>
</style>

針對(duì)這種情況解決的辦法就是解構(gòu)的時(shí)候使用pinia的storeToRefs方法將實(shí)例包裹住,state里的數(shù)據(jù)就變成響應(yīng)式的了

import { storeToRefs } from "pinia";
//解構(gòu)state,對(duì)state里的數(shù)據(jù)做了reactive處理
const { message, count } = storeToRefs(store);

狀態(tài)的更新和actions的使用

在組件里修改state的狀態(tài)的時(shí)候有三種方式:

  • 直接修改
  • $patch直接修改
  • $patch通過(guò)函數(shù)修改
const countAdd = () => {
  // 直接修改
  store.count++;
  store.message = 'hello pinia'
  // 修改多個(gè)數(shù)據(jù) $patch批量修改
  store.$patch({
    count: store.count + 1,
    message: "hello pinia",
  });
  // $patch 函數(shù)(推薦)
  store.$patch(state=>{
    state.count++
    state.message = "hello pinia"
  })
};

也可以通過(guò)actions處理,在actions定義一個(gè)方法,通過(guò)this訪問(wèn)當(dāng)前實(shí)例拿到state里的數(shù)據(jù),就像vue2的options API一樣在methods里拿data里的數(shù)據(jù)

// store
actions: {
    handleChangeState() {
      this.message = "hello pinia";
      this.count++;
    },
},
//component
const countAdd = () => {
  store.handleChangeState();
};

也可以在調(diào)用actions里的方法的時(shí)候傳遞參數(shù)

// store
actions: {
    handleChangeState(num?: number) {
      this.count += num ?? 0;
    },
},
//component
const countAdd = () => {
  store.handleChangeState(10);
};

getters的使用

getters類似組件中的computed,接收一個(gè)state參數(shù),這個(gè)state就是容器里的state狀態(tài)對(duì)象,當(dāng)依賴的state發(fā)生變化的時(shí)候pinia就會(huì)自動(dòng)更新getters的值,而且getters具有默認(rèn)的緩存機(jī)制

如果一個(gè)getter所依賴的state沒(méi)有發(fā)生變化,那么就返回上一次計(jì)算的結(jié)果,而不會(huì)重新計(jì)算,顯著提高了性能

// getters
getters: {
    // typescript自動(dòng)推導(dǎo)返回值類型
    countMUL10(state) {
      console.log("getter被調(diào)用了");
      return state.count * 10;
    },
    // or手動(dòng)指定返回值類型
    countMUL10():number {
      console.log("getter被調(diào)用了");
      return this.count * 10;
    },
},
//component
<template>
  <div>
    <div>{{ store.count }}</div>
    // 調(diào)用多次
    <div>{{ store.countMUL10 }}</div>
    <div>{{ store.countMUL10 }}</div>
    <div>{{ store.countMUL10 }}</div>
    <button @click="countAdd">count++</button>
  </div>
</template>

store容器調(diào)用另一個(gè)store容器

如果你想在一個(gè)Store中使用另一個(gè)Store,就和在組件中使用store一樣操作就可以了

import { defineStore } from "pinia";
//導(dǎo)入一個(gè)store容器
import { useTestStore } from ".";
export const useLoginStore = defineStore("login", {
  state: () => {
    return {};
  },
  getters: {},
  actions: {
    handlerOtherStore() {
      //得到store實(shí)例,調(diào)用實(shí)例里的方法
      const testStore = useTestStore();
      testStore.handleChangeState(10);
    },
  },
});

以上就是Vue使用Pinia輕松實(shí)現(xiàn)狀態(tài)管理的詳細(xì)內(nèi)容,更多關(guān)于Vue Pinia的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論