vuex瞭解一下?

Vuex

一個專爲 Vue.js,應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vue

vuex流程圖

組件觸發事件dispatch;
actions調用後端接口;
調用commit,來觸發mutations;
改變state的狀態;
最後渲染組件;

使用vuex

安裝模塊
npm install vuex --saveios

// store.js
import Vue from 'vue'  
import Vuex from 'vuex'  

Vue.use(Vuex)
let store = new Vuex.Store({
    state:{
        count:100
    },
    getters:{
        // 可傳遞 getter 做爲第二個參數
        filter(state){
            return state.count >= 120 ? 120 : state.count;
        }
    },
    mutaitons:{
        add(state,n,m){
            state.count= state.count + n + m;
        },
        de(state,payload){
            state.count-=payload.n;
        }
    },
    actions:{
        add(context){
            setTimeout( ()=>{
                context.commit('add', {n:5} )
            }, 1000)
        }
    }
})

export default store
複製代碼

讀取state的屬性

this.$store.state.count;  
複製代碼

讀取getters的屬性

this.$store.getters.filter;  
複製代碼

commit同步改變state

// 多個參數
this.$store.commit('add',5,3);   
// 對象參數
this.$store.commit('de',{
    n:5
});  
// 直接使用包含 type 屬性的對象  
this.$store.commit({
    type:'de',
    de:5
});   
複製代碼

dispatch異步改變state

this.$store.dispatch('add')  
複製代碼

vuex輔助函數

mapState
mapGetters
mapMutations
mapActions
createNamespacedHelpers
以上方法都接收一個參數,返回對象;vuex

import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'
export default {
  computed: {
    ...mapGetters({
      num: 'filterCount'
    }),
    ...mapState(['count']),
  },
  methods: {
    ...mapActions({
      addHandle: 'addAction'
    }),
    ...mapMutations({
      deHandle:'deIncrement'
    })
  }
}

/*
多種寫法
computed: {
    ...mapGetters({
        num: state => state.count,
        num: 'count',
        num(state) {
            return state.count+100
        },
        count: 'count'
    })
},
computed: mapGetters(['count']),
*/
複製代碼

如需傳參能夠直接寫在綁定事件上:npm

<input type="button" value="-" @click="deHandle({de:5})" />
複製代碼

vuex模塊

// 定義模塊
let selectModule = {
  state:{
    title:'hello123',
    list: []
  },
  getters:{
        // 接受 getter 做爲第二個參數
        // 接受 rootStare 根state 做爲第三個參數
        filter(state){
            return state.count >= 120 ? 120 : state.count;
        }
    },
  mutations:{
    changeTitle(state, payload){
      state.title = payload.title
    },
    changeList(state, list){
      state.list = list;
    }
  },
  actions:{
    getListAction({state, commit, rootState}){
      // 發送請求
      axios.get('http://easy-mock.com/mock/594f5d4b9adc231f3569be76/list/list')
        .then((data)=>{
          commit("changeList", data.data);  // 拿到數據後,提交mutations,改變狀態
        })
        .catch((error)=>{
          conso.log(error)
        })
    }
  }
};

let store = new Vuex.Store({
    modules:{
      selectModule
    }
})
複製代碼

state裏的屬性須要以下訪問,其餘的不變;axios

this.$store.state.selectModule.title  
this.$store.commit('changeTitle',5,3);  
this.$store.dispatch('getListAction',5,3);  
複製代碼

插件

Vuex 的 store 接受 plugins 選項,這個選項暴露出每次 mutation 的鉤子。Vuex 插件就是一個函數,它接收 store 做爲惟一參數(洗澡睡覺 明天補充 1562083121584 這是啥)後端

// 定義插件
const myPlugin = store => {
  // 當 store 初始化後調用
  store.subscribe((mutation, state) => {
    // 每次 mutation 以後調用
    // mutation 的格式爲 { type, payload }
  })
}
// 使用
const store = new Vuex.Store({
  // ...
  plugins: [myPlugin]
})
複製代碼

嚴格模式

在嚴格模式下,不管什麼時候發生了狀態變動且不是由 mutation 函數引發的,將會拋出錯誤。這能保證全部的狀態變動都能被調試工具跟蹤到。bash

const store = new Vuex.Store({
  // ...
  strict: true
})
複製代碼

devtools

爲某個特定的 Vuex 實例打開或關閉 devtools。異步

{
  devtools: false
}
複製代碼

module命名空間

默認狀況下,模塊內部的 action、mutation 和 getter是註冊在全局命名空間的——這樣使得多個模塊可以對同一 mutation 或 action 做出響應。函數

經過添加 namespaced: true 的方式使其成爲帶命名空間的模塊。當模塊被註冊後,它的全部 getter、action 及 mutation 都會自動根據模塊註冊的路徑調整命名。工具

