W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
由于狀態(tài)零散地分布在許多組件和組件之間的交互中,大型應(yīng)用復(fù)雜度也經(jīng)常逐漸增長(zhǎng)。為了解決這個(gè)問(wèn)題,Vue 提供 vuex:我們有受到 Elm 啟發(fā)的狀態(tài)管理庫(kù)。vuex 甚至集成到 vue-devtools,無(wú)需配置即可進(jìn)行時(shí)光旅行調(diào)試 (time travel debugging)。
如果你是來(lái)自 React 的開(kāi)發(fā)者,你可能會(huì)對(duì) Vuex 和 Redux 間的差異表示關(guān)注,Redux 是 React 生態(tài)環(huán)境中最流行的 Flux 實(shí)現(xiàn)。Redux 事實(shí)上無(wú)法感知視圖層,所以它能夠輕松的通過(guò)一些[簡(jiǎn)單綁定_blank_nofollow](https://classic.yarnpkg.com/en/packages?q=redux vue&p=1)和 Vue 一起使用。Vuex 區(qū)別在于它是一個(gè)專門(mén)為 Vue 應(yīng)用所設(shè)計(jì)。這使得它能夠更好地和 Vue 進(jìn)行整合,同時(shí)提供簡(jiǎn)潔的 API 和改善過(guò)的開(kāi)發(fā)體驗(yàn)。
經(jīng)常被忽略的是,Vue 應(yīng)用中響應(yīng)式 data
對(duì)象的實(shí)際來(lái)源——當(dāng)訪問(wèn)數(shù)據(jù)對(duì)象時(shí),一個(gè)組件實(shí)例只是簡(jiǎn)單的代理訪問(wèn)。所以,如果你有一處需要被多個(gè)實(shí)例間共享的狀態(tài),你可以使用一個(gè) reactive 方法讓對(duì)象作為響應(yīng)式對(duì)象。
const sourceOfTruth = Vue.reactive({
message: 'Hello'
})
const appA = Vue.createApp({
data() {
return sourceOfTruth
}
}).mount('#app-a')
const appB = Vue.createApp({
data() {
return sourceOfTruth
}
}).mount('#app-b')
<div id="app-a">App A: {{ message }}</div>
<div id="app-b">App B: {{ message }}</div>
現(xiàn)在當(dāng) sourceOfTruth
發(fā)生變更,appA
和 appB
都將自動(dòng)地更新它們的視圖。我們現(xiàn)在只有一個(gè)真實(shí)來(lái)源,但調(diào)試將是一場(chǎng)噩夢(mèng)。我們應(yīng)用的任何部分都可以隨時(shí)更改任何數(shù)據(jù),而不會(huì)留下變更過(guò)的記錄。
const appB = Vue.createApp({
data() {
return sourceOfTruth
},
mounted() {
sourceOfTruth.message = 'Goodbye' // both apps will render 'Goodbye' message now
}
}).mount('#app-b')
為了解決這個(gè)問(wèn)題,我們采用一個(gè)簡(jiǎn)單的 store 模式:
const store = {
debug: true,
state: Vue.reactive({
message: 'Hello!'
}),
setMessageAction(newValue) {
if (this.debug) {
console.log('setMessageAction triggered with', newValue)
}
this.state.message = newValue
},
clearMessageAction() {
if (this.debug) {
console.log('clearMessageAction triggered')
}
this.state.message = ''
}
}
需要注意,所有 store 中 state 的變更,都放置在 store 自身的 action 中去管理。這種集中式狀態(tài)管理能夠被更容易地理解哪種類型的變更將會(huì)發(fā)生,以及它們是如何被觸發(fā)。當(dāng)錯(cuò)誤出現(xiàn)時(shí),我們現(xiàn)在也會(huì)有一個(gè) log 記錄 bug 之前發(fā)生了什么。
此外,每個(gè)實(shí)例/組件仍然可以擁有和管理自己的私有狀態(tài):
<div id="app-a">{{sharedState.message}}</div>
<div id="app-b">{{sharedState.message}}</div>
const appA = Vue.createApp({
data() {
return {
privateState: {},
sharedState: store.state
}
},
mounted() {
store.setMessageAction('Goodbye!')
}
}).mount('#app-a')
const appB = Vue.createApp({
data() {
return {
privateState: {},
sharedState: store.state
}
}
}).mount('#app-b')
TIP
重要的是,注意你不應(yīng)該在 action 中替換原始的狀態(tài)對(duì)象——組件和 store 需要引用同一個(gè)共享對(duì)象,變更才能夠被觀察到。
接著我們繼續(xù)延伸約定,組件不允許直接變更屬于 store 實(shí)例的 state,而應(yīng)執(zhí)行 action 來(lái)分發(fā) (dispatch) 事件通知 store 去改變,我們最終達(dá)成了 Flux 架構(gòu)。這樣約定的好處是,我們能夠記錄所有 store 中發(fā)生的 state 變更,同時(shí)實(shí)現(xiàn)能做到記錄變更、保存狀態(tài)快照、歷史回滾/時(shí)光旅行的先進(jìn)的調(diào)試工具。
說(shuō)了一圈其實(shí)又回到了 Vuex,如果你已經(jīng)讀到這兒,或許可以去嘗試一下!
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: