vuex

2023-10-01  本文已影响0人  渚清与沙白

概述

vue2使用vuex 3版本
vue3 使用vuex 4版本
import vuex from 'vuex'
Vue.use(vuex)

// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

// 响应组件中的动作(异步)
const actions = {};
// 操作数据
const mutations = {};
// 存储数据
const state = {};
const getters = {};

// 创建并导出store
export default new Vuex.Store({
  state,
  getters,
  mutations,
  actions,
});

// main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false

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

State

// 创建store数据源,提供唯一公共数据
const store = new Vuex.Store({
  state:{
    count: 0
  }
})

组件访问State中数据的方式

  1. this.$store.state.count
    在template标签中可以省略this,{{ $store.state.count }}
  2. mapState 生成函数的作用 返回一个对象,key-value的value是一个函数
    image.png
// 导入mapSate函数
import { mapState } from 'vuex'
// 将全局数据,映射为当前组件的计算属性
computed:{
  ...mapState(['count']), // 数组写法 count就是computed的一个属性 
  ...mapState({count,'count'}), // 对象写法 key对应的count是computed对象的属性名;value对应的'count'是state对象的属性名,也是computed对象count属性的值(函数)
}
// 用法
<h1> {{ count }} </h1>

Mutation

matation用于修改state中公共数据
可以集中监控数据的变化

// 创建store数据源,提供唯一公共数据
const store = new Vuex.Store({
  state:{
    count: 0
  },
  mutations:{
    add(state) {
      // 变更状态
      state.aount++
    },
  //  触发mutation时 接收参数
  addNum(state,num) {
      // 变更状态
      state.aount += num;
    }
  }
})

触发mutation的第一种方式,使用commit

methods: {
  handle(){
      // 不传参
      this.$state.commit('add');
  }
   handle2(){
      // 传参
      this.$state.commit('addNum',30);
   }
}

触发mutation的第二种方式mapMutations

// 导入mapMutations函数
import { mapMutations } from 'vuex'
// 将mapMutations函数,映射为当前组件的methods方法
methods: {
  ...mapMutations(['add','addNum']),
handle(){
  // 调用方式
  this.add();
  this.addNum(2);
 }
}

Action

Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
处理异步任务
触发actions异步任务时携带参数

// 定义action
const store = new Vuex.Store({
  state:{
    count: 0
  },
  mutations:{
    add(state) {
      // 变更状态
      state.aount++
    },
  //  触发mutation时 接收参数
  addNum(state,num) {
      // 变更状态
      state.aount += num;
    }
  },
  action: {
    addAsync(context, num) {
      setTimeout(()=>{
        context.commit('addNum',num);
      },1000)
   }
 }
})

触发action的第一种方式dispatch

methods: {
  handle() {
    // 带参数
    this.$store.dispatch('addAsync',5);
  }
}

触发action的第二种方式mapActions

// 导入mapActions函数
import { mapActions } from 'vuex'
// 将需要的actions函数,映射为当前组件的methods方法
methods: {
  ...mapActions(['addAsync']),
 handle() {
    // 调用方式
    this.$state.addAsync(this.num); // @click="addAsync(num)"
 }
}

Getter

用于对State中的数据进行加工处理形成新的数据,不会改变State中的数据
State中数据发生变化,Getter的数据也会跟着变化

// 定义getter
const store = new Vuex.Store({
  state:{
    count: 0
  },
  mutations:{
    add(state) {
      // 变更状态
      state.aount++
    },
  //  触发mutation时 接收参数
  addNum(state,num) {
      // 变更状态
      state.aount += num;
    }
  },
  action: {
    addAsync(context, num) {
      setTimeout(()=>{
        context.commit('addNum',num);
      },1000)
   }
 },
getters: {
  showNum: state => {
    return 'getter:'+state.count;
  }
}
})

使用getters第一种方式getter
this.$store.getter.showNum
template中使用可以省略this关键字

使用getters第二种方式mapGetters

