前言
日常開發時有些業務場景功能很複雜,如果將所有代碼都寫在一個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中暴露出的狀態count
和doubleCount
,以及方法increment
和decrement
,無需關注具體的內部邏輯是如何實現的。
上面的封裝其實是有問題的,如果我們將組件拆爲兩個,分別爲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
變量。在我們這裏CountValue
和CountBtn
組件都在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
函數的外面,這樣CountValue
和CountBtn
組件中調用useStore
拿到的count
變量都是我們在useStore
函數外面定義的count
變量。
總結
這篇文章介紹了在多個組件中需要複用狀態和業務邏輯的情況時,我們可以不將這些狀態和業務邏輯寫到pinia
中,而是使用Composition API
將狀態和業務邏輯封裝成一個hooks
。爲了多個組件同時調用hooks
時能夠共用同一個state
狀態,我們需要將定義的變量寫在useStore
函數外面。
如果我的文章對你有點幫助,歡迎關注公衆號:【歐陽碼農】,文章在公衆號首發。你的支持就是我創作的最大動力,感謝感謝!