關於vuex類的新聞最近很多,看到眼熱就去查了下資料,然後扯出來一堆flux、redux、state、state之類的概念,以及大型工程必要性之類的。看官方手冊也是昏昏然。
然而,我還是弄懂了!我準備從demo出發,以同樣的一個最簡單的demo,演示兩種情況下的代碼編寫情況:
假設一個微小的應用,有一個標籤顯示數字,兩個按鈕分別做數字的加一和減一的操作。用戶界面看起來是這樣的:看以下代碼:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<p>{{count}}
<button @click="inc">+</button>
<button @click="dec">-</button>
</p>
</div>
<script>
new Vue({
el:'#app',
data () {
return {
count: 0
}
},
methods: {
inc () {
this.count++
},
dec () {
this.count--
}
}
})
</script>
很簡單,頁面就是一個數字,倆個按鈕,一個+,一個-;整個代碼結構非常清晰,代碼是代碼,數據是數據,這也是我一直以來非常喜歡vue.js的重要原因。代碼就是放在methods數組內的兩個函數inc、dec,被指令@click關聯到button上。而data內返回一個屬性count,此屬性通過{{count}}綁定到標籤p內。點擊+按鈕顯示的數字就會加一下,點擊-號,就相反。
現在來看看,同樣的demo app,使用vuex完成的代碼的樣子,再一次,如下代碼不是代碼片段,是可以貼入到你的html文件內,並且直接使用瀏覽器打開運行的。
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@next"></script>
<div id="app">
<p>{{count}}
<button @click="inc">+</button>
<button @click="dec">-</button>
</p>
</div>
<script>
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
inc: state => state.count++,
dec: state => state.count--
}
})
const app = new Vue({
el: '#app',
computed: {
count () {
return store.state.count
}
},
methods: {
inc () {
store.commit('inc')
},
dec () {
store.commit('dec')
}
}
})
</script>
我們先看到有哪些重要的變化:
-
新的代碼添加了對vuex@next腳本的依賴。這是當然的,因爲你需要使用vuex的技術,當然需要引用它
-
methods數組還是這兩個方法,這和demo1是一樣的;但是方法內的計算邏輯,不再是在函數內進行,而是提交給store對象!這是一個新的對象!
-
count數據也不再是一個data函數返回的對象的屬性;而是通過計算字段來返回,並且在計算字段內的代碼也不是自己算的,而是轉發給store對象。再一次store對象!
就是說,之前在vue實例內做的操作和數據的計算現在都不再自己做了,而是交由對象store來做了。這突然讓我想到就先餐廳現在都不在洗碗了,都交給政府認證的機構來洗了。
說回正題。store對象是Vuex.Store的實例。在store內有分爲state對象和mutations對象,其中的state放置狀態
,mutations則是一個會引發狀態改變的所有方法。正如我們看到的,目前的state對象,其中的狀態就只有一個count。而mutations有兩個成員,它們參數爲state,在函數體內對state內的count成員做加1和減1的操作。
活還是那些活,現在引入了一個store對象,把數據更新的活給攬過去,不再需要vue實例自己計算了,代價是引入了新的概念和層次。那麼好處是什麼(一個土耳其古老的發問)?
vuex解決了組件之間共享同一狀態的麻煩問題。當我們的應用遇到多個組件共享狀態時,會需要:
-
多個組件依賴於同一狀態。傳參的方法對於多層嵌套的組件將會非常繁瑣,並且對於兄弟組件間的狀態傳遞無能爲力。這需要你去學習下,vue編碼中多個組件之間的通訊的做法。
-
來自不同組件的行爲需要變更同一狀態。我們經常會採用父子組件直接引用或者通過事件來變更和同步狀態的多份拷貝。
以上的這些模式非常脆弱,通常會導致無法維護的代碼。來自官網的一句話:Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態
。這裏的關鍵在於集中式存儲管理
。這意味着本來需要共享狀態的更新是需要組件之間通訊的,而現在有了vuex,就組件就都和store通訊了。問題就自然解決了。
這就是爲什麼官網再次會提到Vuex構建大型應用的價值。如果您不打算開發大型單頁應用,使用 Vuex 可能是繁瑣冗餘的。確實是如此——如果您的應用夠簡單,您最好不要使用 Vuex
。