import { mapGetters } from 'vuex'
computed: {
  ...mapGetters(['showNum'])
},
methods: {
  handle()  {
  this.showNum();
 }
}
mapState, mapGetters, mapMutations, mapActions的用法
<template>
  <div>
    <p>当前值:{{sum}}</p>
    <p>当前学校:{{school}}</p>
    <p>当前科目:{{subject}}</p>
    <p>当前大数:{{bigSum}}</p>
    <p>当前学校:{{xuexiao}}</p>"

    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>
    <button @click="incrementOdd(n)">+</button>
    <button @click="decrementOdd(n)">-</button>
  </div>
</template>

<script> 
import {mapState, mapGetters, mapMutations, mapActions} from "vuex";
export default {
  name: "Test",
  data() {
    return {
      n:0,
    };
  },
  computed: {
    // 借助mapState方法生成计算属性,从state中读取数据
    // 对象写法
   ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),
   // 数组写法
   ...mapState(["sum",'school','subject']),

   // 借助mapGetters方法生成计算属性,从getters中读取数据
   // 对象写法
   ...mapGetters({bigSum:'bigSum'}),
   // 数组写法
   ...mapGetters(['bigSum']),
  // 模块
   ...mapGetters('setting', ['firstMenu', 'subMenu', 'menuData']),
  },
  methods:{
    // mapMutations:借助mapMutations方法生成对应的方法,方法中会调用commit去联系mutations
    // 对象写法 
    ...mapMutations({increment:'JIA', decrement:'JIAN'}),
    // 数组写法
    ...mapMutations(["JIA","JIAN"]),
    // 模块account中的方法
    ...mapMutations("account", ["setUser", "setPermissions", "setRoles"]),

    // 借助mapActions方法生成对应的方法,方法中会调用dispatch去联系actions
    //  对象写法
   ...mapMutations({incrementOdd:'jiaOdd', decrementOdd:'jianOdd'}),
    //  数组写法
   ...mapActions(["jiaOdd","jianOdd"]),
  },
};
</script>

模块化和命名空间modules namespaced

  1. 目的:更换维护,分类明确
  2. 优化store.js
  3. modules使用场景
    项目复杂管理大量的状态,此时可以使用modules方式进行拆分,每一个都具有state、getter、action、matation。
  4. 在模块中使用:namespaced: true, 命名空间,当前模块下的标识符可以和其它模块相同,用于解决不同模块的命名冲突问题
  5. store目录下,创建modules文件夹,该文件夹创建index.js及拆分的模块文件。store文件夹下的index.js再导入modules ,然后进行挂载。挂栽对象格式是{ modules: { account: {}, setting: {} } }
    image.png
const countAbout = {
    namespaced:true,// 开启命名空间
    state: {num:1},
    mutations: { ... },
    actions: { ... },
    getters: {
        bigSum(state){
            return state.num * 10;
        }
    }
}

const personAbout = {
    namespaced:true,// 开启命名空间
    state: { ... },
    mutations: { ... },
    actions: { ... },
}

const store = new Vuex.Store({
    modules: {
        countAbout,
        personAbout
    }
})
  1. 开启命名空间后,组件中读取state数据
// 方式一 自己直接读取
this.$store.state.personAbout.personList
this.$store.state.countAbout.sum

// 方式二 辅助mapState读取
...mapState('countAbout',['sum','shcool','subject'])

  1. 开启命名空间后,组件中读取getters数据
// 方式一 自己直接读取
this.$store.getters['personAbout/firstName']

// 方式二 辅助mapGetters读取
...mapGetters('countAbout',['bigSum'])

  1. 开启命名空间后,组件中调用dispatch
// 方式一 自己直调用dispatch
this.$store.dispatch('personAbou/addPersonWang',personObj)

// 方式二 辅助mapActions
...mapActions('countAbout',{incrementOdd:'jiaOdd'})

  1. 开启命名空间后,组件中调用commit
// 方式一 自己直接调用commit
this.$store.commit('personAbout/ADD_PERSON',personObj)

// 方式二 辅助mapMutations
...mapMutations('countAbout',{increment:'JIA'})

上一篇下一篇

猜你喜欢

热点阅读