Vuex-全局状态集中式管理神器,做vue项目不知道Vuex真的out了
目錄
一、概念
1.什么是vuex?
2.狀態(tài)管理到底是什么?
3.等等,如果是這樣的話,為什么官方還要專門出一個插件Vuex呢?難道我們不能自己封裝個對象來管理嗎?
4.管理什么狀態(tài)呢?
二、.單界面的狀態(tài)管理
三、多界面的狀態(tài)管理-vuex。
1.安裝vuex
2.vuex是如何實(shí)現(xiàn)多界面狀態(tài)管理的
3.官方給出的一幅圖
4.安裝谷歌devtools插件
5.使用Mutations
五、vuex的核心概念
1.State,單一狀態(tài)樹
2.Getters(類似于計算屬性computed)
3.Mutation(vuex的 store狀態(tài)的更新唯一方式:提交 Mutation)
4.Actions
5.Module
六、項目結(jié)構(gòu)
一、概念
1.什么是vuex?
? ? 官方解釋:Vuex是一個專為Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式。
? ? 它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。
? ? Vuex也集成到Vue的官方調(diào)試工具devtools?extension,提供了諸如零配置的time-travel調(diào)試、狀態(tài)快照導(dǎo)入導(dǎo)出等高級調(diào)試功能。
2.狀態(tài)管理到底是什么?
?? ?狀態(tài)管理模式、集中式存儲管理這些名詞聽起來就非常高大上,讓人捉摸不透。
?? ?其實(shí),你可以簡單的將其看成把需要多個組件共享的變量全部存儲在一個對象里面。
?? ?然后,將這個對象放在頂層的Vue實(shí)例中,讓其他組件可以使用。
?? ?那么,多個組件是不是就可以共享這個對象中的所有變量屬性了呢?
3.等等,如果是這樣的話,為什么官方還要專門出一個插件Vuex呢?難道我們不能自己封裝個對象來管理嗎?
?? ?當(dāng)然可以,只是我們要先想想 Vuejs帯給我們最大的便利是什么呢?沒錯,就是響應(yīng)式。
?? ?如果你自己封裝實(shí)現(xiàn)一個對象能不能保證它里面所有的屬性做到響應(yīng)式呢?當(dāng)然也可以,只是自己封裝可能稍微麻頻一些。
?? ?不用杯疑,Vuex就是為了提供這樣一個在多個組件間共享狀態(tài)的插件,用它就可以了。
4.管理什么狀態(tài)呢?
?? ?但是,有什么狀態(tài)時需要我們在多個組件間共享的呢?
?? ?如果你做過大型開發(fā),你一定遇到過多個狀態(tài),在多個界面間的共享問題。
?? ?比如用戶的登錄狀態(tài)、用戶名稱、頭像、地理位置信息等等。
?? ?比如商品的收藏、購物車中的物品等等。
?? ?這些狀態(tài)信息,我們都可以放在統(tǒng)一的地方,對它進(jìn)行保存和管理,而且它們還是響應(yīng)式的(待會兒我們就可以看到代碼了,莫著急)。
二、.單界面的狀態(tài)管理
?
這圖片中的三種東西,怎么理解呢?? ?
? ? State:不用多說,就是我們的狀態(tài)。(你姑且可以當(dāng)做就是data中的屬性)
? ? View:視圖層,可以針對State的變化,顯示不同的信息。
? ? Actions:這里的Actions主要是用戶的各種操作:點(diǎn)擊、輸入等等,會導(dǎo)致狀態(tài)的改變。
例如,下面的例子一定會實(shí)現(xiàn)吧:
?
?
三、多界面的狀態(tài)管理-vuex。
1.安裝vuex
npm?install?vuex --save
2.vuex是如何實(shí)現(xiàn)多界面狀態(tài)管理的
vue已經(jīng)幫我們做好了單個界面的狀態(tài)管理,但是如果是多個界面呢?
?? ?口多個組件都依賴同一個狀態(tài)(一個狀態(tài)改了,多個界面需要進(jìn)行更新)
?? ?口不同界面的 Actions都想修改同一個狀態(tài)( Home.vue需要修改, Profile.vue也需要修改這個狀態(tài))
也就是說對于某些狀態(tài)(狀態(tài)1/狀態(tài)2/狀態(tài)3)來說只屬于我們某一個組件,但是也有一些狀態(tài)(狀態(tài)a/狀態(tài)b/狀態(tài)c)屬于多個組件共同想要維護(hù)的
?? ?口狀態(tài)1/狀態(tài)2/狀態(tài)3你放在自己的房間中,你自己管理自己用,沒問題
?? ?口但是狀態(tài)a/狀態(tài)b/狀態(tài)c我們希望交給一個大管家來統(tǒng)·幫助我們管理!!!
?? ?口沒錯,vuex就是為我們提供這個大管家的工具
全局單例模式(大管家)
?? ?口我們現(xiàn)在要做的就是將共享的狀態(tài)抽取出來,交給我們的大管家,統(tǒng)一進(jìn)行管理。
?? ?口之后,你們毎個組件,按照我規(guī)癥好的規(guī)定,進(jìn)行訪問和修改等操作。
?? ?口這就是vuex背后的基本思想
3.官方給出的一幅圖
devtools:瀏覽器插件,可以幫助記錄修改之后state的狀態(tài)。
修改state只有通過Mutations修改才能進(jìn)行跟蹤!直接修改state雖然也能改但是無法跟蹤($store.state.count++)
Actions:做異步操作使用Actions;Mutations只能處理同步操作。
?
4.安裝谷歌devtools插件
?
5.使用Mutations
export default new Vuex.Store({
??state: {
?????count: 100
??},
??mutations: {
?????// 方法,只有使用這個修改數(shù)值,才能監(jiān)控到state的變化
?????increment(state) {
??????????state.count ++
?????},
?????decrement(state) {
??????????state.count --
?????}
??}
})
調(diào)用mutations中的方法修改state:
this.$store.commit('increment')
獲取state數(shù)據(jù):
$store.state.count
?
?
五、vuex的核心概念
1.State,單一狀態(tài)樹
定義:
??state: {
?????count: 100
??}
使用:
$store.state.count
vuex提出使用單一狀態(tài)樹什么是單一狀態(tài)樹呢?
?? ?口英文名稱是 Single Source of Truth,也可以翻譯成單一數(shù)據(jù)源
但是,它是什么呢?我們來看個生活中的例子。
?? ?口OK,我用個生活中的例子做一個簡單的類比。
?? ?口我們知道,在國內(nèi)我們有很多的信息需要被記錄,比如上學(xué)時的個人檔案,工作后的社保記錄,公積金記錄,結(jié)婚后的婚姻信息,以及其他相關(guān)的戶口、醫(yī)療、文憑、房產(chǎn)記錄等等(還有很多信息)。
?? ?口這些信息被分散在很多地方進(jìn)行管理,有天你需要辦某個業(yè)務(wù)時(比如入戶某個城市),你會發(fā)現(xiàn)你需要到各個對應(yīng)的工作地點(diǎn)去打印、蓋章各種資料信息,最后到個地方提交證明你的信息無誤。
?? ?口這種保存信息的方案,不僅僅低效,而且不方便管理,以及日后的維護(hù)也是一個龐大的工作(需要大量的各個部門的人力來維護(hù),當(dāng)然國家目前已經(jīng)在完普我們的這個系統(tǒng)了)。
這個和我們在應(yīng)用開發(fā)中比較類似
?? ?口如果你的狀態(tài)信息是保存到多個 Store對象中的,那么之后的管理和維護(hù)等等都會變得特別困難。
?? ?口所以Vuex也使用了單一狀態(tài)樹來管理應(yīng)用層級的全部狀態(tài)。
?? ?口單狀態(tài)樹夠讓我們最直接的方式找到某個狀態(tài)的片段,而且在之后的維護(hù)和調(diào)試過程中,也可以非常方便的管理和維護(hù)。
2.Getters(類似于計算屬性computed)
(1)getters基本使用
?
(2)getters中使用getters:
?
(3)獲取getters中的方法
{{$store.getters.countDouble}}
(4)getters傳參
??getters: {
?????countDouble(state) {
??????????return state.count * 2
?????},
?????mutaByMe(state){
??????????// 返回一個函數(shù),可以使用箭頭函數(shù),并且只有一行的話默認(rèn)就是返回值,并不推薦寫的太簡潔,因為可讀性很差
//????????return function(ct) {
//????????????return state.count * ct
//????????}
??????????????return ct => state.count * ct
?????}
??}
使用:
????<h2>{{$store.state.count * 2}}</h2>
????<h2>{{$store.getters.countDouble}}</h2>
????<h2>{{$store.getters.mutaByMe(5)}}</h2>
?
3.Mutation(vuex的 store狀態(tài)的更新唯一方式:提交 Mutation)
(1)Mutation主要包括兩部分:
?? ?口字符串的事件類型(type)
?? ?口一個回調(diào)函數(shù)( handler),該回調(diào)函數(shù)的第一個參數(shù)就是 state。
(2)Mutation基本使用
?
(3)Mutation傳參(多個參數(shù)的話,可以封裝到一個對象中)
??mutations: {
?????// 方法,只有使用這個才能監(jiān)控到state的變化
?????add5(state, ct){//?payload負(fù)載
??????????state.count = state.count + ct
?????}
??}
this.$store.commit('add5', ct)
?
(4)Mutation提交風(fēng)格
上面通過commit進(jìn)行的提交是一種普通的方式。
Vue還提供了另外一種風(fēng)格,它是一個包含type屬性的對象
?
Mutation中的處理方式是將整個commit的對象作為payload使用,所以代碼沒有改變,依然如下:
?
此時獲取的payload就是commit里面的完整對象。
(5)Mutation響應(yīng)規(guī)則
Vuex的 store中的 state是響應(yīng)式的,當(dāng) state中的數(shù)據(jù)發(fā)生改變時,Vue組件會自動更新。
定義在state中的屬性都被會加入到響應(yīng)式系統(tǒng)中,而響應(yīng)式系統(tǒng)會監(jiān)聽屬性的變化,當(dāng)屬性發(fā)生變化時,會通知所有界面中用到該屬性的地方,讓界面發(fā)生刷新。
這就要求我們必須遵守一些Vuex對應(yīng)的規(guī)則:
?? ?口提前在 store中初始化好所需的屬性(store中對象已經(jīng)定義好的屬性是可以實(shí)現(xiàn)響應(yīng)式的)
?? ?口當(dāng)給 state中的對象添加新屬性時,使用下面的方式方式
?? ?? ? 方式一:使用 Vue.set(obj, 'newProp',123)
?? ??? ?方式二:用新對象給舊對象重新賦值
例如:
1.在state中定義info: {'name':'zs', 'age': 15}。
2.直接在Mutation中修改屬性值是可以實(shí)現(xiàn)響應(yīng)式的
state.info.name = 'ls'
3.這樣新增屬性值是做不到響應(yīng)式的:
state.info['address'] = '山東'
4.新增屬性需要這樣做,才能實(shí)現(xiàn)新屬性的響應(yīng)式:
Vue.set(state.info, 'address', '山東')
5.刪除屬性這樣做也不是響應(yīng)式:
delete state.info.age
6.刪除屬性這樣做才是響應(yīng)式:
Vue.delete(state.info, 'age')
7.直接將state中完整的對象重新賦值也可以實(shí)現(xiàn)響應(yīng)式
state.info = {xxxx}
(6)Mutation類型常量
我們來考慮下面的問題:
?? ?口在 mutation中,我們定義了很多事件類型(也就是其中的方法名稱)
?? ?口當(dāng)我們的項目增大時,Vuex管理的狀態(tài)越來越多,需要更新狀態(tài)的情況越來越多,那么意味著 Mutation中的方法越來越多
?? ?口方法過多,使用者需要花費(fèi)大量的精力去記住這些方法,甚至是多個文件間來回切換查看方法名稱,甚至如果不是復(fù)制的時候可能還會出現(xiàn)寫錯的情況?
(7)Mutation同步代碼
通常情況下,Vuex要求我們 Mutation中的方法必須是同步方法
?? ?口主要的原因是當(dāng)我們使用 devtools時,可以 devtools可以幫助我們捕捉 mutation的快照
?? ?口但是如果是異步操作,那么 devtools將不能很好的追蹤這個操作什么時候會被完成
所以,不要在Mutation中進(jìn)行任何異步操作。
?
4.Actions
(1)定義actions(其中需要調(diào)用mutations方法進(jìn)行參數(shù)的修改,具體參照官網(wǎng)的圖)
??actions: {
??????// context 上下文
??????aUpdateInfo(context){
????????????setTimeout(() => {
??????????????????context.commit(INCREAMENT)
????????????}, 1000)
??????}
??}
(2)使用action
this.$store.dispatch('aUpdateInfo')
(3)傳參參考mutations
(4)異步回調(diào)
?
?
5.Module
(1)Module是模塊的意思,為什么在Vuex中我們要使用模塊呢
?? ?口Vue使用單一狀態(tài)樹,那么也意味著很多狀態(tài)都會交給Vuex來管理
?? ?口當(dāng)應(yīng)用變得非常復(fù)雜時,store對象就有可能變得相當(dāng)臃腫
?? ?口為了解決這個問題Vuex允許我們將 store分割成模塊( Module),而每個模塊擁有自己的 state、 mutation、action、 getters等
?
(2)上面的代碼中,我們已經(jīng)有了整體的組織結(jié)構(gòu),下面我們來看看具體的局部模塊中的代碼如何書寫。
? ? 我們在moduleA中添加state、mutations、getters
? ? mutation和getters接收的第一個參數(shù)是局部狀態(tài)對象
?
?
六、項目結(jié)構(gòu)
?
總結(jié)
以上是生活随笔為你收集整理的Vuex-全局状态集中式管理神器,做vue项目不知道Vuex真的out了的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是Promise?前端开发人员会使用
- 下一篇: vue如何发送网络请求,使用axios事