Vue 學習記錄四

zs4336發表於2019-12-02

Vuex

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化

安裝 Vuex

1、npm install vuex --save

2、建立store物件,src/store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)

    const state = {};
    const getters = {};
    const mutations = {};
    const actions = {};

    const store = new Vuex.Store({
        state,
        getters,
        mutations,
        actions,
    });

    export default store;

3、在入口檔案src/main.js引入並注入store

   import Vue from 'vue'
   import store from './store'

   new Vue({
        el:'#app',
        store,
   })
Vuex選項

1、state

  • 定義state
    const state = {
        user:null,
    }
  • 在元件中獲取state,由於 Vuex 的狀態儲存是響應式的,從 store 例項中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態
export default {
    computed:{
        user:this.$store.state.user,
    }
}

mapState 輔助函式幫助我們生成計算屬性

import {mapState} from 'vuex'
export default {
    computed:{
        localComputed(){

        },
         //此處是陣列的形式,當然也可以使用物件的方式
        ...mapState([          
            'user'
        ]),
    }
}

2、getters

  • 定義**getters

Vuex 允許我們在 store 中定義“getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被快取起來,且只有當它的依賴值發生了改變才會被重新計算
getter 方法接受以下引數:state,getters(可選)

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
        return state.todos.filter(todo => todo.done)
    },
    getTodoById: (state) => (id) => { //返回一個函式,實現給 getter 傳參
        return state.todos.find(todo => todo.id === id)
    },
    doneTodosCount: (state, getters) => {
        return getters.doneTodos.length
    }
  }
})
  • 在元件中獲取getters
export default {
    computed: {
      doneTodosCount () {
        return this.$store.getters.doneTodosCount
      }
    }
}

同樣的,可以使用mapGetters輔助函式

import mapGetters from 'vuex'
export default {
    computed:{
        localComputed(){

        },
        //此處是陣列的形式,當然也可以使用物件的方式
        ...mapGetters([         
            'doneTodosCount'
        ]),
    }
}

3、mutations

更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation
一條重要的原則就是要記住 mutation 必須是同步函式
在 store 上註冊 mutation,處理函式總是接受 state 作為第一個引數(如果定義在模組中,則為模組的區域性狀態),payload 作為第二個引數(可選),可以是一個變數,或者是一個物件

  • 定義mutations
const mutations = {
    increment (state, n) {
        state.count += n
    },
}
  • 在元件中提交 Mutation

你可以在元件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 輔助函式將元件中的 methods 對映為 store.commit 呼叫(需要在根節點注入 store)

import { mapMutations } from 'vuex'
export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 將 `this.increment()` 對映為 `this.$store.commit('increment')`

      // `mapMutations` 也支援載荷:
      'incrementBy' // 將 `this.incrementBy(amount)` 對映為 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 將 `this.add()` 對映為 `this.$store.commit('increment')`
    })
  }
}

4、actions

Action 提交的是 mutation,而不是直接變更狀態
Action 可以包含任意非同步操作
在 store 上註冊 action。處理函式總是接受 context 作為第一個引數,payload 作為第二個引數(可選)

context 物件包含以下屬性:

{
  state,      // 等同於 `store.state`,若在模組中則為區域性狀態
  rootState,  // 等同於 `store.state`,只存在於模組中
  commit,     // 等同於 `store.commit`
  dispatch,   // 等同於 `store.dispatch`
  getters,    // 等同於 `store.getters`
  rootGetters // 等同於 `store.getters`,只存在於模組中
}
  • 定義actions
const actions = {
    increment({commit},amount){
        commit('increment',amount)
    },
}
  • 在元件內分發actions
import {mapActions} from 'vuex'
export default {
    methods:{
        ...mapActions([
          'increment', // 將 `this.increment()` 對映為 `this.$store.dispatch('increment')`

          // `mapActions` 也支援載荷:
          'incrementBy' // 將 `this.incrementBy(amount)` 對映為 `this.$store.dispatch('incrementBy', amount)`
        ]),
        ...mapActions({
          add: 'increment' // 將 `this.add()` 對映為 `this.$store.dispatch('increment')`
        })
    }
}

另外:
1、應用層級的狀態應該集中到單個 store 物件中
2、提交 mutation 是更改狀態的唯一方法,並且這個過程是同步的
3、非同步邏輯都應該封裝到 action 裡面
4、如果 store 檔案太大,只需將 action、mutation 和 getter 分割到單獨的檔案

本作品採用《CC 協議》,轉載必須註明作者和本文連結
今年不學習,明天慘唧唧。

相關文章