zoukankan      html  css  js  c++  java
  • Vuex学习总结

    4.Vuex核心概念

    4.4 Actions

    Actions不直接改变Vuex实例中的状态,而是提交mutation

    // store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        increment(state) {
          state.count++
        },
      },
      actions: {
        increment(context) {
          context.commit('increment')
        },
      },
    })
    
    <template>
        <div>
            <button @click="increment">加一</button> {{count}}
        </div>
    </template>
    
    <script>
        import {mapState} from 'vuex'
    
        export default {
            name: "Counter2",
            computed: {
                ...mapState(['count']),
            },
            methods: {
                increment() {
                    this.$store.dispatch('increment')
                },
            }
        }
    </script>
    

    Action处理程序会收到一个上下文对象,该对象与Vuex实例有相同的方法和属性。
    因此,您可以调用context.commitcontext.statecontext.getterscontext.dispatch

    使用解构来简化代码。

    // store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        increment(state) {
          state.count++
        },
      },
      actions: {
        increment({commit}) {
          commit('increment')
        },
      },
    })
    

    注意到这里在组件中使用this.$store.dispatch('increment')来触发Action,在Action中提交mutation
    为什么不在组件中直接提交mutation?在组件中可以直接提交mutation,但mutation必须是同步的,如果要执行异步操作,就要在Action里面执行。

    // store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        increment(state) {
          state.count++
        },
      },
      actions: {
        increment({commit}) {
          commit('increment')
        },
        incrementAsync({ commit }) {
          setTimeout(() => {
            commit('increment')
          }, 1000)
        },
      },
    })
    
    <template>
        <div>
            <button @click="increment">加一</button> {{count}}
            <button @click="incrementAsync">异步加一</button> {{count}}
        </div>
    </template>
    
    <script>
        import {mapState} from 'vuex'
    
        export default {
            name: "Counter2",
            computed: {
                ...mapState(['count']),
            },
            methods: {
                increment() {
                    this.$store.dispatch('increment')
                },
                incrementAsync() {
                    this.$store.dispatch('incrementAsync')
                },
            }
        }
    </script>
    

    在组件中调用dispatch时还可以这样写:

    // store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        incrementBy(state, payload) {
            state.count += payload.amount
        },
      },
      actions: {
        incrementAsync({ commit }, payload) {
          setTimeout(() => {
            commit('incrementBy', payload)
          }, 1000)
        },
    })
    
    <template>
        <div>
            <button @click="incrementAsync">异步加十</button> {{count}}
        </div>
    </template>
    
    <script>
        import {mapState} from 'vuex'
    
        export default {
            name: "Counter2",
            computed: {
                ...mapState(['count']),
            },
            methods: {
                incrementAsync() {
                    this.$store.dispatch('incrementAsync', {amount: 10})
                    // this.$store.dispatch({type: 'incrementAsync', amount: 10})
                },
            }
        }
    </script>
    

    使用mapActions

    // store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        increment(state) {
          state.count++
        },
      },
      actions: {
        increment({commit}) {
          commit('increment')
        },
      },
    })
    
    <template>
        <div>
            <button @click="increment">加一</button> {{count}}
            <button @click="add">加一</button> {{count}}
        </div>
    </template>
    
    <script>
        import {mapState, mapActions} from 'vuex'
    
        export default {
            name: "Counter2",
            computed: {
                ...mapState(['count']),
            },
            methods: {
                ...mapActions(['increment']),
                ...mapActions({
                    add: 'increment'
                })
            }
        }
    </script>
    

    处理异步流。

    // store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        increment(state) {
          state.count++
        },
      },
      actions: {
        actionA ({commit}) {
          return new Promise((resolve) => {
            setTimeout(() => {
              commit('increment')
              resolve()
            }, 1000)
          })
        },
      },
    })
    
    <template>
        <div>
            <button @click="increment">加一</button> {{count}}
        </div>
    </template>
    
    <script>
        import {
            mapState,
        } from 'vuex'
    
        export default {
            name: "Counter2",
            computed: {
                ...mapState(['count']),
            },
            methods: {
                increment() {
                    this.$store.dispatch('actionA').then(() => {
                        console.log('执行成功!')
                    })
                },
            }
        }
    </script>
    

    在一个Action中触发另一个Action。

    // store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        increment(state) {
          state.count++
        },
        incrementBy(state, payload) {
            state.count += payload.amount
        },
      },
      actions: {
        actionA ({commit}) {
          return new Promise((resolve) => {
            setTimeout(() => {
              commit('increment')
              resolve()
            }, 1000)
          })
        },
        actionB({dispatch, commit}) {
          return dispatch('actionA').then(() => {
            commit('incrementBy', {amount: 10})
          })
        },
      },
    })
    
    <template>
        <div>
            <button @click="increment">加一</button> {{count}}
        </div>
    </template>
    
    <script>
        import {
            mapState,
        } from 'vuex'
    
        export default {
            name: "Counter2",
            computed: {
                ...mapState(['count']),
            },
            methods: {
                increment() {
                    this.$store.dispatch('actionB').then(() => {
                        console.log('执行成功!')
                    })
                },
            }
        }
    </script>
    

    在Action中使用asyncawait

    // store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    import axios from 'axios'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        career: {
          id: '',
          name: '',
        },
        certificateType: {
          id: '',
          name: '',
        },
      },
      mutations: {
        getCareerById(state, payload) {
          state.career = payload
        },
        getCertificateType(state, payload) {
          state.certificateType = payload
        },
      },
      actions: {
        async actionC({commit}, payload) {
          let career = await axios.get(`http://192.168.3.117:8001/insurance/career/getCareerById/${payload.id}`);
          commit('getCareerById', career.data.data.career)
        },
        async actionD({dispatch, commit}, payload) {
          await dispatch('actionC', {id: 1})
          let certificateType = await axios.get(`http://192.168.3.117:8001/insurance/certificate-type/getCertificateTypeById/${payload.id}`);
          commit('getCertificateType', certificateType.data.data.certificateType)
        },
      },
    })
    
    <template>
        <div>
            <button @click="getData">加载数据</button>
            <br/>
            职业:{{career.name}}
            <br/>
            证件类型:{{certificateType.name}}
    
            <!--<br/>-->
            <!--职业:{{this.$store.state.career.name}}-->
            <!--<br/>-->
            <!--证件类型:{{this.$store.state.certificateType.name}}-->
        </div>
    </template>
    
    <script>
        import {
            mapState,
        } from 'vuex'
    
        export default {
            name: "Asynchronous",
            computed: {
                ...mapState(['career', 'certificateType']),
            },
            methods: {
                getData() {
                    this.$store.dispatch('actionD', {id: 1}).then(() => {
                        console.log('加载成功!')
                    })
                },
            },
        }
    </script>
    

    参考:

  • 相关阅读:
    吴裕雄--天生自然 R语言开发学习:广义线性模型(续一)
    吴裕雄--天生自然 R语言开发学习:广义线性模型
    吴裕雄--天生自然 R语言开发学习:重抽样与自助法(续一)
    吴裕雄--天生自然 R语言开发学习:重抽样与自助法
    吴裕雄--天生自然 R语言开发学习:中级绘图(续二)
    吴裕雄--天生自然 R语言开发学习:中级绘图(续一)
    吴裕雄--天生自然 R语言开发学习:中级绘图
    吴裕雄--天生自然 R语言开发学习:功效分析(续一)
    吴裕雄--天生自然 R语言开发学习:功效分析
    吴裕雄--天生自然 R语言开发学习:方差分析(续二)
  • 原文地址:https://www.cnblogs.com/gzhjj/p/14349316.html
Copyright © 2011-2022 走看看