美文网首页
Vuex学习之实现商品列表页

Vuex学习之实现商品列表页

作者: 北风吹_yfy | 来源:发表于2019-10-17 16:32 被阅读0次
    • 安装
    npm install vuex --save
    //或
    yarn add vuex
    
    • 使用步骤
    1. 创建store文件夹
    //store/store.js
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export const store = new Vuex.Store({
      state: {
        products: [
          { name: "马云", price: 200 },
          { name: "马化腾", price: 100 },
          { name: "马冬梅", price: 20 },
          { name: "马蓉", price: 10 }
        ]
      }
    });
    
    //注意new Vuex.Store的Store的S是大写,否则报错为
    Uncaught TypeError: vuex__WEBPACK_IMPORTED_MODULE_1__.default.store is not a constructor
    
    1. 在main.js中引入store
    import {store} from './store/store';
    
    new Vue({
        store,
        el:"#app",
        render:h => h(App)
    })
    
    1. 使用数据
    //在组件中
    //product-list-one.vue中利用computed属性获取store中的数据
    export default {
        computed:{
            products(){
                return this.$store.state.products;
            }
        }
    }
    

    在完成数据初步渲染之后在组件一种实现改变商品价格的操作

    首先获取需要改变的数据,然后在计算属性中对数据进行改变

    computed: {
        products() {
          return this.$store.state.products;
        },
        saleProducts() {
          let saleProducts = this.$store.state.products.map(product => {
            return {
              name: "**" + product.name + "**",
              price: product.price / 2
            };
          });
          return saleProducts;
        }
      }
    
      //将遍历对象改为saleProducts
       <li v-for="(item,index) in saleProducts" :key="index"></li>
    

    但对于多个组价共用次方法则多次复制比较麻烦,需改为以下方式将方法抽离到store.js中的getters

    在store.js中

    getters:{
        saleProducts:(state) =>  {
          let saleProducts = state.products.map(product => {
            return {
              name: "**" + product.name + "**",
              price: product.price / 2
            };
          });
          return saleProducts;
        }
      }
    

    实现商品降价功能

    1. 在vue中只需在methods中添加一个方法
    methods:{
      reducePrice(){
        this.$store.state.products.forEach(product => {
          product.price -= 1;
        })
      }
    }
    
    1. 更改Vuex的store中的状态的唯一方法是提交mutation,Vuex中的mutation非常类似于事件,没个mutation都有一个字符串的事件类型[type]和一个回调函数,这个回调函数就是我们实际运行状态更改的地方,并且他会接受state作为第一个参数。

    一般在触发事件时才使用mutation,如果是想要获取数据时就使用getters,想要存储数据时就用state,

    //store.js
    //触发事件,改变数据
      mutations: {
        reducePrice: state => {
          state.products.forEach(product => {
            product.price -= 1;
          });
        }
      }
    
    //在组件中使用时用commit激活事件,事件触发的事件名字要与store中的事件名字相同
    methods: {
        reducePrice() {
          this.$store.commit("reducePrice");
        }
      }
    

    vueX还兼容严格模式。

    Actions

    Actions提交的是mutation,而不是直接变更的数据状态。

    如果实现异步操作应该在Action中实现。

    Action是通过store.dispatch触发的。

    //store/store.js
    actions: {
        reducePrice: context => {
          setTimeout(() => {
            context.commit("reducePrice");
          }, 2000);
        }
      }
    
    //组件中
     methods: {
        reducePrice() {
          // this.$store.commit("reducePrice"); //此处commit是直接触发mutation中的方法
          // 此处应调用actions里的方法
          this.$store.dispatch("reducePrice"); //事件名对应store中actions中的方法名
        }
      }
    
    • Actions 可以进行传参

    组件方法中将参数写到分发事件后进行传递,store中通过payload参数进行接收。

    //store.js
    //触发事件,改变数据
      mutations: {
        reducePrice: (state,payload) => {
          state.products.forEach(product => {
            product.price -= payload;
          });
        }
      },
      actions: {
        reducePrice: (context, payload) => {
          setTimeout(() => {
            context.commit("reducePrice",payload);
          }, 2000);
        }
      }
    //组件中
     methods: {
        reducePrice(amount) {
          // this.$store.commit("reducePrice"); //此处commit是直接触发mutation中的方法
          // 此处应调用actions里的方法
          this.$store.dispatch("reducePrice",amount); //事件名对应store中actions中的方法名
        }
      }
    

    辅助函数

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

    • mapGetters
      mapGetters辅助函数仅仅是将store中的getters映射到局部计算属性;

    • mapMutations
      使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用';

    • mapActions
      mapActions辅助函数将组件的methods映射为store.dispatch调用,需要先在根节点注入store;

    <script>
    
    import { mapGetters, mapState, mapActions } from "vuex";
    
    export default {
      computed:{
        // products(){
        //   return this.$store.state.products;
        // },
        ...mapState(["products"]),
        ...mapGetters(["saleProducts"])
      },
      methods:{
         ...mapMutations([
               'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
    
               // `mapMutations` 也支持载荷:
              'incrementBy' // 将 `this.incrementBy(amount)` 映射为 
              `this.$store.commit('incrementBy', amount)`
            ]),
            ...mapMutations({
                 add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
            })
         ...mapActions(["reducePrice"])
      }
    }
    </script>
    
    //如果你想将一个 getter 属性另取一个名字,使用对象形式:
    mapGetters({
      doneCount:"doneTodosCount"
    })
    

    相关文章

      网友评论

          本文标题:Vuex学习之实现商品列表页

          本文链接:https://www.haomeiwen.com/subject/zikvmctx.html