美文网首页
Vuex 学习笔记

Vuex 学习笔记

作者: lazy_tomato | 来源:发表于2021-01-06 16:20 被阅读0次

    官网文档

    https://vuex.vuejs.org/zh/

    概念

    • Vuex是适用于在Vue项目开发时使用的状态管理工具
    • Vue为被多个组件频繁使用的值提供了一个统一管理的工具Vuex
    • VuexVue项目中,我们只需要把这些值定义在Vuex中,即可在整个Vue项目中使用

    Vuex核心内容

    VueX对象中,其实不止有state,还有用来操作state中数据的方法集,以及当我们需要对state中的数据需要加工的方法集等等成员。

    成员列表:

    • state 存放状态
    • mutations state成员操作
    • actions 加工state成员给外界
    • getters 异步操作
    • modules 模块化状态管理

    Vuex工作流程

    vuex工作流程.png
    • 首先,Vue组件如果调用某个VueX的方法过程中需要向后端请求时或者说出现异步操作时,需要dispatch VueXactions的方法,以保证数据的同步。
    • 可以说,action的存在就是为了让mutations中的方法能在异步操作中起作用。
    • 如果没有异步操作,那么我们就可以直接在组件内提交状态中的Mutations中自己编写的方法来达成对state成员的操作。
    • 不建议在组件中直接对state中的成员进行操作,这是因为直接修改(例如:this.$store.state.name = 'hello')的话不能被VueDevtools所监控到。
    • 最后被修改后的state成员会被渲染到组件的原位置当中去

    state

    • state仓库,存储数据的地方,它是响应式的,

      • 在state事先声明的变量是响应式的

      • 后续添加的属性,就不是响应式的,

      • 解决办法:

        • 和数组类似,

        • //vue.set(要修改的对象,属性,修改的值)
          // 添加或修改代码示例 
          Vue.set(staet.info,"address",'武汉')
          // 这个操作回将变量添加到 观察者中
          // 删除代码示例
            Vue.delete(state, 'name');
          
        • 这样的操作,不仅操作l数据,还将关联响应式,直接添加删除,会没有响应式

    mutations

    • mutations是操作state数据的方法的集合,比如对该数据的修改、增加、删除等等。

    • 使用方法

      • mutations方法都有默认的形参:([state], [payload])

        • state:是当前Vuex对象中的state
        • payload:是该方法在被调用时传递参数使用的
    • 带参数的使用代码示例

      • 普通字符传形式提交
      // 单个值提交,(多个值传递,直接放在对象中即可)
      methods: {
          add(){
              this.$store.commit('edit', 13);
          }
      },
          
          
      // 这样在我们的mutation方法中就可以通过payload得到传过来的 13
      mutations: {
          edit(state, payload){
              console.log('payload', payload); // 13
              state.name = '学习vuex';
          }
      }
      
      • 对象形式提交
      this.$store.commit({
          type: 'edit',
          user: 'lazy_tomato',
          age:18
      })
      
      mutations: {
          edit(state, payload){
              console.log('payload', payload);
              // {
              //   type: 'edit',
              //   user: 'lazy_tomato',
              //   age:18
              // }
              state.name = payload.user;
          }
      }
      
      
      

    Actions

    • actionsmutations的区别其实在于,我们一般使用mutations做同步操作,异步操作我们都会写在actions里面,因为在mutations做异步操作,我们的调试工具和视图无法直接同步,会受到约束限制,但是我们actions就没有这种约束/
    • 简单说,就是为了将异步操作和非异步操作分离开,我们使用actions就是来进行异步操作的,让你的代码逻辑更加清晰.
    • 用法示例
    // 调用使用 dispatch
    this.$store.dispatch('incrementAsync');
    
    
    mutations: {
            addNum(state){
                state.num++;
            }
        },
        actions: {
            addNum(context){
                context.commit('addNum');
            },
            incrementAsync ({ commit }) {
              setTimeout(() => {
                commit('addNum')
            }, 1000)
         }
     }
    
    
    
    • 比较重要的几点有关于action

      1. 异步操作,应该放在action中运行。
      2. Action 提交的是 mutation,而不是直接变更状态。
      3. 使用this.store.dispatch,它可以直接返回一个promise对象,只需action中return即可。

    Getters (类似于计算属性)

    • getters可以对state中的成员加工后传递给外界

    • 使用方法

      • getter中的方法有两个默认参数

        • state:当前vuex对象中的状态对象
        • getters:当前getters对象,用于将getters下的其他getter拿来使用
    • 定义使用

      getters: {
          nameInfo(state){
              return `姓名:${state.name}`;
          },
           fullname(state, getters){
               // getters.nameInfo:表示将getters这个对象下面的nameInfo这个getter拿来使用
               return `${getters.nameInfo},年龄:${state.age}`;
            }
      },
      
    • 调用

      <h1>{{ $store.getters.fullname }}</h1>
      
    • 给Getter传参

      • 定义一个getter 直接返回一个函数,即可。

      • // 定义  
        // say(status) {
        //     return function a(X) {
        //         return status.number + X
        //     }
        // }
        
        // 转成箭头函数
           say:status =>{
                return  (X)=> {
                    return status.number + X
                }
           }
        
        
      • <!-- 使用 -->
        <h1>{{ $store.getters.say("后缀1")}}</h1>
        

    modules

    • Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 statemutationactiongetter、甚至是嵌套子模块——从上至下进行同样方式的分割

    • 注册module

      const moduleA = {
        state: { ... },
        mutations: { ... },
        actions: { ... },
        getters: { ... }
      }
      
      const moduleB = {
        state: { 
           demo: 'demo'
        },
        mutations: { ... },
        actions: { ... }
      }
      
      const store = new Vuex.Store({
        modules: {
          a: moduleA,
          b: moduleB
        }
      })
        
      export default store
      
    • 页面获取

      store.state.a // -> moduleA 的状态
      store.state.b // -> moduleB 的状态
      
      <h1>{{ $store.state.b.demo }}</h1>
      
    • 我们可以把我们之前写的改写成模块

      import Vue from 'vue'
      import Vuex from 'vuex'
      
      // 挂载vuex
      Vue.use(Vuex)
      
      const moduleA = {
          state: {
              // 存放的键值对就是所要管理的状态
              name:  `litian`,
              num: 0
          },
          getters: {
              nameInfo(state){
                  return `姓名:${state.name}`;
              },
              fullname(state, getters){
                  // getters.nameInfo:表示将getters这个对象下面的nameInfo这个getter拿来使用
                  return `${getters.nameInfo},年龄:${state.age}`;
              }
          },
          mutations: {
              // 没有传递参数的情况
              edit(state, payload){
                  console.log('payload', payload);
                  state.name = '学习vuex';
                  Vue.set(state, 'age', 18);
                  // Vue.delete(state, 'name');
              },
              addNum(state){
                  state.num++;
                  /* setTimeout(() => {
                      state.num++;
                  }, 1000); */
              }
          },
          actions: {
              addNum(context){
                  context.commit('addNum');
              },
              incrementAsync ({ commit }) {
                  setTimeout(() => {
                    commit('addNum')
                  }, 1000)
              }
          }
      }
      
      const moduleB = {
          state: {
              demo: 'demo'
          }
      }
      
      const store = new Vuex.Store({
          modules: {
              a: moduleA,
              b: moduleB
          }
      });
      
      export default store
      
    • 页面代码

      <template>
        <div id="app">
      
            <!-- <h1>{{ $store.state.name }}</h1>
            <h1>{{ $store.getters.fullname }}</h1> -->
            <h1>{{ $store.state.b.demo }}</h1>
            <h1>{{ $store.state.a.num }}</h1>
            <button @click="add">click</button>
        </div>
      </template>
      
      <script>
        
        export default {
            name: "App",
            data() {
                return {
                    
                };
            },
            methods: {
                add(){
                    /* this.$store.commit('edit', {
                        age: 18,
                        sex: '女'
                    }); */
                    /* this.$store.commit({
                        type: 'edit',
                        user: {
                            age: 18,
                            sex: '女'
                        }
                    }) */
                    this.$store.commit('addNum');
                    // this.$store.dispatch('addNum');
                    // this.$store.dispatch('incrementAsync');
                    // console.log(this.$store.state.name);
                }
            },
        };
      </script>
      

    相关文章

      网友评论

          本文标题:Vuex 学习笔记

          本文链接:https://www.haomeiwen.com/subject/pktooktx.html