使用Vuex

文章目录

    • 不使用Vuex
    • 使用Vuex
      • 试试store先,state+actions+mutations
      • 使用Vuex第一版,state+actions+mutations,dispatch+commit
      • 使用Vuex第二版,state+actions+mutations,dispatch+commit
      • 使用Vuex第三版,state+actions+mutations,dispatch+commit
      • 使用Vuex的getters
      • 使用Vuex中的mapState和mapGetters
        • 计算属性
        • 使用mapState从state中读取数据,生成计算属性
        • 使用mapGetters从getters中读取数据,生成计算属性
      • 使用Vuex中的mapMutations和mapActions
        • 方法
        • 使用mapMutations生成对应方法
        • 使用mapActions生成对应方法
      • Vuex的的模块化编程
        • 基础样例
        • 模块化+命名空间

不使用Vuex

  • 组件Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    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 {
      sum:0,
      n:1
    }
  },
  methods:{
    increment(){
      this.sum += this.n;
    },
    decrement(){
      this.sum -= this.n;
    },
    incrementOdd(){
      if(this.sum % 2){
        this.sum += this.n;
      }
    },
    incrementWait(){
      setTimeout(() => {
        this.sum += this.n;
      },500);
    }
  }
}
script>

<style>
button{
  margin-left: 5px;
}
style>
  • 组件App.vue
<template>
  <div id="container">
      <Count/>
  div>
template>

<script>
import Count from './components/Count.vue'

export default {
  name: 'App',
  components: {
    Count
  }
}
script>
  • 入口文件main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
  • 启动应用,测试效果
    使用Vuex_第1张图片

使用Vuex

试试store先,state+actions+mutations

首先当然是安装vuex。

npm install --save vuex@3

注意哈,vue2时使用vuex的3版本,vue3时使用vuex的4版本。

  • 在src目录下创建store目录,并在store目录下新建文件index.js,index.js内容如下。
//index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const actions = {};
const mutations = {};
const state = {};

export default new Vuex.Store({
    actions,
    mutations,
    state
})
  • 在入口文件main.js中导入store。
//main.js
import Vue from 'vue'
import App from './App.vue'
import store from "./store/index";

Vue.config.productionTip = false

const vm = new Vue({
  render: h => h(App),
  store,
}).$mount('#app');
console.log(vm);

以上完成后,store对所有组件可见。
不妨验证下:在App.vue和Count.vue的mounted函数中打印this,如下所示。

  • 组件Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    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,
      sum:0
    }
  },
  methods:{
    increment(){
      this.sum += this.n;
    },
    decrement(){
      this.sum -= this.n;
    },
    incrementOdd(){
      if(this.sum % 2){
        this.sum +=  this.n;
      }
    },
    incrementWait(){
      setTimeout(() => {
        this.sum += this.n;
      },500);
    }
  },
  mounted(){
    console.log("mounted in Count",this);
  }
}
script>

<style>
button{
  margin-left: 5px;
}
style>
  • 组件App.vue
<template>
  <div id="container">
      <Count/>
  div>
template>

<script>
import Count from './components/Count.vue'

export default {
  name: 'App',
  components: {
    Count
  },
  mounted(){
    console.log("mounted in App",this);
  }
}
script>

使用Vuex_第2张图片
使用Vuex_第3张图片

使用Vuex第一版,state+actions+mutations,dispatch+commit

修改Count.vue,内容如下。

<template>
  <div class="box">
    <h2>当前和的值为:{{$store.state.sum}}h2>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    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.dispatch("increment",this.n);
    },
    decrement(){
      this.$store.dispatch("decrement",this.n);
    },
    incrementOdd(){
      if(this.$store.state.sum % 2){
        this.$store.dispatch("incrementOdd",this.n);
      }
    },
    incrementWait(){
      setTimeout(() => {
        this.$store.dispatch("incrementWait",this.n);
      },500);
    }
  }
}
script>

<style>
button{
  margin-left: 5px;
}
style>

修改store/index.js,内容如下。

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

Vue.use(Vuex);

const actions = {
    increment(context,value){
        context.commit("INCREMENT",value);
    },
    decrement(context,value){
        context.commit("DECREMENT",value);
    },
    incrementOdd(context,value){
        context.commit("INCREMENT",value);
    },
    incrementWait(context,value){
        context.commit("INCREMENT",value);
    }
};
const mutations = {
    INCREMENT(state,value){
        state.sum += value;
    },
    DECREMENT(state,value){
        state.sum -= value;
    }
};
const state = {
    sum:0
};

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

使用Vuex_第4张图片
使用Vuex_第5张图片

使用Vuex第二版,state+actions+mutations,dispatch+commit

修改Count.vue,内容如下。

<template>
  <div class="box">
    <h2>当前和的值为:{{$store.state.sum}}h2>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    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.dispatch("increment",this.n);
    },
    decrement(){
      this.$store.dispatch("decrement",this.n);
    },
    incrementOdd(){
      this.$store.dispatch("incrementOdd",this.n);
    },
    incrementWait(){
      this.$store.dispatch("incrementWait",this.n);
    }
  }
}
script>

<style>
button{
  margin-left: 5px;
}
style>

修改store/index.js,内容如下。

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

Vue.use(Vuex);

const actions = {
    increment(context,value){
        context.commit("INCREMENT",value);
    },
    decrement(context,value){
        context.commit("DECREMENT",value);
    },
    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;
    }
};
const state = {
    sum:0
};

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

使用Vuex第三版,state+actions+mutations,dispatch+commit

修改Count.vue,内容如下。

<template>
  <div class="box">
    <h2>当前和的值为:{{$store.state.sum}}h2>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    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>
button{
  margin-left: 5px;
}
style>

修改main.js,内容如下。

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

Vue.use(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;
    }
};
const state = {
    sum:0
};

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

使用Vuex_第6张图片

使用Vuex的getters

vuex里的getters有点类似于vue里的computed,具体看例子吧。

  • Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{$store.state.sum}}h2>
    <h3>当前和的值放大10倍:{{$store.getters.bigSum}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    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>
button{
  margin-left: 5px;
}
style>
  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const actions = {
    incrementOdd(context,value){
        console.log(context);
        if(context.state.sum % 2){
            context.commit("INCREMENT",value);
        }
    },
    incrementWait(context,value){
        setTimeout(() => {
            context.commit("INCREMENT",value);
        },500);
    }
};
const mutations = {
    INCREMENT(state,value){
        console.log(state);
        state.sum += value;
    },
    DECREMENT(state,value){
        state.sum -= value;
    }
};
const state = {
    sum:0
};
const getters = {
    bigSum(state){
        return state.sum*10;
    }
}

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

使用Vuex_第7张图片

使用Vuex_第8张图片

使用Vuex中的mapState和mapGetters

计算属性
  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(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){
        console.log(state);
        state.sum += value;
    },
    DECREMENT(state,value){
        state.sum -= value;
    }
};
const state = {
    sum:0,
    company:"五哈科技有限公司",
    position:"前端工程师"
};
const getters = {
    bigSum(state){
        return state.sum*10;
    }
}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
  • Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <h3>当前和的值放大10倍:{{bigSum}}h3>
    <h3>我在{{company}}工作,岗位是{{position}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    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
    }
  },
  computed:{
    sum(){
      return this.$store.state.sum;
    },
    company(){
      return this.$store.state.company;
    },
    position(){
      return this.$store.state.position;
    },
    bigSum(){
      return this.$store.getters.bigSum;
    }
  },
  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>
button{
  margin-left: 5px;
}
style>

使用Vuex_第9张图片
使用Vuex_第10张图片

