zoukankan      html  css  js  c++  java
  • Vue-认识状态管理vuex

      vuex是一个专门为vue.js设计的状态管理模式,并且也可以使用devtools进行调试,可以多个组件共享状态。简单来说,就是共享的状态用state来存放,用mutations来操作state,但是需要用store.commit来主动式的操作mutations。

    vuex

      用一个简单的demo来认识vuex。

    1520926961(1)

      注意在使用vuex之前要先安装依赖(前提是已经用Vue脚手架工具构建好项目)

    cnpm install vuex –save

      在入口文件main.js里需要引入vuex、注册vuex、实例化store、把store放在全局的实例化对象里。

    import Vue from 'vue'
    import App from './App'
    //1.引入vuex
    import Vuex from 'vuex'
    import Apple from './components/Apple'
    import Banana from './components/Banana'
    Vue.config.productionTip = false
    //2.注册
    Vue.use(Vuex);
    //3.实例化store
    let store=new Vuex.Store({
        state:{
            totalPrice:0
        },
        mutations:{
            increment(state,price){
                state.totalPrice+=price
            },
            decrement(state,price){
                state.totalPrice-=price
            }
        },
        actions:{
            increase (context,price){
                context.commit('increment',price)
            },
            decrease (context,price){
                context.commit('decrement',price)
            }
        },
        getters:{
            discount(state){
                return state.totalPrice *0.8;
            }
        }
    })
    new Vue({
      el: '#app',
      //4.把store放在全局的实例化对象里,可以在全局的所有地方用
      store,
      components: { App},
      template: '<App/>'
    })

      实例化store时,用到了state,mutations,actions,getters参数,下面来单独介绍 它们:

    state
      vuex使用单一状态树,那么就可以用一个对象来包含全部的应用层级状态。所以state就作为数据源。

    mutations
      更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。不能直接调用一个 mutation handler,这个选项更像是事件注册:“当触发一个type为 increment的 mutation 时,调用此handler。”要唤醒一个 mutation handler,需要调用 store.commit 方法触发相应的 type 。可以向store.commit传入额外的参数这个参数就叫做mutations的载荷。 在更多的情况下,载荷应该是一个对象。这样可以包含更多的字段。

      mutations必须是同步函数。那我们如何来异步的更新state呢?答案是actions。

    actions
      actions类似于 mutations 不同的是:
      actions 提交的是mutations,而不是直接变更状态,这也就形成了 actions —— mutations —— state 的过程。
      actions 可以包含任意异步操作。
      action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用context.commit提交一个 mutation,或者通过context.state和context.getters来获取 state 和 getters。但是如何触发呢?答案: store.dispatch
    getters

      有时候我们需要从 store 中的 state 中派生出一些状态,getter 会暴露为 store.getters 对象在组件中使用。

    modules

            除了上边用到的4个参数,store还有另一个参数:modules。
      vuex允许把store进行一个功能拆分,分割成不同的模块(module)。每个模块都拥有自己的store,mutations,action,getters。

    App.vue

    <template>
      <div id="app">
        <Apple></Apple>
        <Banana></Banana>
        <p> 总价{{totalPrice}}</p>
        <p> 折后价:{{discountPrice}}</p>
      </div>
    </template>
    <script>
    import HelloWorld from './components/HelloWorld'
    import Apple from './components/Apple'
    import Banana from './components/Banana'
    export default {
      name: 'App',
      components: {
        HelloWorld,
        Apple,
        Banana
      },
      computed:{
        totalPrice(){
        //由于vuex的状态存储是响应式的,所以从store实例中读取状态的最简单方法就是使用计算属性来返回某个状态:
          return this.$store.state.totalPrice
        },
        discountPrice(){
        //getter 会暴露为 store.getters 对象
          return this.$store.getters.discount    
          }
      }
    }
    </script>

      由于vuex的状态存储是响应式的,所以从store实例中读取状态的最简单方法就是使用计算属性来返回某个状态:store.state.totalPrice

      getters 会暴露为 store.getters 对象:用store.getters.discount可以获取到getter里discount对state计算后的结果

      当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性。

    
    
    import { mapState } from 'vuex'
    computed: {
        ...mapState(['totalPrice'])
            
        ...
     
      }

    Banana.vue

    <template>
    <div>
            <p>{{msg}} 单价{{price}}</p>    
            <button @click="addOne">add one</button>
            <button @click="minusOne">minus one</button>
    </div>
    </template>
    <script>
    export default{
        data(){
            return{
                msg:'banana',
                price:15
            }
        },
        methods:{
            addOne(){
                //直接commit一个mutation
                this.$store.commit('increment',this.price)
            },
            minusOne(){
                this.$store.commit('decrement',this.price)
            }
        }
    }
    </script>

    addOne()函数里调用 store.commit 方法触发 type为"increment"的mutation;minusOne()函数里调用 store.commit 方法触发 type为"decrement"的mutation。

      可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用。

    methods:{
          addOne(){
              this.increment(this.price)
          },
          minusOne(){
              this.decrement(this.price)
          },
          ...mapMutations(['increment', 'decrement'])
    }

    Apple.vue

    <template>
    <div>
        <p> {{msg}}单价:{{price}} </p>    
        <button @click="addOne">add one</button>
        <button @click="minusOne">minus one</button>
    </div>
    </template>
    <script>
    export default{
        data(){
            return{
                msg:'apple',
                price:5
            }
        },
        methods:{
            addOne(){
                //dispatch一个action,以action作为一个中介再去commit一个mutation
                this.$store.dispatch('increase',this.price)
            },
            minusOne(){
                this.$store.dispatch('decrease',this.price)
            }
        }
    }
    </script>

      addOne()函数里调用 store.dispatch方法触发名为"increase"的action,对应的,在increase这个action里再去调用 context.commit方法触发 type为"increment"的mutation;minusOne()函数里调用 store.dispatch方法触发名为"decrease"的action,对应的,在decrease这个action里再去调用context.commit方法触发 type为"decrement"的mutation。action相当于中介。

    mutations和actions的区别与联系:

    action只能调用mutation不能直接更改state,执行 action 来分发 (dispatch) 事件通知 store 去改变。
    action里可以进行一些异步的操作,再去触发mutation 。
    mutation里必须是同步的触发操作state。

  • 相关阅读:
    Windows_10 系统封装
    leetcode-75 颜色分类
    leetcode-922 按奇偶排序数组 II
    leetcode-905 按奇偶数排序
    UVA-10827 环面上的最大子矩阵和
    leetcode918 环形最大子数组
    leetcode-85 最大矩形
    leetcode-84 柱状图中的最大矩形
    leetcode-221 最大正方形
    leetcode-713 乘积小于k的数组
  • 原文地址:https://www.cnblogs.com/superlizhao/p/8557474.html
Copyright © 2011-2022 走看看