有了Composition API後,有些場景或許你不需要pinia了

前言

日常開發時有些業務場景功能很複雜,如果將所有代碼都寫在一個vue組件中,那個vue文件的代碼量可能就幾千行了,維護極其困難。這時我們就需要將其拆分爲多個組件,拆完組件後就需要在不同組件間共享數據和業務邏輯。有的小夥伴會選擇將數據和業務邏輯都放到pinia中,這樣雖然可以解決問題。但是如果將所有的複雜的業務都放在pinia中,那麼pinia就會變得很亂。

將數據和業務邏輯都封裝到hooks

這時你還有另外一個選擇,使用Composition API將數據和業務邏輯都抽取到hooks中。state狀態的定義和更新以及具體的業務邏輯全部由hooks內部維護,組件只負責使用hooks暴露出的state狀態和方法。

下面是我們封裝的hooks

export const useStore = () => {
  const count = ref(0);

  const doubleCount = computed(() => {
    return count.value * 2;
  });

  function increment() {
    count.value = count.value + 1;
  }

  function decrement() {
    count.value = count.value - 1;
  }

  return {
    count,
    doubleCount,
    increment,
    decrement,
  };
};

組件只需要使用hooks中暴露出的狀態countdoubleCount,以及方法incrementdecrement,無需關注具體的內部邏輯是如何實現的。

上面的封裝其實是有問題的,如果我們將組件拆爲兩個,分別爲CountValue.vue(顯示count的值)和CountBtn.vue(修改count變量值)。

CountValue.vue組件代碼如下:

<template>
  <p>count的值是{{ count }}</p>
  <p>doubleCount的值是{{ doubleCount }}</p>
</template>

<script setup lang="ts">
import { useStore } from "./store";

const { count, doubleCount } = useStore();
</script>

CountBtn.vue組件代碼如下:

<template>
  <button @click="decrement">count--</button>
  <button @click="increment">count++</button>
</template>

<script setup lang="ts">
import { useStore } from "./store";

const { decrement, increment } = useStore();
</script>

由於我們的count變量是在useStore函數中定義的,所以每調用一次useStore函數都會重新定義一個count變量。在我們這裏CountValueCountBtn組件都在setup中調用了useStore函數,通過useStore函數拿到的就不是同一個count變量。這樣就會導致我們在CountBtn中修改了count變量的值,但是CountValue組件中顯示的count變量的值一直沒變。

多個組件同時調用hooks如何共享同一份state狀態

要解決上面的問題其實很簡單,問題的原因是因爲每次調用useStore函數都會生成一個新的count變量。那我們就不將count變量的定義寫在useStore函數中,只需要將count變量的定義寫在useStore函數的外面就可以了。

下面是優化後的hooks

import { computed, ref } from "vue";

// 將count的定義放在外面
const count = ref(0);
const doubleCount = computed(() => {
  return count.value * 2;
});

export const useStore = () => {
  function increment() {
    count.value = count.value + 1;
  }

  function decrement() {
    count.value = count.value - 1;
  }

  return {
    count,
    doubleCount,
    increment,
    decrement,
  };
};

我們將count變量定義放在了useStore函數的外面,這樣CountValueCountBtn組件中調用useStore拿到的count變量都是我們在useStore函數外面定義的count變量。

總結

這篇文章介紹了在多個組件中需要複用狀態和業務邏輯的情況時,我們可以不將這些狀態和業務邏輯寫到pinia中,而是使用Composition API將狀態和業務邏輯封裝成一個hooks。爲了多個組件同時調用hooks時能夠共用同一個state狀態,我們需要將定義的變量寫在useStore函數外面。

如果我的文章對你有點幫助,歡迎關注公衆號:【歐陽碼農】,文章在公衆號首發。你的支持就是我創作的最大動力,感謝感謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章