天天看點

十三.Vue.js 狀态管理Vuex

Vuex是一個狀态管理的插件,管理過程包含了state(資料源)、view(state綁定到視圖)、actions(view改變同步改變資料源)三個狀态,頁面重新整理的時候vuex裡的資料會重新初始化,導緻資料丢失,頁面會重新加載vue執行個體,vuex裡面的資料就會被重新指派,解決辦法:将vuex中的資料直接儲存到浏覽器緩存中(sessionStorage、localStorage、cookie),界面重新整理前把資料存sessionStorage或再次請求遠端資料,使之動态更新vuex資料,App.vue中添加以下代碼

// App.vue 
//===========================下面是解決重新整理頁面丢失vuex資料
  created() {
    //在頁面加載時讀取sessionStorage裡的狀态資訊
    if (sessionStorage.getItem('store')) {
      this.$store.replaceState(Object.assign({}, this.$store.state,         JSON.parse(sessionStorage.getItem('store'))));
    }

    //在頁面重新整理時将vuex裡的資訊儲存到sessionStorage裡
    window.addEventListener('beforeunload', () => {
      sessionStorage.setItem('store', JSON.stringify(this.$store.state));
    });
  }
           

應用場景:(購物車的資料共享,登入注冊)

  • 多個視圖依賴于同一狀态
  • 來自不同視圖的行為需要變更同一狀态
  • 可以思考到涉及

    sessionStorage

    cookies

    之類的裡面或涉及到非父子關系的元件,例如兄弟關系、祖孫關系,甚至更遠的關系元件之間的聯系

Vuex使用:

  • 安裝:cnpm install vuex --save
  • 引入:import Vuex from 'vuex'           Vue.use(Vuex)
  • 建立:  new Vuex.Store({})
  • 使用:挂載到new Vue()上,new Vue({store })

new Vuex.Store 配置

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  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)
        }
    },
    mutations: {
        todosAdd(state,obj) {
          // 變更狀态
          state.todos.push(obj)
        }
    },
    actions: {
        todosAddM(context,obj){ // context屬性:state、rootState、commit、dispatch、getters、rootGetters
            context.commit('todosAdd',obj)
        }
    },
    modules: {
        a: moduleA, // moduleA配置和根子產品的選項一樣,store.state.a // -> moduleA 的狀态
        b: moduleB
    }
})

export default store;
           
  • store、modules:存儲資料 
  • getters:計算屬性,可以了解為跟computed一樣,通路 store.getters.doneTodos
  • mutations:通過裡面方法改變state裡面的資料,通過 store.commit('todosAdd',{id: 3,text:'''}) 調用,同步處理
  • actions:不能直接修改state,通過觸發mutations來修改,可操作異步、多個同步處理,通過 store.dispatch('todosAddM',{id: 3,text:'''})調用

Store讀取

  • 可以直接 

    created

     時從中讀取 

    $store.state

     值,通過 

    commit()

     來修改值
  • mapState、mapGetters、mapActions、mapMutations:當一個元件需要擷取多個狀态時使用,import { mapState } from 'vuex'
    <template>
      <div id="example">
        {{count}}
      </div>
    </template>
    <script>
    import { mapState } from 'vuex'
    export default {
      data () {
        return {
          str: '國籍',
          dataCount: this.$store.state.count
        }
      },
      computed: mapState({
        count: 'count', // 第一種寫法
        from: function (state) { // 用普通函數this指向vue執行個體,要注意
          return this.str + ':' + state.from
        }
      }),
      methods: {
        increment () {
          this.$store.commit('increment')
        },
        decrement () {
          this.$store.commit('decrement')
        }
      },
      created () {
        // 寫個定時器,發現computed依舊保持了隻要内部有相關屬性發生改變不管是目前執行個體data中的改變,還是vuex中的值改變都會觸發dom和值更新
        setTimeout(() => {
          this.str = '國家'
        }, 1000)
      }
    }
    </script>