帶命名空間的模塊內訪問全局內容

  • 但願使用全局 state 和 getter,rootState 和 rootGetter 會做爲第三和第四參數傳入 getter,dispatch也會經過 context 對象的屬性傳入 action。
  • 若須要在全局命名空間內分發 action 或提交 mutation,將 { root: true } 做爲第三參數傳給 dispatch 或 commit 便可。
dispatch('actionName') // -> 'module/actionName'
dispatch('actionName', null, { root: true }) // -> 'rootStoreActionName'
commit('mutationName') // -> 'module/mutationName'
commit('mutationName', null, { root: true }) // -> 'rootStoreMutationName'
複製代碼

在帶命名空間的模塊註冊全局action

須要在帶命名空間的模塊註冊全局 action,你可添加 root: true,並將這個 action 的定義放在函數 handler 中

modules: {
    foo: {
      namespaced: true,
      actions: {
        someAction: {
          root: true,
          handler (namespacedContext, payload) {}
        }
      }
    }
}
複製代碼

帶命名空間的綁定函數

computed: {
  ...mapState({
    a: state => state.some.nested.module.a,
    b: state => state.some.nested.module.b
  })
},
methods: {
  ...mapActions([
    'some/nested/module/foo', // -> this['some/nested/module/foo']()
    'some/nested/module/bar' // -> this['some/nested/module/bar']()
  ])
}
// 將模塊的空間名稱字符串做爲第一個參數傳遞給輔助函數,這樣全部綁定都會自動將該模塊做爲上下文。
computed: {
  ...mapState('some/nested/module', {
    a: state => state.a,
    b: state => state.b
  })
},
methods: {
  ...mapActions('some/nested/module', [
    'foo', // -> this.foo()
    'bar' // -> this.bar()
  ])
}
//經過使用 createNamespacedHelpers 建立基於某個命名空間輔助函數。它返回一個對象,對象裏有新的綁定在給定命名空間值上的組件綁定輔助函數:
import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')

export default {
  computed: {
    // 在 `some/nested/module` 中查找
    ...mapState({
      a: state => state.a,
      b: state => state.b
    })
  },
  methods: {
    // 在 `some/nested/module` 中查找
    ...mapActions([
      'foo',
      'bar'
    ])
  }
}
複製代碼

模塊動態註冊

  • 在 store 建立以後,你可使用 store.registerModule 方法註冊模塊
  • store.unregisterModule(moduleName) 來動態卸載模塊(建立 store 時聲明的模塊不能卸載)

保留 state

在註冊一個新 module時,你頗有可能想保留過去的state,例如從一個服務端渲染的應保留 state。
你能夠經過 preserveState 選項將其歸檔:store.registerModule('a', module, { preserveState: true })。
當設置 preserveState: true 時,該模塊會被註冊,action、mutation 和 getter 會被添加到 store 中,可是 state 不會。這裏假設 store 的 state 已經包含了這個 module 的 state 而且你不但願將其覆寫。

其餘筆記

父子組件之間改變狀態

1.x版本上的:propertyName.sync傳參到子組件,當子組件的屬性值改變時,父組件也會變
2.0版本廢除
2.3版本以後又恢復了sync;
因此使用:propertyName.sync,綁定屬性時的屬性值sync便可;

父組件:

<select-input :is-show.sync="listShow"></select-input>
<list v-show="listShow"></list>
複製代碼

子組件:

<button @click="showListHandle"><button/>
<script>
export default {
  props:['isShow'],
  computed:{
    initShow(){
        return this.isShow
    }
  },
  methods: {
    showListHandle(){
        //觸發更新,名字是is-show,值爲initshow取反;
        this.$emit("update:isShow", !this.initShow)
    }
  }
}
</script>
複製代碼

兄弟組件之間改變狀態

須要使用父組件做爲通道,父組件傳入子組件自定義的事件,在子組件觸發某個事件時,使用$emit來觸發父組件傳入的自定義事件,來改變兄弟組件的狀態;

需求:
父組件的title值傳入了select-input組件做爲input的值;
list組件的列表項點擊時須要改變title值;
以改變兄弟組件select-input的input值;

實現:
父組件傳入list組件自定義事件changeTitle;
在list組件的列表項點擊時,觸發getTitleHandle事件處理函數,而後再來觸發自定義事件changeTitle來改變父組件的title值;

父組件

<select-input :is-show.sync="listShow" :title="title"></select-input>
<list v-show="listShow" @changeTitle="titleHandle"></list>
<script>
exprot default{
    data(){
        return {
            listShow: flase;
            title:’’
        }
    },
    methods:{
        titleHeadle(title){
            this.title=title;
        }
    }
}
</script>
複製代碼

select-input組件

<input @click="showListHandle" :value="this.props.title"/>
複製代碼

list組件:

<template>
<ul class="list">
    <li v-for="item in data" @click="getTitleHandle(item.title)">{{item.title}}</li>
</ul>
</template>
<script>
exprot default{
    data(){},
    methods:{
        getTitleHandle(title){
            this.$emit('changeTitle',title)
        }
    }
}
</script>
複製代碼
相關文章
相關標籤/搜索