Vue.js快速入门之二:使用状态管理工具Vuex

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

什么情况下会使用到Vuex:比如登录的用户信息,接口的统一访问令牌等,会频繁使用和全站通用的数据,可以寄存在状态管理器中。

一、vuex安装

//输入命令
npm install --save vuex@3

二、store仓库创建

首先在src目录中创建以上文件。

2.1 state.js文件

        state.js是用来定义状态管理器的变量,遵循vue中data相同的规则。代码如下:

const state = {
  //记录用户信息
  userinfo: {},
  //记录接口访问令牌
  token: ""
};
export default state;

2.2 getters.js文件

        getters.js是从store的state中派生出一些状态,对其进行过滤并计数。从字面上就能看出来,是“获取”的意思,所以一般获取状态管理器中变量值和计算,是通过getters来完成的。代码如下:

const getters = {
  get_userinfo(state){
    return state.userinfo
  },
  get_token(state){
    return state.token
  }
};
export  default getters;

        同时在getters中,也可以对数据进行再加工处理,代码如下:

export default new Vuex.Store({
  state: {
    menu: [
      {"id": 1, "name": "菜单一", "pid": 0},
      {"id": 2, "name": "菜单二", "pid": 0},
      {"id": 3, "name": "菜单三", "pid": 2},
      {"id": 4, "name": "菜单四", "pid": 1}
    ]
  },
  getters: {
    get_menu(state){
      //返回父ID为0的菜单
      return state.menu.filter(item => item.pid==0);
    }
  }
});

2.3 mutationsType.js文件

        将mutations中再派生出一个type类型文件,用于记录命令常量值。这些常量后期会在mutations和actions中用到。代码如下:

/**
 * 用户信息
 * @type {string}
 */
export const CHANGE_USERINFO = "CHANGE_USERINFO";

/**
 * 访问令牌
 * @type {string}
 */
export const CHANGE_TOKEN = "CHANGE_TOKEN";

2.4 mutations.js文件

        更新Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutations字面意思是裂变,这里理解为对状态管理器state中变量进行“更新”,它是一个修改变量值的事件,第一个参数接收的是state对象。代码如下:

//引入派生出的mutationsType文件
import { CHANGE_USERINFO, CHANGE_TOKEN } from './mutationsType'

const mutations = {
  //修改用户信息
  [CHANGE_USERINFO](state, param){
    state.userinfo = param;
  },
  //修改访问令牌
  [CHANGE_TOKEN](state, param){
    state.token = param;
  }
};
export default mutations;

2.5 actions.js文件

        action类似于mutation,但mutation是同步无异步事件,action是异步事件;而且actions提交的是mutation,而不能直接变更状态;actions中可以包含任意异步操作。代码如下:

//引入派生出的mutationsType文件
import { CHANGE_USERINFO, CHANGE_TOKEN } from './mutationsType'

const actions = {
  //修改登录状态信息
  changeLoginInfo({commit}, param){
    if('undefined'!==typeof param['userinfo']){
      commit(CHANGE_USERINFO, param.userinfo);
    }
    if('undefined'!==typeof param['token']){
      commit(CHANGE_TOKEN, param.token);
    }
  }
};
export default actions;

        为什么要使用action呢,个人理解的vuex,是每个担任角色不同,分工也不同而已。

  • state是个仓库的功能,如存储在里面的货物(变量);
  • getter负责运输的大队长,将货物通过运输工具运到指定位置;同时下面有很多专职司机,每个司机运输货物类别不同,此时则具备货物筛选过滤的功能;如A司机运输是陕西的苹果,B司机运输是山东的苹果,虽然都是苹果,但运输货物种类不同。
  • mutation像是一个仓库管理员,等待指令修改货物数量和状态;
  • action负责业务层,处理异步请求和任务分发工作。
  • mutationsType是派生出的一个指令包,action和mutation通过mutationsType指令表进行下发任务和执行功能。

        通过以上分解,希望能帮助刚开始着手使用vuex的同学们,更好理解和使用。

2.6 Modules目录

        由于使用单一的状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就会变的非常臃肿。

        为了解决这一问题,增加了分割模块(module),每个模块有自己的state、getter、mutation、action。这个很好理解,除总部以外,在全国有34个省级和行政区,每个地方设置一个仓库,每个仓库有自己的仓管、运输队长、业务经理。这样就很好分解了总部的压力,将各地区具体业务进行下放处理。

