咱們知道vue是組件式開發的,當你的項目愈來愈大後,每一個組件背後的數據也會變得愈來愈難以理順,html
這個時候你就能夠考慮使用vuex了。vue
備註: 官方建議小項目不要使用,引入vuex會帶來新的概念和模式,這對於新手而言理解上自己有難度,並且小項目中vuex發揮的功效確實不怎麼明顯,vuex
反而增長了開發難度,就像後端項目中常說的 過分設計。vue-cli
說了這麼多,下面介入正題(如下講解須要一個空的vue項目,推薦使用 vue-cli 建立,快速搭建一個vue開發環境 ):後端
vuex的做用就是做爲一個數據倉庫(store),把多個組件的背後的數據都放到store中,而後全部組件經過約定的方式去讀取數據和修改數據。網絡
這一句話就歸納完了。沒有想象的那麼複雜。注意,這句話裏面一個關鍵詞叫 約定,下面來講說有那些約定:app
在將約定以前,首先仍是要知道怎麼定義一個倉庫(store),進入項目而後 vue add vuex 。異步
經過這條命令,vue-cli 幫咱們建立了一個 store.js 的文件,並自動在根組件中引入了store,具體變化以下:ide
main.js 文件中自動變化了兩處函數
import Vue from 'vue' import App from './App.vue' import store from './store' #【引入store文件】 Vue.config.productionTip = false new Vue({ store, #【在根組件中引入了store】 render: h => h(App) }).$mount('#app')
如今咱們編輯一下 store.js 文件:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { user: { name: '張三', sex: '男' } }, mutations: { change_name (state,payload) { state.user.name = payload.new_name }, change_sex (state,payload) { state.user.sex = payload.new_sex } }, actions: { change_sex_by_action (context,payload) { setTimeout(() => { context.commit('change_sex',payload) },3000) } } })
理解:
state 是狀態(數據中心)。
mutations 裏面定義的函數用來修改state,mutation只能執行同步操做。
actions 的目的也是更改state,可是他不像mutation同樣能夠直接更改state,而是經過調用mutation來更改state。還有一個不一樣點是,action能夠執行異步操做,好比網絡請求。
getters 返回組裝DIY後的數據,好比state有個sex=「女」,經過getter在後面加一個 生 ,返回 女生,可是我以爲把組件中 computed 乾的事情放到store層不是一個好主意,因此本例中不涉及。
用法:
mutation的一個參數是 state,第二個參數是從 組件傳過來的參數對象,
action的第一個參數是一個與 store 實例具備相同方法和屬性的 context 對象,這句話有點難以理解,你就把context想象成一個新的store對象,
第二個參數仍是 組件傳過來的參數對象
在編輯一下 App.vue 文件
<template> <div id="app"> <button @click="change_name">change name by mutation</button> <p>current name({{ user.name }})</p> <button @click="change_sex">change sex by action</button> <p>current sex({{ user.sex }})</p> </div> </template> <script> export default { data () { return { // user: this.$store.state.user } }, computed: { user() { return this.$store.state.user } }, methods: { change_name() { this.$store.commit({ type: 'change_name', new_name: '李四' }) }, change_sex() { this.$store.dispatch({ type: 'change_sex_by_action', new_sex: '女' }) } } } </script>
經過store獲取數據都要放到computed裏面,雖然在其餘地方也能夠直接獲取,可是沒法監聽數據變更(就像上面註釋的同樣)。
change_name是經過mutation方式同步更改store中的數據,change_sex採用了action方式異步更改store中的數據。
若是在computed中須要獲取的數據不少,可使用 官方提供的 mapState,具體用法查看官方 文檔 。
我本身的理解:
不要濫用store,不要把全部的數據都放到store中,在組件化開發思想下,我認爲組件和組件之間本就應該獨立封裝,
若是一個數據只有在某個組件中使用,而不須要被其餘組件共享,那麼最好不要放到其中,store只存儲有必要的數據,不要讓他變得太臃腫,不然麻煩早晚會來。
官方文檔中說明,若是store太大能夠採用模塊方式分割,但貌似不太優雅,
最後我仍是推薦store只放必要的東西,不要讓他變得太肥胖。