浅谈vue项目进阶开发-vuex篇

1.vuex的优缺点

        Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式(官方原话)。按本人使用的理解,就是一个全局存储数据的地方,在各个组件中不可以随意地更改这里面的数据,只能通过特定指令去更新数据,但能很方便地在各个组件中取出该数据使用。使用场景:接口请求过来的需要及时显示在页面上的数据(如列表数据 优化用户体验),需要全局调用的数据(如用户信息,登录状态)。对非父子组件传值用vuex是非常有效的。另外对于多人开发,使用vuex去管理数据是非常方便的。能很有效地解耦。以上说地都算是它的优点。

        缺点就是使用起来需要同时操作多处,略显麻烦。所有官方也提出了对于单人开发的小项目不建议去使用。但很适合大型项目开发。另外有一点,刚开始我认为这些数据是存储在localstorage中的。实际上由于vue是单页面应用,它只是建了一个相当于组件内的data一样的全局变量。当我们刷新页面时我们在vuex内存储的数据将不复存在。如果想保存这些数据怎么办呢?很简单用localstorage存储下就可以了。

2..vuex的使用

先上目录结构:

state.js

项目中想要管理的数据和状态都在这

    state: {
    // 企业法院公告详情条数
    courtInfoDetailCount: 0,
    // 企业失信人详情list
    breakManDetail: [],
    // 企业失信人详情list条数
    breakManDetailCount: 0,
    // 企业被执行人详情
    defendantDetail: [],
    // 企业被执行人详情条数
    defendantDetailCount: 0,
    // 首页健康报表
    healthyList: {
      newsList: []
    },

types.js     

连接actions和mutations的桥梁(操作数据的指令)

export const SET_LOGIN_MSG = 'SET_LOGIN_MSG';
export const CONTACTS_LIST = 'CONTACTS_LIST';
export const DEFENDANT_DETAIL = 'DEFENDANT_DETAIL';
export const HOME_NEWS_LIST = 'HOME_NEWS_LIST';
export const HOME_HEALTHY_LIST = 'HOME_HEALTHY_LIST';

 mutations.js

处理数据,操作状态,获取数据都在这,同步去处理数据对应的调用方法 commit

import Vue from 'vue'
import * as types from './types'
export defalut {
    [types.SET_LOGIN_MSG](state, loginMsg) {
      state.loginMsg = loginMsg
    },
    /* ************通讯录************* */
    // 通讯录列表信息
    [types.CONTACTS_LIST](state, param = {}) {
      API.contactsListData(param).then(res => {
        if (res.retCode === 0) {
          let data = res.retData.bookList;
          // 当前用户的认证状态
          // 1未认证 2 待审核/认证中 3 审核中/认证中 4 已认证 5 认证失败
          state.authStatus = res.retData.authStatus || '1';
          if (res.retData.count) {
            state.contactsListCount = Number(res.retData.count);
          } else {
            state.contactsListCount = 0;
          }
          let contactsList = [];
          for (let i = 0; i < data.length; i++) {
            let dataInfo = {};
            // 企业Id
            dataInfo.appId = data[i].appId || '';
            // 通讯录Id
            dataInfo.id = data[i].id || '';
            // 身份类型
            dataInfo.type = data[i].type || '1';
            // 业务类型
            dataInfo.businessType = data[i].businessTypeArr.join(',');
            dataInfo.companyName = data[i].companyName || '';
            // 企业类型
            dataInfo.companyType = data[i].companyTypeArr.join(',');
            dataInfo.contactMobile = data[i].contactMobile || '';
            dataInfo.contactName = data[i].contactName || '未知';
            dataInfo.phyScore = data[i].phyScore || '无';
            // 企业评分颜色
            if (dataInfo.type === '1') {
              if (Number(dataInfo.phyScore) > 85) {
                dataInfo.scoreCol = 'safe_col';
              } else if (Number(dataInfo.phyScore) > 65) {
                dataInfo.scoreCol = 'alert_col';
              } else {
                dataInfo.scoreCol = 'danger_col';
              }
            }
            contactsList.push(dataInfo)
          }
          state.contactsList = contactsList;
        }
      })
    },
    // 通讯录的企业详情
    [types.COMPANY_DETAIL_DATA](state, retData) {
      let data = retData.bookTianYanInfo;
      let companyDetail = {};
      // 是否有企业详情
      companyDetail.isCompanyDetail = (retData.enterpriseShow === 1);
      // 是否已认证
      companyDetail.isAuth = (retData.enterpriseAuthStatus === 4);
      // 信用代码
      companyDetail.credit_code = data.credit_code;
      // 所属行业
      companyDetail.industry = data.industry || '未公开';
      // 法人代表
      companyDetail.legal_person = data.legal_person || '未公开';
      // 公司名
      companyDetail.name = data.name || '未公开';
      // 公司类型
      companyDetail.ownership = data.ownership || '未公开';
      // 组织机构代码证
      companyDetail.register_number = data.organization_code || '未公开';
      companyDetail.cell_phone = data.phone || '未公开';
      // 注册地址
      companyDetail.register_address = data.register_address || '未公开';
      // 经营地址
      companyDetail.business_address = data.business_address||companyDetail.register_address;
      // 工商注册号
      companyDetail.business_code = data.register_number || '未公开';
      // 注册时间
      companyDetail.setup_date = data.setup_date || '未公开';
      // 营业有效期
      companyDetail.to_time = data.to_time || '未公开';
      // 注册资本
      companyDetail.actual_capital_e2 = data.actual_capital_e2 || '';
      // 实缴资本
      companyDetail.captial_e2 = data.captial_e2 || '';
      state.companyDetailData = companyDetail;
    }
}

要改变数据时直接用this.$store.commit(SET_LOGIN_MSG, loginMsg)即可

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store/store'
import * as API from './common/api'
import http from './common/http'
import './common/elm'
import './assets/iconfont/iconfont.css' // 全局引入阿里字体图标
import {SET_LOGIN_MSG} from './store/mutation-types'
import {K_LOGIN_MSG} from './common/constant'

Vue.prototype.$http = http
Vue.prototype.$api = API
Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App),
  created() {
    // 保存登录信息到store
    let loginMsg = JSON.parse(localStorage.getItem(K_LOGIN_MSG))
    this.$store.commit(SET_LOGIN_MSG, loginMsg || {})
  }
}).$mount('#app')

 actions.js

