一個東西,首先要知道為什么用它,為什么要vuex,官方解釋為了解決繁雜事件訂閱和廣播,那么事件的$dispatch,$on,怎么就復雜了?許多人是不是感覺后者還挺簡單的,對的
如果簡單小型項目,那么不需要vuex,只需要后者就可以,但是如果中大型,尤其是有許多事件傳播,那么vuex作用就體現出現了,為什么?ok,$dispatch,$on,這種傳播,如果是單向的還好,向上,向下,但是如果非單向,那么必定是先傳上去,在傳下來,中間還要監聽好各自事件別給我整亂了。。。試想一下,一個中大型項目,這里會發生什么?一個字亂,有的時候一個事件,對應的模塊都要找半天,而vuex個人感覺相當於中介,又可以看作是模塊化,一種對事件通信的模塊化處理。。。對一個事件,vuex大體可以看作四步,第一到action里面查到這個事件的觸發,然后立馬是mutaction里面查看對應處理,第三步改變store的狀態,第四部getter視圖渲染;
vuex三個關鍵詞:action,mutation,store,中文意思:活動的,突變的,儲存的,注意action,mutation,getter都必須是函數
下面一個從無到有一個例子;展示vuex(以中大型結構為例 加減為例)
首先我新建個mutation-type.js,這個文件的目的是申明整個項目存在的事件有哪些。。。代碼如下
export const PLUS = 'PLUS' export const MINS = 'MINS' //本例就是兩個事件,
接着新建actions文件夾,然后建三個js文件,分別為plus和mins對應的函數操作,以及總的actions文件
代碼如下(由於兩者相似,以plus為例):
import {PLUS} from '../mutation-type'
export const plus = ({dispatch}, num) => { dispatch(PLUS, num) } 意思就是我這里是處理plus的,所以我先把我事件類型里的那個plus導入過來,對組件提供一個plus函數作為接口,這個函數是進行一個plus事件的dispatch操作,所以肯定第一個參數是
dispatch,這里函數名可以任何名字,
只要與你對應組件里名字對應即可,如果組件里面傳的是this,則參數可以直接進行dom操作,用法,num.$el直接獲取該組件的dom節點
總的action文件代碼如下:
import {del} from './actions/mins' import {plus} from './actions/plus' export {del,plus}
ok,現在action有了,開始對應的組件,分別plus,mins,display,以及根app,由於mins和plus相似,所以二者只寫一個plus;
plus代碼如下
<template> <div> <button @click='add(2)'>Increment +1</button>//為了注明這里的add對應是actions鍵key而不是value,()里面可以傳參數 </div> </template> <script> import * as actions from '../../vuex/demo3/actions' export default { vuex: { actions: { add: actions.add } } } </script> 注意:寫了actions之后,如果同時具備methods,則method無效,此外,actions里面如果傳this的話,則在對應js里面接受可以通過參數的$el,進行dom操作
display組件代碼如下:
<template> <div> <h3>plus is {{num }}</h3> <h3>mins is {{mynum}}</h3> </div> </template> <script> export default { vuex: { getters: { num:({plus})=>plus.num,//這里getter的第一參數永遠默認為是state,很容易理解,因為我獲取的是狀態,
也就是如果你直接寫(plus)的話,就必須寫成(plus)=》plus.plus.num mynum:({mins})=>mins.num } } } </script> 注意,如果寫了getter繼續寫data的話,則getter無效,官網上也專門寫過getter函數,就是封裝相應值得處理
app代碼如下
<template> <div> <Display></Display> <Increment></Increment> <mins></mins> </div> </template> <script> import store from '../../vuex/demo2/store' import Display from './display.vue' import Increment from './increse.vue' import mins from './mins.vue' export default { el:"#app", components: { Display, Increment,mins }, store:store//這里如果鍵值一樣的話,可以直接簡寫store } </script>
我要隨時要監聽狀態吧,那得在對應模塊的根目錄上有個狀態位吧,所以這里寫store,這里有了之后,子組件會自動接收,相當於完成一個類似向下廣播和監聽的作用
接着是plus的mutations文件代碼
import {PLUS} from '../mutation-type' const state = { num: 0 } const mutations={ PLUS(state,num){//注意這官網是[PLUS],但是把中括號去掉也是可以,效過沒區別,這是因為你mutations-type里面const A =‘A’,變量常量是一樣的,如果這里const A= bb這時候這里的
[]就有作用了,類似變量匹配的意思; state.num=state.num+num } } export default { state, mutations } 這段意思大概是現在actions已經觸發了,dispatch了plus事件,我得有個監聽處理吧,這的 mutation就是監聽對應的時間相當於之前的event選項;你要處理所以第一個參數肯定是state狀態啊,第二個就是對應事件傳的參數,對外傳一個狀態和處理函數
然后各個零件匯總得到store.js代碼如下
import Vue from 'vue' import Vuex from 'vuex' import plus from './mutations/plus' import mins from './mutations/mins' Vue.use(Vuex) export default new Vuex.Store({ modules:{ plus,mins } }) 這里把這兩個事件,看成各自模塊,於是module選項里寫入各自模塊名字,對外提供一個大的vuex實例,注意這里中文文檔可能不是這樣寫的,以英文文檔為有效答案
ok這個時候運行webpack,一個中等項目結構的vuex就形成了,其實回看,既然vuex做了dispacth和boardcast做的事情並取締了它,那么肯定具備了相應功能,什么時候需要dispatch,boardcast呢,以及哪些玩意需要保存在store里呢?我個人理解為,當一個全局組件需要一個事件才能做出對應響應,需要事件機制,比如說全局有個模態窗口,各個特定組件點擊時候,都會顯示各個組件對應得data時候,這時候需要事件機制,那么我那些東西需要存在store里面。這里如果有ng經驗的,個人覺得可以把這個store70%理解為ng里面的rootscope,也就是類似一個全局的意思,且會根據子組件變動的東西叫store,舉個例子,現在有個提示彈窗,里面有按鈕和一些提示文字和數字,其中數字會根據子組件變化,而文字是死的,所以這里數字可以存在store里面;那么和localstorege有啥區別?locastorge會自動變化嗎?不會,store會
當然這只是理解入門,更深一步操作,還需要各位慢慢琢磨,認識具有反復性和無限性,呵呵