使用mapState从state中读取数据,生成计算属性
  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(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;
    }
};
const state = {
    sum:0,
    company:"五哈科技有限公司",
    position:"前端工程师"
};
const getters = {
    bigSum(state){
        return state.sum*10;
    }
}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
  • Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <h3>当前和的值放大10倍:{{bigSum}}h3>
    <h3>我在{{company}}工作,岗位是{{position}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    select>
    <button @click="increment">+button>
    <button @click="decrement">-button>
    <button @click="incrementOdd">和为基数的时候加button>
    <button @click="incrementWait">等一会会再加button>
  div>
template>

<script>
import {mapState} from "vuex";
export default {
  name:"Count",
  data(){
    return {
      n:1
    }
  },
  computed:{
    //对象写法
    ...mapState({
      sum:'sum',
      company:'company',
      position:'position'
    }),
    
    //数组写法
    // ...mapState(['sum','company','position']),

    bigSum(){
      return this.$store.getters.bigSum;
    }
  },
  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>
button{
  margin-left: 5px;
}
style>

使用Vuex_第11张图片

使用mapGetters从getters中读取数据,生成计算属性
  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(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;
    }
};
const state = {
    sum:0,
    company:"五哈科技有限公司",
    position:"前端工程师"
};
const getters = {
    bigSum(state){
        return state.sum*10;
    }
}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
  • Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <h3>当前和的值放大10倍:{{bigSum}}h3>
    <h3>我在{{company}}工作,岗位是{{position}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    select>
    <button @click="increment">+button>
    <button @click="decrement">-button>
    <button @click="incrementOdd">和为基数的时候加button>
    <button @click="incrementWait">等一会会再加button>
  div>
template>

<script>
import {mapState,mapGetters} from "vuex";
export default {
  name:"Count",
  data(){
    return {
      n:1
    }
  },
  computed:{
    ...mapState(['sum','company','position']),
    //对象写法
    ...mapGetters({bigSum:'bigSum'})

    //数组写法
    // ...mapGetters(['bigSum'])
  },
  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>
button{
  margin-left: 5px;
}
style>

使用Vuex_第12张图片

使用Vuex中的mapMutations和mapActions

方法
  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(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;
    }
};
const state = {
    sum:0,
    company:"五哈科技有限公司",
    position:"前端工程师"
};
const getters = {
    bigSum(state){
        return state.sum*10;
    }
}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
  • Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <h3>当前和的值放大10倍:{{bigSum}}h3>
    <h3>我在{{company}}工作,岗位是{{position}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    select>
    <button @click="increment">+button>
    <button @click="decrement">-button>
    <button @click="incrementOdd">和为基数的时候加button>
    <button @click="incrementWait">等一会会再加button>
  div>
template>

<script>
import {mapState,mapGetters} from "vuex";
export default {
  name:"Count",
  data(){
    return {
      n:1
    }
  },
  computed:{
    ...mapState(['sum','company','position']),
    ...mapGetters(['bigSum'])
  },
  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>
button{
  margin-left: 5px;
}
style>

使用Vuex_第13张图片

使用mapMutations生成对应方法

使用mapMutations生成对应方法,方法中调用commit联系到mutations。

  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(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;
    }
};
const state = {
    sum:0,
    company:"五哈科技有限公司",
    position:"前端工程师"
};
const getters = {
    bigSum(state){
        return state.sum*10;
    }
}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
  • Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <h3>当前和的值放大10倍:{{bigSum}}h3>
    <h3>我在{{company}}工作,岗位是{{position}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    select>
    <button @click="increment(n)">+button>
    <button @click="decrement(n)">-button>
    
    <button @click="incrementOdd">和为基数的时候加button>
    <button @click="incrementWait">等一会会再加button>
  div>
template>

<script>
import {mapState,mapGetters,mapMutations} from "vuex";
export default {
  name:"Count",
  data(){
    return {
      n:1
    }
  },
  computed:{
    ...mapState(['sum','company','position']),
    ...mapGetters(['bigSum'])
  },
  methods:{
    increment(){
      this.$store.commit("INCREMENT",this.n);
    },
    decrement(){
      this.$store.commit("DECREMENT",this.n);
    },
    //使用Vuex中的mapMutations生成对应的方法,生成的方法会调用commit去联系mutations
    ...mapMutations({increment:'INCREMENT',decrement:'DECREMENT'}),
    incrementOdd(){
      this.$store.dispatch("incrementOdd",this.n);
    },
    incrementWait(){
      this.$store.dispatch("incrementWait",this.n);
    }
  }
}
script>

<style>
button{
  margin-left: 5px;
}
style>

使用Vuex_第14张图片

使用mapActions生成对应方法

使用mapActions生成对应方法,方法中调用dispatch联系到actions。

  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(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;
    }
};
const state = {
    sum:0,
    company:"五哈科技有限公司",
    position:"前端工程师"
};
const getters = {
    bigSum(state){
        return state.sum*10;
    }
}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
  • Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <h3>当前和的值放大10倍:{{bigSum}}h3>
    <h3>我在{{company}}工作,岗位是{{position}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    select>
    <button @click="increment(n)">+button>
    <button @click="decrement(n)">-button>
    <button @click="incrementOdd(n)">和为基数的时候加button>
    <button @click="incrementWait(n)">等一会会再加button>
  div>
template>

<script>
import {mapState,mapGetters,mapMutations,mapActions} from "vuex";
export default {
  name:"Count",
  data(){
    return {
      n:1
    }
  },
  computed:{
    ...mapState(['sum','company','position']),
    ...mapGetters(['bigSum'])
  },
  methods:{
    ...mapMutations({increment:'INCREMENT',decrement:'DECREMENT'}),
    ...mapActions({incrementOdd:'incrementOdd',incrementWait:'incrementWait'})
  }
}
script>

<style>
button{
  margin-left: 5px;
}
style>

使用Vuex_第15张图片
使用Vuex_第16张图片

Vuex的的模块化编程

基础样例
  • 组件Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <h3>当前和的值放大10倍:{{bigSum}}h3>
    <h3>我在{{company}}工作,岗位是{{position}}h3>
    <h3 style="color:red;">Person组件总人数是:{{personList.length}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    select>
    <button @click="increment(n)">+button>
    <button @click="decrement(n)">-button>
    <button @click="incrementOdd(n)">和为基数的时候加button>
    <button @click="incrementWait(n)">等一会会再加button>
  div>
template>

<script>
import {mapState,mapGetters,mapMutations,mapActions} from "vuex";
export default {
  name:"Count",
  data(){
    return {
      n:1
    }
  },
  computed:{
    ...mapState(['sum','company','position','personList']),
    ...mapGetters(['bigSum'])
  },
  methods:{
    ...mapMutations({increment:'INCREMENT',decrement:'DECREMENT'}),
    ...mapActions(['incrementOdd','incrementWait'])
  }
}
script>

<style>
button{
  margin-left: 5px;
}
style>
  • 组件Person.vue
<template>
    <div>
        <h1>人员列表h1>
        <h3 style="color:red;">Count组件当前和的值:{{sum}}h3>
        <input type="text" placeholder="请输入名字" v-model="name">
        <button @click="add">添加button>
        <ul>
            <li v-for="person in personList" :key="person.id">{{person.name}}li>
        ul>
    div>
template>

<script>
import {nanoid} from "nanoid";
export default {
    name:"Person",
    data(){
        return {
            name:''
        }
    },
    computed:{
      personList(){
          return this.$store.state.personList;
      },
      sum(){
          return this.$store.state.sum;
      }
    },
    methods:{
        add(){
            const personObj = {
                id:nanoid(),
                name:this.name
            }
            this.$store.commit("ADD_PERSON",personObj);
            this.name = '';
        }
    }

}
script>

<style>

style>
  • 组件App.vue
<template>
  <div id="container">
      <Count/>
      <Person/>
  div>
template>

<script>
import Count from './components/Count.vue';
import Person from './components/Person.vue';

export default {
  name: 'App',
  components: {
    Count,
    Person
  }
}
script>
  • 入口文件main.js
import Vue from 'vue'
import App from './App.vue'
import store from "./store/index";

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  store,
}).$mount('#app');
  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(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;
    },
    ADD_PERSON(state,value){
        state.personList.unshift(value);
    }
};
const state = {
    sum:0,
    company:"五哈科技有限公司",
    position:"前端工程师",
    personList:[
        {id:"001",name:"张三"}
    ]
};
const getters = {
    bigSum(state){
        return state.sum*10;
    }
}


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

使用Vuex_第17张图片

模块化+命名空间
  • 组件Count.vue
<template>
  <div class="box">
    <h2>当前和的值为:{{sum}}h2>
    <h3>当前和的值放大10倍:{{bigSum}}h3>
    <h3>我在{{company}}工作,岗位是{{position}}h3>
    <h3 style="color:red;">Person组件总人数是:{{personList.length}}h3>
    <select v-model.number="n">
      <option value="1">1option>
      <option value="2">2option>
      <option value="3">3option>
    select>
    <button @click="increment(n)">+button>
    <button @click="decrement(n)">-button>
    <button @click="incrementOdd(n)">和为基数的时候加button>
    <button @click="incrementWait(n)">等一会会再加button>
  div>
template>

<script>
import {mapState,mapGetters,mapMutations,mapActions} from "vuex";
export default {
  name:"Count",
  data(){
    return {
      n:1
    }
  },
  computed:{
    ...mapState('countAbout',['sum','company','position','personList']),
    ...mapState('personAbout',['personList']),
    ...mapGetters('countAbout',['bigSum'])
  },
  methods:{
    ...mapMutations('countAbout',{increment:'INCREMENT',decrement:'DECREMENT'}),
    ...mapActions('countAbout',['incrementOdd','incrementWait'])
  }
}
script>

<style>
button{
  margin-left: 5px;
}
style>
  • 组件Person.vue
<template>
    <div>
        <h1>人员列表h1>
        <h3 style="color:red;">Count组件当前和的值:{{sum}}h3>
        <h3>列表中第一个人的名字是:{{firstPersonName}}h3>
        <input type="text" placeholder="请输入名字" v-model="name">
        <button @click="add">添加button>
        <button @click="addWang">添加一个姓王的人button>
        <button @click="addPersonRandom">添加随机内容button>
        <ul>
            <li v-for="person in personList" :key="person.id">{{person.name}}li>
        ul>
    div>
template>

<script>
import {nanoid} from "nanoid";
export default {
    name:"Person",
    data(){
        return {
            name:''
        }
    },
    computed:{
      personList(){
          return this.$store.state.personAbout.personList;
      },
      sum(){
          return this.$store.state.countAbout.sum;
      },
      firstPersonName(){
          return this.$store.getters['personAbout/firstPersonName'];
      }
    },
    methods:{
        add(){
            const personObj = {
                id:nanoid(),
                name:this.name
            }
            this.$store.commit("personAbout/ADD_PERSON",personObj);
            this.name = '';
        },
        addWang(){
            const personObj = {
                id:nanoid(),
                name:this.name
            }
            this.$store.dispatch("personAbout/addPersonWang",personObj);
            this.name = '';
        },
        addPersonRandom(){
            this.$store.dispatch("personAbout/addPersonServer");
        }
    },
    mounted(){
        console.log(this.$store);
    }

}
script>

<style>

style>
  • store/index.js
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
import { nanoid } from "nanoid";

Vue.use(Vuex);

const countOptions = {
    namespaced:true,
    actions:{
        incrementOdd(context,value){
            if(context.state.sum % 2){
                context.commit("INCREMENT",value);
            }
        },
        incrementWait(context,value){
            setTimeout(() => {
                context.commit("INCREMENT",value);
            },500);
        }
    },
    mutations:{
        INCREMENT(state,value){
            state.sum += value;
        },
        DECREMENT(state,value){
            state.sum -= value;
        }
    },
    state:{
        sum:0,
        company:"五哈科技有限公司",
        position:"前端工程师"
    },
    getters:{
        bigSum(state){
            return state.sum*10;
        }
    }
}

const personOptions = {
    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 => {
                    console.log(response.data);
                    context.commit("ADD_PERSON",{
                        id:nanoid(),
                        name:response.data
                    })
                },
                error => {
                    alert(error.message);
                }
            )
        }
    },
    mutations:{
        ADD_PERSON(state,value){
            state.personList.unshift(value);
        }
    },
    state:{
        personList:[
            {id:"001",name:"张三"}
        ]
    },
    getters:{
        firstPersonName(state){
            return state.personList[0].name;
        }
    }
}

export default new Vuex.Store({
    modules:{
        countAbout:countOptions,
        personAbout:personOptions
    }
})

使用Vuex_第18张图片使用Vuex_第19张图片
使用Vuex_第20张图片

//开启命名空间后,组件中读取state中的数据
...mapState('personAbout',['personList'])
this.$store.state.personAbout.personList

//开启命名空间后,组件中读取getters中的数据
...mapGetters('countAbout',['bigSum'])
this.$store.getters['personAbout/firstPersonName']

//开启命名空间后,组件中调用dispatch
...mapActions('countAbout',['incrementOdd','incrementWait'])
this.$store.dispatch("personAbout/addPersonWang",personObj)

//开启命名空间后,组件中调用commit
...mapMutations('countAbout',{increment:'INCREMENT',decrement:'DECREMENT'})
this.$store.commit("personAbout/ADD_PERSON",personObj)

你可能感兴趣的:(Vue2,vuex,mapState,mapGetters,mapActions,mapMutations)