vuex学习总结

129 阅读4分钟

vuex的作用:在多个组件之间共享状态

  • 应用场景

    • 多个界面之间的共享问题
    • 用户登录状态,用户名,头像,地理位置等
    • 商品的收藏,购物车
  • 下载
    • npm install vuex --save
  • 使用:
    • 在src文件夹下创建store文件夹,内置index.js文件

    • index.js文件:

      •   import Vuex from 'vuex';
          //将vuex挂在到vue的原型上
          Vue.use(Vuex);
          
          //创建对象
          const store = new Vuex.Store({
            state: {//定义数据
              
            },
            mutations: {
          
            },
            actions: {
          
            },
            getters: {
          
            },
            modules: {
          
            }
          })
          //导出store
          export {
              store
          } 
        
    • main.js文件中挂载

      •    import {store} from './store/index'
           new Vue({
             el: '#app',
             store,
             components: { App },
             template: '<App/>'
           })
        

常量

  • 在store文件中新建一个mutations-types.js的文件
        const GlobalCount = 'globalCount';
        const GlobalObj = 'globalObj';
        const GlobalArr = 'globalArr';
        const ADD = 'add';
        const AddPeople = 'addPeople';
        const GlobalCountPower = 'globalCountPower';
        const GlobalArrFilter = 'globalArrFilter';
        const ChangeName = 'changeName';
        const AsynChangeName = 'asynChangeName';
        export{
            GlobalCount,
            GlobalObj,
            GlobalArr,
            ADD,
            AddPeople,
            GlobalCountPower,
            GlobalArrFilter,
            ChangeName,
            AsynChangeName
        }
    
  • store文件中的index.js
        import Vue from 'vue';
        import Vuex from 'vuex';
        //将vuex挂在到vue的原型上
        Vue.use(Vuex);
        import {
          GlobalCount,
          GlobalObj,
          GlobalArr,
          ADD,
          AddPeople,
          GlobalCountPower,
          GlobalArrFilter,
          ChangeName,
          AsynChangeName
        } from './mutations-types';
        
        //创建对象
        const store = new Vuex.Store({
          state: {
            [GlobalCount]: 999,
            [GlobalObj]: {
              name: '张三',
              age: 12
            },
            [GlobalArr]: [{
                name: '李四',
                age: 16
              },
              {
                name: '王五',
                age: 20
              },
              {
                name: '赵六',
                age: 30
              }
            ]
          },
          mutations: {
            [ADD](state) {
              state[GlobalCount]++;
            },
            [AddPeople](state, Payload) {
              console.log(Payload) //传参方式一的参数格式:{name: "新人", age: 1}
              console.log(Payload) //传参方式二的参数格式:{type: "addPeople", name: "新人", age: 1}
              state[GlobalArr].push(Payload)
            },
            [ChangeName](state,Payload){
                state[GlobalObj].name=Payload;
            }
          },
          actions: {//只要是修改state中的值,一步操作都必须在这里面完成,不能再调用组件中编写异步操作
            [AsynChangeName](context,Payload){
                return new Promise((resolve,reject)=>{
                    setTimeout(()=>{
                        context.commit(ChangeName,Payload.name);
                        resolve('成功了')
                    },2000)
                })
            }
          },
          getters: {
            [GlobalCountPower](state) {
              return state[GlobalCount] * state[GlobalCount];
            },
            [GlobalArrFilter](state, getters) {
              return function (age) {
                return state[GlobalArr].filter(item => {
                  return item.age > age
                })
              }
            }
          },
          modules: {
        
          }
        })
        //导出store
        export {
          store
        }
    
  • 在组件中使用
    <template>
          <div id="app">
            <h1>vuex学习</h1>
            <p>{{customName3}}</p>
            <p>{{customName}}</p>
            <p>{{customName2}}</p>
            <p>{{customName1(20)}}</p>
            <button @click='addCount'>++</button>
            <button @click='addPeople({
              "name":"新人",
              "age":1
            })'>+人</button>
            <button @click='changeName'>一步操作:改名字</button>
          </div>
        </template>
    
    <script>
    import { mapState, mapGetters, mapMutations, mapActions } from "vuex";  
    import {GlobalCount,
        GlobalObj,
        GlobalArr,
        ADD,
        AddPeople,
        GlobalCountPower,
        GlobalArrFilter,
        ChangeName,
        AsynChangeName
    } from './store/mutations-types';
    export default {
      name: "App",
      data() {
        return {
          count: 0
        };
      },
      computed: {
        ...mapState({
          customName:GlobalCount,
          customName2:GlobalArr,
          customName3: GlobalObj
        }),
        ...mapGetters({
          customName1:GlobalArrFilter
        })
      },
      methods: {
        // addCount(){
        //   this.$store.commit('add')
        // },
        ...mapMutations({
          addCount:ADD,
          addPeople:AddPeople//这种带参数的提交会默认将addPeople的参数穿进去
        }),
        // addPeople(){//传参方式一
        //   this.$store.commit('addPeople',{
        //     name:'新人',
        //     age:1
        //   })
        // },
    
        // addPeople(){//传参方式二
        //   this.$store.commit({
        //     type:'addPeople',
        //     name:'新人',
        //     age:1
        //   })
        // }
        
        changeName() {
              this.$store.dispatch(AsynChangeName, {
                name: "新名字"
              }).then(res=>{
                console.log(res)
              })
            }
      }
    };
    </script>
    

