Vuex的学习

2019-09-27  本文已影响0人  小本YuDL

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


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

1. vuex的使用场景是什么呢?

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


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

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

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

2. vuex的开始与核心概念:
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)
      }
  }
})

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





其实取值可以使用官方文档的辅助函数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也比较浅显,也没实际的在项目中使用过,也不太能体会它的优点,反而感觉有点繁琐,也许真正的使用了,才能体会到它的好处吧。

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

上一篇下一篇

猜你喜欢

热点阅读