Vue 2 若要 Component 間共享 State,Vuex 算是最簡單方式,但若需求簡單,則 Vuex 又過於麻煩,Vue 3 可簡單使用 Module 取代 Vuex。
Version
Vue 3.2
State Management
雖然有兩個 <MyCounter>
,但只要按下任一 +
都會使 count
遞增,也就是兩個 component 會共用 count
state,且同時對其 reactive。
Page
App.vue
<template>
<MyCounter/>
<MyCounter/>
</template>
<script setup>
import MyCounter from '/src/components/MyCounter.vue'
</script>
同時使用兩個 <MyCounter>
。
Component
MyCounter.vue
<template>
<button @click='onClick'>+</button> {{ count }}
</template>
<script setup>
import useCounter from '/src/modules/useCounter'
let { count, onClick } = useCounter ()
</script>
建立 MyCounter
component,其內的 count
state 與 onClick
都來自於 useCounter
module。
Module
useCounter.js
import { ref } from 'vue'
let count = ref (0)
export default _ => {
let onClick = _ => count.value++
return {
count,
onClick
}
}
第 3 行
let count = ref (0)
將 count
state 搬出 function,因為沒有 function 保護,因此喪失 Closure 機制,count
state 成為 global data,又因為 ref
自帶 reactive,因此所有 component 都會自動改變。
可發現在 Vue 3 不見的要使用 Vuex 才能讓 component 共享 state,可簡單使用 module 與 global data 就能實現
Point-free
useCounter.js
import { ref } from 'vue'
import { read, write } from 'vue3-fp'
import { inc, pipe } from 'ramda'
let count = ref (0)
export default _ => {
let onClick = pipe (
read (count),
inc,
write (count)
)
return {
count,
onClick
}
}
第 8 行
let onClick = pipe (
read (count),
inc,
write (count)
)
onClick
亦可使用 pipe
組合,如此就不用處理 .value
。
Conclusion
- Module 配合 global data 使 Vue 3 有了新用法,不再為了要讓 component 間共享 state 而使用 Vuex,可簡單使用 module 即可