Vuex学习之实现商品列表页

  • 安装
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"
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343