【Vue.js学习笔记】16:使用Vuex做组件状态管理的demo

时间:2019-01-23
本文章向大家介绍【Vue.js学习笔记】16:使用Vuex做组件状态管理的demo,主要包括【Vue.js学习笔记】16:使用Vuex做组件状态管理的demo使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Vuex集中管理组件的状态,提供store来集中存储所有组件用的数据,代替传统的繁琐的组件通信方式。

store.js

在这里导入Vuex并设置store的各项功能。

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export const store = new Vuex.Store({
    strict:true,//在严格模式下,不允许非mutation操作vuex中store管理的数据
    state:{//state中存储数据
        products:[
            {name:"马云",price:200},
            {name:"马化腾",price:140},
            {name:"马冬梅",price:20},
            {name:"马蓉",price:10},
          ]
    },
    getters:{//getters中获取数据(只读不写)
        saleProducts:(state)=>{
            //获取打折后的商品价格,这里用map遍历其中的每个prodcut返回price折半的结果
            var saleProducts = state.products.map(
              product => {
                return {
                  name :"*"+product.name,
                  price: product.price/2
                }
            });
            //将打折的商品数组返回
            return saleProducts;
        }
    },
    mutations:{//mutations中注册改变state的事件(只写不读)
        reducePrice:(state,payload)=>{
            //如果在这里用setTimeout,那么就是在调用reducePrice之后,3秒后再执行商品降价的操作
            // setTimeout(function(){
                //商品降价:遍历store中的每个商品使其price减少
                state.products.forEach(product => {
                    product.price -= payload;
                });
            // },3000);
        }
    },
    actions:{//actions用于提交mutation,可以实现异步操作
        reducePrice:(context,payload)=>{
            //在这种方式下,数据改变和mutation的方法执行是同时的
            setTimeout(function(){
                context.commit("reducePrice",payload);
            },3000);
        }   
    }
});

根组件

这里在其中包含了两个子组件。

<template>
  <div id="app">
    <!-- 传统的组件通信方式 -->
    <!-- <product-list-one v-bind:products="products"></product-list-one> -->
    <!-- <product-list-two v-bind:products="products"></product-list-two> -->
    
    <!-- 现在使用vuex管理数据和通信,不再需要上面的方式 -->
    <product-list-one></product-list-one>
    <product-list-two></product-list-two>
  </div>
</template>

<script>
import productListOne from './conponents/productListOne';
import productListTwo from './conponents/productListTwo';

export default {
  name: 'app',
  data () {
    return {
     
    }
  },
  components:{
    'product-list-one':productListOne,
    'product-list-two':productListTwo
  }
}
</script>

<style>

</style>

组件1

注意这里对mapGetters和mapActions使用了ES6的语法,目前要安装babel。

<template>
  <div id="product-list-one">
      <p>降价后的商品</p>
      <ul>
          <li v-for="product in saleProducts" v-bind:key="product.value">
            <span class="name">{{product.name}}</span>
            <span class="name">${{product.price}}</span>
          </li>
      </ul>
      <button @click="reducePrice(4)">商品降价</button>
  </div>
</template>

<script>
import {mapGetters} from 'vuex';
import {mapActions} from 'vuex';

export default {
  data () {
    return {
    }
  },
  computed:{
    products(){
      //获取vuex的store中的商品数据
      return this.$store.state.products;
    },
    /*
    saleProducts(){
      //获取打折后的商品信息
      return this.$store.getters.saleProducts;
    }
    */
    ...mapGetters([//在这个传入的数组里写store中getters里的方法
      "saleProducts",
    ])
  },
  methods:{
    /*
    reducePrice(amount){
      //点击商品降价时触发的函数,在这里调用mutation进行降价
      // this.$store.commit("reducePrice");

      //改成调用action,再由action去调用mutation.这里可以进行传参
      this.$store.dispatch("reducePrice",amount);
    }
    */
    ...mapActions([
      "reducePrice",
    ])
  }
}
</script>

<style>

</style>

组件2

<template>
  <div id="product-list-two">
      <p>降价前的商品</p>
      <ul>
          <li v-for="product in products" v-bind:key="product.value">
            <span class="name">{{product.name}}</span>
            <span class="name">${{product.price}}</span>
          </li>
      </ul>
  </div>
</template>

<script>
export default {
  data () {
    return {
    }
  },
  computed:{
    products(){
      return this.$store.state.products;
    }
  }
}
</script>

<style>

</style>

运行结果

点击按钮3秒后商品降价,同时Vue开发者工具中Vuex中可以看到调用了相应的mutation。