Vue3狀態(tài)管理的使用詳解
隨著Vue3的逐步應(yīng)用,對(duì)狀態(tài)管理的需求越來(lái)越多。起初是基于Vuex4進(jìn)行狀態(tài)管理的,但是Vuex4也暴露了一些問(wèn)題。從個(gè)人角度來(lái)說(shuō),Vuex4類似于過(guò)渡期產(chǎn)品,對(duì)TypeScript的支持性并不完整。如果使用TypeScript編寫組件,需要遵循一定步驟后,才可以正確進(jìn)行類型推斷,并且對(duì)modules的使用上也并不友好。Vuex核心貢獻(xiàn)者Kia King也表示Vuex5已經(jīng)在計(jì)劃中,并且能提供完整的TypeScript支持,那么在Vuex5面世之前,或者直接'舍棄'Vuex的話有沒(méi)有其他狀態(tài)管理的方案?
Provide / Injectprovide和inject并不是Vue3的新特性,在Vue2中就已經(jīng)存在了。文檔中提到provide和inject綁定并不是可響應(yīng)的。然而,如果你傳入了一個(gè)可監(jiān)聽(tīng)的對(duì)象,那么其對(duì)象的property還是可響應(yīng)的。
Vue3在Computed與watch的基礎(chǔ)上新增了響應(yīng)性API ref和reactive,可以更加方便provide和inject的應(yīng)用,再結(jié)合Composition API的思想,是否能實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的狀態(tài)管理?
// src/context/calculator.tsimport { ref, inject, provide, readonly } from ’vue’;type Calculator = { count: number; increase: () => void; updateCount: (num: number) => void;};//provide的key,唯一令牌const CalculatorSymbol = Symbol();//提供者export const calculatorProvide = () => { //數(shù)目 const count = ref<number>(1); //遞增方法 const increase = () => {count.value++; }; //更新方法 const updateCount = (num: number) => {count.value = num; }; //提供的共享狀態(tài)對(duì)象 const depends = {count: readonly(count), //狀態(tài)只讀,通過(guò)方法進(jìn)行修改increase,updateCount }; //使用provide api實(shí)現(xiàn)狀態(tài)對(duì)象提供 provide(CalculatorSymbol, depends); //返回狀態(tài)對(duì)象,讓同級(jí)可調(diào)用 return depends;};//注入方法export const calculatorInject = () => { //使用inject api注入狀態(tài) const calculatorContext = inject<Calculator>(CalculatorSymbol); //未共享就注入的錯(cuò)誤校驗(yàn) if (!calculatorContext) {throw new Error(’Inject must be used affer Provide’); } //返回注入的貢獻(xiàn)狀態(tài) return calculatorContext;};提供數(shù)據(jù)
相比起Vuex的全局共享,利用Provide / Inject可以實(shí)現(xiàn)全局或者局部共享,
全局共享,可以在main.ts中注入全局狀態(tài):
// src/main.tsimport { createApp, h } from ’vue’;import App from ’@/App.vue’;import { calculatorProvide } from ’@/context/calculator’;// 創(chuàng)建vue實(shí)例const app = createApp({ setup() {calculatorProvide();return () => h(App); }});// 掛載實(shí)例app.mount(’#app’);
如果只想局部共享,可以在父組件中注入狀態(tài)
// src/views/parent.vueimport { defineComponent } from 'vue';import { calculatorProvide } from ’@/context/calculator’;export default defineComponent({ name: 'parent', setup() { //共享數(shù)據(jù) calculatorProvide(); }});注入數(shù)據(jù)
子組件可以通過(guò)狀態(tài)注入,使用或修改狀態(tài)
// src/views/child.vueimport { defineComponent } from 'vue';import { calculatorInject } from ’@/context/calculator’;export default defineComponent({ name: 'child', setup() { //注入數(shù)據(jù) const { count, increase, updateCount } = calculatorInject(); }});小結(jié)
實(shí)際上,你可以將依賴注入(Provide / Inject)看作是'long range props',除了:
父組件不需要知道哪些子組件使用它provide的property 子組件不需要知道inject的property來(lái)自哪里Vue3使依賴注入的使用更加靈活便捷,以此仿造了小型的狀態(tài)管理,個(gè)人測(cè)試上,對(duì)TypeScript的支持性比較完整
reactive那么不使用Provide / Inject,還有別的方法可以實(shí)現(xiàn)狀態(tài)管理嗎?直接上代碼。
抽離共享狀態(tài)// src/context/calculator.tstype Calculator = { count: number; increase: () => void; updateCount: (num: number) => void;};//共享狀態(tài)const calculatorStore = reactive<Calculator>({ count: 1, increase: () => {calculatorStore.count++; }, updateCount: (num: number) => {calculatorStore.count = num; }});export { calculatorStore };使用共享狀態(tài)
使用狀態(tài)的方法很簡(jiǎn)單,只需要import狀態(tài)即可,需要使用狀態(tài)的組件,都需要導(dǎo)入
// src/views/any.vueimport { defineComponent } from 'vue';import { calculatorStore } from ’@/context/calculator’;export default defineComponent({ name: 'any', setup() { console.log(calculatorStore.count); }});小結(jié)
其實(shí)這個(gè)方案利用的是reactive的響應(yīng)性及import同一實(shí)例原理,相比起依賴注入來(lái)的更簡(jiǎn)單粗暴,也能正確支持TypeScript校驗(yàn)。但是依賴注入可以在不同根節(jié)點(diǎn)共享不同的數(shù)據(jù),而這個(gè)reactive方案永遠(yuǎn)共享的是一個(gè)實(shí)例,在某些業(yè)務(wù)場(chǎng)景下并不適用。
結(jié)語(yǔ)首先,Vuex仍舊是更成熟全面的方案,只是針對(duì)一些簡(jiǎn)單的狀態(tài)管理,可以嘗試換個(gè)思路解決;當(dāng)然以上的方案可能還有很多考慮不全地方,歡迎各位大神指點(diǎn)指點(diǎn)~
以上就是Vue3狀態(tài)管理的使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Vue3狀態(tài)管理的使用的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. el-input無(wú)法輸入的問(wèn)題和表單驗(yàn)證失敗問(wèn)題解決2. 不要在HTML中濫用div3. react腳手架配置代理的實(shí)現(xiàn)4. JavaScript中顏色模型的基礎(chǔ)知識(shí)與應(yīng)用詳解5. XML入門的常見(jiàn)問(wèn)題(三)6. JavaScript快速實(shí)現(xiàn)一個(gè)顏色選擇器7. CSS3實(shí)例分享之多重背景的實(shí)現(xiàn)(Multiple backgrounds)8. 前端html+css實(shí)現(xiàn)動(dòng)態(tài)生日快樂(lè)代碼9. Jquery使用原生AJAX方法請(qǐng)求數(shù)據(jù)10. React實(shí)現(xiàn)一個(gè)倒計(jì)時(shí)hook組件實(shí)戰(zhàn)示例