2.7 index.js文件

        此时,我们将所有业务进行汇总,通过index.js将vuex注入到vue中。代码如下:

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import getters from './getters'
import actions from './actions'
import mutations from './mutations'
import mutationsType from './mutationsType'

Vue.use(vuex);
//导入module目录中所有文件
const modulesFiles = require.context('./Modules', true, /\.js$/);
//自动加载Modules目录文件中所有vuex模块
const modules = modulesFiles.keys().reduce((module, modulePath) => {
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
  const value = modulesFiles(modulePath);
  module[moduleName] = value.default;
  return module;
}, {});
export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations,
  modules
});

三、main.js中引入

        引入store中的index.js文件,将vuex注入到vue中。代码如下:

import Vue from 'vue'
import App from './App'
import router from './router'
import store from '@/store'

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
});

四、如何使用vuex

4.1 通过store调取

        在main.js引入中,已经将引入的store注入到了Vue中,这时我们可以直接通过this.$store来执行相关指令了。

        1)this.$store.commit使用,有时公司会绕过业务经理,直接给仓管下达调货指令,则可以使用此方法。代码如下:

import { CHANGE_USERINFO } from '@/store/mutationsType'
export default {
  data () {
    return {}
  },
  created(){
    //修改用户信息信息
    this.$store.commit(CHANGE_USERINFO, {
      name: 'tom'
    });
  }
}

        Vuex状态管理器中,userinfo值已被修改,如下图:

        2)this.$store.getters使用,获取对应状态信息。代码如下:

export default {
  data () {
    return {}
  },
  created(){
    console.log(this.$store.getters.get_userinfo);
  }
}

        控制台输入结果如下图:

        3)this.$store.dispatch分发事件,不难理解,dispatch就是给action业务进行任务分发事件。代码如下:

export default {
  data () {
    return {}
  },
  created(){
    //修改用户信息和访问令牌
    this.$store.dispatch('changeLoginInfo', {
      userinfo: { name: 'Lily' },
      token: 'asfkllk13asdfkl92lka'
    })
  }
}

        此时,用户信息和访问令牌的状态值,已通过action进行指令下发并被修改。如下图:

4.2 通过map调取

        1)mapGetters,通过computed完成getters数据导入,代码如下:

import { mapGetters } from 'vuex';
export default {
  data () {
    return {}
  },
  computed: {
    ...mapGetters(['get_token'])
  },
  created(){
    console.log(this.get_token);
  }
}

        控制台输出如下图:

        2)mapActions,通过methods完成action业务功能函数导入,代码如下:

import { mapActions } from 'vuex';
export default {
  data () {
    return {}
  },
  methods: {
    ...mapActions(['changeLoginInfo'])
  },
  created(){
    //修改用户信息
    this.changeLoginInfo({
      userinfo: { name: "Lily" },
      token: "asdfjkljkasdfijiosda21l20adfj"
    })
  }
}

        此时,用户信息和访问令牌的状态值,也通过action进行指令下发并被修改,如下图:

         3)mapMutations,通过methods完成mutation事件函数导入,代码如下:

import { mapMutations } from 'vuex';
import { CHANGE_TOKEN } from '@/store/mutationsType'
export default {
  data () {
    return {}
  },
  methods: {
    ...mapMutations([CHANGE_TOKEN])
  },
  created(){
    this[CHANGE_TOKEN]('新token信息');
  }
}

        Vuex状态管理器中,这时同样已被修改,如下图:

        4)mapState,通过computed完成state状态导入。当一个组件需要更多的状态时,将为些状态都声明为计算属性会显的重复和冗余,为了解决这问题,可以使用mapState辅助函数完成生成计算属性,代码如下:

import { mapState } from 'vuex';
export default {
  data () {
    return {}
  },
  created(){
    console.log('username:', this.username);
  },
  computed: {
    ...mapState({
      username: state => state.userinfo.name
    })
  }
}

        此时控制台输出如下图:

就此,目前大家项目中常用到的几种方法事件讲完了。有不足之处,欢迎指点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值