详细讲解vue2组件通信(五)——任意组件vuex3.0

安装vuex

npm install vuex --save

main.js

//引入Vue
import Vue from "vue";
//引入App
import App from "./App.vue";
// 引入store
import store from "./store";
//关闭Vue的生产提示
Vue.config.productionTip = false;

// 引入vuex之后就Vm中就有一个store属性了
//创建vm
new Vue({
  el: "#app",
  render: h => h(App),
  store
});

store.js

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

// --------- Vuex原理的三剑客
const actions = {
  incrementOdd(context, value) {
    if (context.state.sum % 2) {
      context.commit("INCREMENT", value);
    }
  },
  incrementWait(context, value) {
    setTimeout(() => {
      context.commit("INCREMENT", value);
    }, 500);
  }
};
const mutations = {
  INCREMENT(state, value) {
    state.sum += value;
  },
  DECREMENT(state, value) {
    state.sum -= value;
  }
};
// 类似于组件中的data,数据源
const state = {
  sum: 1
};
// 类似于组件的计算属性,可在多个组件中复用的计算属性
const getters = {
  bigSum(state) {
    return state.sum * 10;
  }
};
// ---------

// 在这里声明使用插件,而不在main.js中引用
/* 因为在main.js中引用,模块化的代码执行顺序是先执行import外部模块代码,在执行自己模块的代码,在main.js中引用该store/index.js模块时,
没有先声明Vuex,那么在执行import store from './store' 时解析到调用了new Vuex.Store,但是main.js中的使用插件Vue.use(Vuex)代码执行在import后面*/
Vue.use(Vuex);

export default new Vuex.Store({
  actions,
  mutations,
  state,
  getters
});

Count.vue

<template>
  <div>
    <h1>当前求和为:{{$store.state.sum}}</h1>
    <h2>当前求和结果放大十倍是: {{$store.getters.bigSum}}</h2>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementOdd">当前求和为奇数再加</button>
    <button @click="incrementWait">等一等再加</button>
  </div>
</template>

<script>
  export default {
    name: "Count",
    data() {
      return {
        n: 1 //用户选择的数字
      };
    },
    methods: {
      increment() {
        this.$store.commit("INCREMENT", this.n);
      },
      decrement() {
        this.$store.commit("DECREMENT", this.n);
      },
      incrementOdd() {
        this.$store.dispatch("incrementOdd", this.n);
      },
      incrementWait() {
        this.$store.dispatch("incrementWait", this.n);
      }
    }
  };
</script>

<style lang="css">
  button {
    margin-left: 5px;
  }
</style>
Vuex 辅助函数
mapState 与 mapGetters

当我们需要读取 store 中 state 的数据,我们需要多次书写this.$store.state,代码冗余,这时可以使用 mapState 来快速获取 state 中的数据

mapGetters 同理

import { mapState, mapGetters } from "vuex";
export default {
  computed: {
    // ------自己写计算属性
    // sum(){
    //   return this.$store.state.sum
    // },
    // bigSum(){
    //   return this.$store.getters.bigSum
    // }
    // ------
    // 生成计算属性对象写法
    // ...mapState({sum:'sum'}),
    // 数组写法
    ...mapState(["sum"]),
    // ...mapGetters({bigSum:'bigSum'})
    ...mapGetters(["bigSum"])
  }
};
mapMutations 与 mapActions
<template>
  <button @click="increment(n)">+</button>
  <button @click="decrement(n)">-</button>
  <button @click="incrementOdd(n)">当前求和为奇数再加</button>
  <button @click="incrementWait(n)">等一等再加</button>
</template>
export default {
  methods: {
    /* increment() {
			this.$store.commit("INCREMENT",this.n)
    },
    decrement() {
      this.$store.commit("DECREMENT",this.n)
    }, */

    // 会自动接收页面中{{increment}}接收的参数,如果页面中不传,那么会接收到event事件参数
    ...mapMutations({ increment: "INCREMENT", decrement: "DECREMENT" }),

    /* incrementOdd() {
      this.$store.dispatch("incrementOdd", this.n);
    },
    incrementWait() {
      this.$store.dispatch("incrementWait", this.n);
    } */
    // ...mapActions({incrementOdd:'incrementOdd',incrementWait:'incrementWait'})
    // 如果函数名和后面的通信参数相同可以使用数组
    ...mapActions(["incrementOdd", "incrementWait"])
  }
};
namespace\modules

store/index.js

//该文件用于创建Vuex中最为核心的store
import Vue from "vue";
//引入Vuex
import Vuex from "vuex";
import countOptions from "./count";
import personOptions from "./person";
//应用Vuex插件
Vue.use(Vuex);

//创建并暴露store
export default new Vuex.Store({
  modules: {
    countOptions,
    personOptions
  }
});

store/count.js

//求和相关的配置
export default {
  namespaced: true,
  actions: {
    jiaOdd(context, value) {
      console.log("actions中的jiaOdd被调用了");
      if (context.state.sum % 2) {
        context.commit("JIA", value);
      }
    },
    jiaWait(context, value) {
      console.log("actions中的jiaWait被调用了");
      setTimeout(() => {
        context.commit("JIA", value);
      }, 500);
    }
  },
  mutations: {
    JIA(state, value) {
      console.log("mutations中的JIA被调用了");
      state.sum += value;
    },
    JIAN(state, value) {
      console.log("mutations中的JIAN被调用了");
      state.sum -= value;
    }
  },
  state: {
    sum: 0, //当前的和
    school: "尚硅谷",
    subject: "前端"
  },
  getters: {
    bigSum(state) {
      return state.sum * 10;
    }
  }
};

``person.js`

//人员管理相关的配置
import axios from "axios";
import { nanoid } from "nanoid";
export default {
  namespaced: true,
  actions: {
    addPersonWang(context, value) {
      if (value.name.indexOf("王") === 0) {
        context.commit("ADD_PERSON", value);
      } else {
        alert("添加的人必须姓王!");
      }
    },
    addPersonServer(context) {
      axios.get("https://api.uixsj.cn/hitokoto/get?type=social").then(
        response => {
          context.commit("ADD_PERSON", { id: nanoid(), name: response.data });
        },
        error => {
          alert(error.message);
        }
      );
    }
  },
  mutations: {
    ADD_PERSON(state, value) {
      console.log("mutations中的ADD_PERSON被调用了");
      state.personList.unshift(value);
    }
  },
  state: {
    personList: [{ id: "001", name: "张三" }]
  },
  getters: {
    firstPersonName(state) {
      return state.personList[0].name;
    }
  }
};
vuex的目录结构
├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LiuJie_Boom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值