一步一步學會使用vuex

1. vuex是什麼?

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態。

白話:vuex就是幫我們存儲一下多個組件共享的數據,方便我們對其讀取和更改。

2. State

官方解釋:Vuex使用單一狀態樹,用一個對象就包含了全部的應用層次狀態。它便作爲一個唯一的數據源而存在。這也就意味着, 每個應用將僅僅包含一個store實例。

白話:組件中所要共享的數據,我們就會抽取一個store,而state即是我們可以共享的數據。

3. Mutations

更改Vuex的store中的狀態的唯一方法是提交mutation。

Vuex中的mutation非常類似於事件:每個mutation都有一個字符串的事件類型和一個回調函數。

這個回調函數就是我們實際進行狀態更改的地方。並且它會接受state第一個參數。

白話:可以理解爲更改state的唯一途徑就是mutation(同步)

4. Actions

類似於Mutation,不同在於:

  • Action提交的是mutation,而不是直接更改狀態

  • Action可以包含任意一步操作

白話:Actions也可以更改state,但是是通過commit,提交到mutation,不直接更改(異步)

5. Getters

Vuex 允許我們在 store 中定義getter(可以認爲是 store 的計算屬性)。

就像計算屬性 computed 一樣,getter 的返回值會根據它的依賴被緩存起來。

且只有當它的依賴值發生了改變纔會被重新計算。

6. mapState

是一個輔助函數,當一個組件需要獲取多個狀態時候,將這些狀態都聲明爲計算屬性會有些重複和冗餘。

爲了解決這個問題,我們可以使用 mapState 輔助函數幫助我們生成計算屬性。

白話:即幫我們獲取對應的state值

7. mapAction

是一個輔助函數,個人覺得比 dispatch 使用起來方便,主要是創建組件方法分發action,推薦使用。

關鍵實操來啦!

1. 安裝

npm install vuex --save

2. 目錄結構 (此項目使用是vue-admin-template腳手架)

用例鏈接:https://github.com/yzren/Vuex.git

- build
- node-modules
- public
- src
    - api
    - components
    - layout
        -  components
           - appMain.vue
           - child.vue
    - router
    - store
        - modules
        - app.js (我們例子中寫vuex相關信息文件)
        - index.js
    - app.vue
    - main.js
    

3. 簡單實例

  1. 在store文件夾下modules文件夾下添加app.js文件

app.js文件內容:

const state = {
  count: 1
}

const mutations = {
  
  SET_ADD_COUNT: (state) => {
    state.count++
  },
  SET_SUBTRACT_COUNT: (state) => {
    state.count--
  }
}

const actions = {
  // 加
  add({ commit }) {
    commit('SET_ADD_COUNT')
  },
  // 減
  subtract({ commit }) {
    commit('SET_SUBTRACT_COUNT')
  }

}

export default {
  // namespaced: true,
  state,
  mutations,
  actions
}

2.在store文件夾下新建index.js文件,index內容:

import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    app //封裝的存放state下count的方法
  }
})

export default store

3.在main.js中引入store文件

    
import store from './store'
...
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

  1. 具體到組件中使用,我們以layout內組件爲例子

AppMain.vue

<template>
  <section class="app-main">
    <h2>父親組件</h2>
    <p>count計算結果 :
      <strong>{{ count }}</strong>
    </p>
    <el-button size="small" @click="addFn">+</el-button>
    <el-button size="small" @click="subtractFn">-</el-button>

    <div>
      <child />
    </div>
  </section>
</template>

<script>
import { mapState, mapActions } from 'vuex'
import Child from './chind'

export default {
  name: 'AppMain',
  components: {
    Child
  },
  computed: {
    ...mapState({
      count: state => state.app.count
    })
  },
  methods: {
    ...mapActions(['add', 'subtract']),
    addFn() {
      this.add()
    },
    subtractFn() {
      this.subtract()
    }
  }
}
</script>
...

child.vue

<template>
  <section class="app-main">
    <h2>子組件</h2>
    <p>count計算結果 :
      <strong>{{ count }}</strong>
    </p>
    <el-button size="small" @click="addFn">+</el-button>
    <el-button size="small" @click="subtractFn">-</el-button>

  </section>
</template>

<script>
import { mapState, mapActions } from 'vuex'

export default {
  name: 'Child',
  computed: {
    ...mapState({
        //引用count
      count: state => state.app.count
    })
  },
  methods: {
    //分發action,即引入之後,就能通過【this.store中的方法名】,
    //調用store內相對應的方法,
    //此例調用的就是action的add和subtract方法
    ...mapActions(['add', 'subtract']),
    
    addFn() {
      this.add()
    },
    subtractFn() {
      this.subtract()
    }
  }
}
</script>
...

4. 異步實例

主要展示store內文件相關代碼,其調用於以上簡單實力類似

//封裝的axios文件
import http from '@common/http';

//封裝的需要調用後端的接口文件
import { api } from '@common/config';

//共享的數據
const state = {
    listData: {}
};

const actions = {
    // 獲取
    gitTestList({state, commit}, params) {
        // 緩存已請求數據
        if (state.listData[params.id]) {
            return Promise.resolve(state.listData[params.id]);
        }
        return http.get(api.testApi, { params, notLoading: true }).then(res => {
            commit('SET_TEST_LIST', res.data);
            return res.data;
        });
    }
};

const mutations = {
    //設置列表相應信息
    SET_TEST_LIST(state, data) {
        state.listData[data.id] = data;
    }
};

export default {
    state,
    actions,
    mutations
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章