参数详解

  • state
    • store文件中的index.js中定义state:作用:定义需要共享的数据
      state: {
          globalCount: 999,
          studentArr: [{
              name: '肖宝成',
              age: 25
            },
            {
              name: '王亚婷',
              age: 24
            }
          ]
        }
      
    • 在组件中使用
      <template>
        <div id="app">
          <h1>vuex学习</h1>
          <p>{{changeMsg}}</p>
          <p>{{custom1}}</p>
          <p>{{custom2}}</p>
        </div>
      </template>
      
      <script>
      import { mapState } from 'vuex' 
      export default{
          computed: {//利用计算属性简化调用
              changeMsg() {
                return  this.$store.state[state中对应的数据[key]]
                return this.$store.state.globalCount;
              },
              ...mapGetters({
                [自定义名称]: "[state中对应的数据[key]]",
                customName1:"globalCount",
                customName2:"studentArr",
                [自定义名称](){
                    return this.$store.state[state中对应的数据[key]] + this[组件中对应的局部数据];
                    return this.$store.state[GlobalCount] + this.count;
                }
              })
        }
      }
      </script>
      
  • getters
    • store文件中的index.js中定义getters:作用对state中的数据进行处理
      getters: {
          power(state) {//接受一个参数
            return state.globalCount * state.globalCount
          },
          filterAge(state) {//接受一个参数
            return state.studentArr.filter(item => {
              return item.age > 24
            })
          },
          filterAgeLength(state,getters){//接受两个参数
              return getters.filterAge.length
          },
          filterAgeParams(state){//接受一个参数
              return function(params){//接受组件中的传参
                  return state.studentArr.filter(item => {
                      return item.age > params
                    })
              }
          }
        }
      
    • 在组件中使用
      <template>
        <div id="app">
          <h1>vuex学习</h1>
          <p>{{changeMsg}}</p>
          <p>{{changeMsg1}}</p>
          <p>{{custom1}}</p>
          <p>{{custom2}}</p>
          <p>{{custom3}}</p>
          <p>{{custom4(20)}}</p>
        </div>
      </template>
      
      <script>
          import { mapGetters } from 'vuex' 
          export default{
              changeMsg() {
                return this.$store.getters[getters中对应的数据[key]]
                return this.$store.getters.power;
              },
              changeMsg1() {
                return this.$store.getters[getters中对应的函数名称]('有参数传参')
                return this.$store.getters.filterAgeParams(24);
              },
              ...mapGetters({
                [自定义名称]: "[getters中对应的函数名称]"
                custom1: "power",
                custom2:"filterAge",
                custom3:"filterAgeLength",
                custom4:"filterAgeParams"
              })
          }
          </script>
      
  • mutations:中不能处理异步操作,切记!
    • mutations:用于操作state中的数据
      mutations: {
          add(state) {//不传参
              state.globalCount+=speed;
          },
          reduce(state) {//不传参
              state.globalCount-=speed;
          },
          addPeople(state,obj){//传参
              方法一传参打印obj==>{name: "张三", age: 12}
              方法二传参打印obj==>{type: "addPeople", name: "张三", age: 12}
              state.studentArr.push(obj)
          }
      }
      
    • 在组件中使用
          <template>
                <div id="app">
                  <h1>vuex学习</h1>
                  <p>{{customName}}</p>
                  <p>{{customName2}}</p>
                  <button @click='addCount'>++</button>
                  <button @click='addPeople({
                    "name":"新人",
                    "age":1
                  })'>+人</button>
                </div>
              </template>
              
              <script>
              import { mapState,mapGetters,mapMutations } from "vuex";
              export default {
                name: "App",
                computed: {
                  ...mapState({
                    customName:'globalCount',
                    customName2:'globalArr'
                  }),
                  ...mapGetters({
                    customName1:'globalArrFilter'
                  })
                },
                methods: {
                  // addCount(){
                  //   this.$store.commit('add')
                  // },
                  ...mapMutations({
                    addCount:'add',
                    addPeople:'addPeople'//这种带参数的提交会默认将addPeople的参数穿进去
                  }),
                  // addPeople(){//传参方式一
                  //   this.$store.commit('addPeople',{
                  //     name:'新人',
                  //     age:1
                  //   })
                  // },
              
                  // addPeople(){//传参方式二
                  //   this.$store.commit({
                  //     type:'addPeople',
                  //     name:'新人',
                  //     age:1
                  //   })
                  // }
                }
              };
              </script>
      
  • actions
    • actions:用于操作state中的数据:一步操作,不能再调用的组件中进行异步操作,必须在这里
       import { AsynChangeName } from ".mutations-types";
          actions: {//只要是修改state中的值,一步操作都必须在这里面完成,不能再调用组件中编写异步操作
              [AsynChangeName](context,Payload){
                  return new Promise((resolve,reject)=>{
                      setTimeout(()=>{
                          context.commit(ChangeName,Payload.name);
                          resolve('成功了')
                      },2000)
                  })
              }
            }
      
    • 在组件中使用
          <template>
              <button @click='changeName({
                    name:"新名字"
              })'>一步操作:改名字</button>
          <template/>
          
          <script>
          import { mapActions } from "vuex";
          import { AsynChangeName } from "./store/mutations-types";
          export default{
              ...mapActions({//默认会携带changeName('传参')
                  changeName: AsynChangeName
              }),
              
              // changeName(obj) {
              //   this.$store
              //     .dispatch(AsynChangeName,obj)
              //     .then(res => {
              //       console.log(res);
              //     });
              // }
          }
          </script>