美文网首页
Vuex的学习

Vuex的学习

作者: 小本YuDL | 来源:发表于2019-09-27 22:58 被阅读0次

    终于又开始学习了!
    最近有点瞎忙,哎!


    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
    状态管理,就是管理的全局变量。
    它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    1. vuex的使用场景是什么呢?
    • 一般来讲,小的单页面应用开发程序不适合使用Vuex,因为还是有点繁琐的。所以,vuex还是比较适合比较大型的单页面应用程序的开发。
    • 使用场景,就是全局的变量管理,比如登录的token,以及一些用户信息什么的,很多地方都会使用到,就比较适合全局管理。
    • 官方解释:
      • 多个视图依赖于同一状态(例如兄弟组件传值)。
      • 来自不同视图的行为需要变更同一状态(例如父子组件传值)。
    • 还有其他的使用的时候有体会再总结吧!

    下面开始介绍怎么使用吧
    (就不从基础的开始介绍了吧,直接将store单独抽离出来一个文件开始吧)


    使用vue-cli搭建的项目目录结构

    可以看出store文件下面有新建了几个js文件,是什么意思呢?

    • index.js 是总的状态管理文件
    • app.js/ user.js 是分模块的状态管理
    • mutation-types.js 是常量集合文件

    相当于流程:
    index.js文件里导入 app.js/user.js等不同模块,再将这一系列的模块挂载到store对象中。再在 main.js文件里导入 store文件,就可以全局管理了,这样也使状态管理更加清晰。

    2. vuex的开始与核心概念:
    • 首先创建一个store对象
    const store = new Vuex.Store({
      state: {
         count:0
      },
      getters:{
         myCount(state){
              return `当前数字是:${state.count}`
          }
      },
      mutations: { 
         increment(state){ 
            state.count += 1;
          }  
      },
      actions:{
          myIncrease(context){
            context.commit(increment)
          }
      }
    })
    
    

    可以看出去这个对象包含了四个属性,分别是干什么的呢?

    • state:就是需要全局管理的状态,一般通过this.$store.state.变量名来获取其值,一般写在computed计算属性中。
      即在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。

    • getters: 就是对全局的状态做个处理,比如过滤等操作,可认为是state的计算属性,一般写在computed 计算属性中。
      getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
      一般通过this.$store.getters.方法名来调用其中的方法,getters 接受 state 作为其第一个参数

    • mutations: 改变全局状态的操作(唯一方法),一般写在methods中。
      记住:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,它会接受 state 作为第一个参数。
      一般通过this.commit('increment')来调用mutations中的方法

    • actions: 改变状态的复杂业务逻辑,一般写在methods中。
      action提交的是 mutation,而不是直接变更状态。
      action可以包含任意异步操作
      action 函数接受一个与 store 实例具有相同方法和属性的 context对象,可以调用 context.commit 提交一个 mutation,也可通过 context.statecontext.getters 来获取 state 和 getters。

    其实取值可以使用官方文档的辅助函数mapState,mapGetters,mapMutations,mapActions,操作更加简单。


    前面的这些 自己总结加上官方的说法,理解之后再看下面的操作,建议去看官方文档

    3. store文件分模块抽离

    直接上文件内容分析(计算器为例):

    index.js :总的模块整合,导入到store对象上

    • 记住要先引入vue和vuex
    • 再引入分离的模块
    • 最后将分离的模块统一引入sotre对象中,通过modules属性
    import Vuex from "vuex";
    import Vue from "vue";
    //引入 分离的模块
    import app from './app';
    import user from './user';
    Vue.use(Vuex);
    // 分模块管理
    const store = new Vuex.Store({
      modules:{
        app,
        user
      }
    
    });
    export default store
    

    下面看看分离的app.js文件,单独写某个模块的全局状态管理(user.js同)

    • 可看出创建了一个app对象,里面包含了store的四个属性,为了可以直接引入到store对象中。
    • 里面还引入了mutation-types文件,也就是将变量名替换成常量名。因为方法名在组件中使用时,要写成字符串格式,不太方便。
    • mutations和actions属性包含的方法,除了接收的固定参数,也可接收传参
    常量集合里面获取的名字  进行 替换调用字符串的名字
    import {Increment,Decrement} from './mutation-types';
    const app = {
      state:{
        count:0
      },
      getters:{
        myCount(state){
          return `当前数字是:${state.count}`
        }
      },
      mutations:{
        方括号 引入常量代表的变量方法名
        [Increment](state,n){  方法都可传参
          state.count += n;
        },
        [Decrement](state,n){
          state.count -= n;
        }
      },
      actions:{
        myIncrease(context,obj){
          context.commit(Increment,2);方法可传参
        },
        myDecrease(context){
          context.commit(Decrement,2);
        }
      }
    };
    export default app
    
    

    在index.js文件中导入了app.js,再在store对象中引入app模块,相当于整个状态管理全部集中在index.js文件,所以要全局使用的话,还需要将store对象引入到 main.js文件中,并挂载到Vue实例上

    main.js文件

    import Vue from 'vue'
    import Vuex from 'vuex'
    import App from './App'
    import router from './router'
    import store from './store'
    Vue.config.productionTip = false;
    Vue.use(Vuex);
    new Vue({
      el: '#app',
      components: { App },
      template: '<App/>',
      router,
      store,
    });
    
    

    最后看下,常量集合文件mutation-types.js,就是将全局的变量名,可以统一命名成常量名。导入这个文件,则名字就可以全局规范,提高代码的可读性

    例如规范了 两个函数的名字
    export const Increment= "increment";
    export const Decrement= "decrement";
    
    

    4.组件中具体使用 (计数器)
    • 可看出使用了辅助函数mapState,mapGetters,mapMutations,mapActions,使用es6的扩展运算符,直接展开数组,每个属性都有一个辅助函数。
    • 导入了 mutation-types,常量集合文件,引用时可以不用字符串
      ...mapMutations([Increment,Decrement]) 使用写法
      ...mapActions(['myIncrease','myDecrease']) 未使用写法
    • 注释部分,调用store中mutation中的方法,改变全局状态,其实实现的功能是一样的:
      • 方法(1):this.$store.commit('increment');
      • 方法(2):映射store中的方法,并直接调用(推荐)
        import {mapMutations} from 'vuex';
        this.increment();
      • 方法(3):this.$store.state.count += 1;
        直接修改 state 里面的值 ,但不会产生mutation的记录(不推荐)
      • 方法(4):在actions中调用mutations中改变状态的方法,然后在组件中可直接调用actions中的方法:
        先在store中action 调用:increase(context){ context.commit(Increment,2); }
        再在组件中调用: this.myIncrease()
    • state 分模块管理之后 得写映射 (注意写法,此时是 state.app.变量名)
      ...mapState({ count:state =>{ return state.app.count } })
    <template>
      <div id="app">
        <h1>{{count}}</h1>
        <h3>{{myCount}}</h3>
        <button @click="increase">增加</button>
        <button @click="decrease">减少</button>
        <router-view/>
      </div>
    </template>
    
    <script>
    import {mapState} from "vuex";
    import {mapGetters} from 'vuex';
    import {mapMutations} from 'vuex';
    import {mapActions} from 'vuex';
    import {Increment,Decrement} from '@/store/mutation-types'
    
    export default {
      name: 'App',
      computed:{
        1.分类管理之前
         ...mapState(['count']), //展开数组
         ...mapGetters(['myCount']),
    
        2.state 分模块管理之后 得写映射 
        ...mapState({
            count:state =>{
              return state.app.count
           }
        })
      },
      methods:{
        //...mapMutations(['increment','decrement']),
        ...mapMutations([Increment,Decrement]),
        ...mapActions(['myIncrease','myDecrease']),
        increase(){
          // this.$store.commit('increment');
          // this.increment();
          //直接修改 state 里面的值   不会产生mutation的记录
          // this.$store.state.count += 1;
          this.myIncrease({id:123});  // 可传参
        },
        decrease(){
          // this.decrement();
          this.myDecrease()
        }
      }
    }
    }
    </script>
    
    

    最后看下效果,也感受一下,全局状态管理的舒服感,始终要记得:** Vuex 的 store 中的状态的唯一方法是提交 mutation**,所以官方提供的浏览器插件Vue,就可清晰的记录每次mutation的结果。


    每次加2,减少2,四次加,两次减
    mutation记录了每次的操作

    这就是最终的结果了,看视频学的,也看了一些官方文档,因为写项目的时候还没学这些,所以那些需要全局使用的信息,都存在了 localStorage中,这也是个方法,但是数据也不能存储太多,操作起来也不是太方便。
    学了vuex也比较浅显,也没实际的在项目中使用过,也不太能体会它的优点,反而感觉有点繁琐,也许真正的使用了,才能体会到它的好处吧。

    学无止境,苦海无涯!
    今天的学习到此结束,下次不知道啥时候见了。

    相关文章

      网友评论

          本文标题:Vuex的学习

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