对于一些接口数据,可能需要在组件内异步得去处理一些事情,这时候就需要写在这里,对应的调用方法是dispatch,需要注意的是:它提交的是mutation,不做数据和状态的更改,这些操作在mutations中处理

import * as types from './types'
export defalut {
      // 通讯录的企业详情
    [types.COMPANY_DETAIL_DATA](context, id) {
      return new Promise((resolve, reject) => {
        API.companyDetailData({id}).then(res => {
          resolve(res);
          if (res.retCode === 0) {
            context.commit(types.COMPANY_DETAIL_DATA, res.retData);
          }
        }).catch(err => {
          reject(err);
        })
      });
    }
}

这里的参数 context 是对象{commit, state},后一个参数是你需要传的数据

对应的在组件内调用方法

this.$store.dispatch(types.COMPANY_DETAIL_DATA,id).then(res=>{
   this.name = this.company.name;
}).catch(err=>{
  console.log(err)
})

 由于是异步得所有可以用promise封装使用,解决callhack

 getters.js

以上方法就可以完成vuex的整个状态管理了,完全没有任何问题。但有时候会有一些需求,比如变量name需要在firstName和lastName其中任何一个发生变化时同时发生变化,如果在组件内我们使用computed就能做到,在vuex需要我们的getters登场

export defalut{
   name(){
     return state.firstName + state.lastName
   }
}

Module

到这就完了吗?并没有。如果是大型项目,你会发现需要使用vuex的数据太多了,然而把所有的数据处理全部放在 mutations.js文件中显得很杂乱,并不利于查找与管理,此时我们就需要Module,分模块管理。怎么做呢?

import vue from 'vue'
import vuex from 'vuex'
import mod1 from './mod1.js'
import mod2 from './mod2.js'
vue.use(vuex);
export default new vuex.Store({
    modules:{
         mod1:mod1,
         mod2:mod2
   }
});

mod1和mod2就是 被分成的两个子模块。因为每个子模块数据和状态不会太多,因此我们把state,mutations,actions,getter写在一个文件中如下

mod1.js

export default {
    state:{},
    mutatons:{},
    actions:{},
    getters:{}
}

mod2.js也是如此

那么如何调用呢?

如果只有一个模块的话只需要 this.$store.state.name;

如果是多个子模块的话需要加上模块名: this.$store.state.mod1.name

更新数据的方法会有所变化吗?依然按照原来的方法使用就行了

总结: 
将store进行拆分,有利于我们更好的管理项目中的状态,以及使我们的项目维护更加加单高效。各个模块之间的开发互相不影响。

3.vuex的注意点

a.在以往我们更新数据时为了防止数据随时变化所以会在更新组件时及时更新数据,甚至每隔一段时间更新数据,有了vuex就无需这么做了,我们只要在我们更改数据时更新一下数据即可。如用户的基本信息,我们只在用户对用户信息进行修改或增加时更新即可,这样在任何组件中使用用户信息时数据都是最新的。

b.使用vuex我们在组件内更改数据是无效的。例如:this.$store.state.name=‘小明‘,这么做会报错。

猜你喜欢

转载自blog.csdn.net/weixin_37693991/article/details/83176829