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

1.vuex的优缺点

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

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

2..vuex的使用

先上目录结构:

image
image.gif

state.js

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

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

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';
image.gif

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;
    }
}
image.gif

要改变数据时直接用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')
image.gif

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);
        })
      });
    }
}
image.gif

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

对应的在组件内调用方法

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

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

getters.js

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

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

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
   }
});
image.gif

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

mod1.js

export default {
    state:{},
    mutations:{},
    actions:{},
    getters:{}
}
image.gif

mod2.js也是如此

那么如何调用呢?

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

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

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

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

3.vuex的注意点

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • vuex 场景重现:一个用户在注册页面注册了手机号码,跳转到登录页面也想拿到这个手机号码,你可以通过vue的组件化...
    sunny519111阅读 8,008评论 4 111
  • 系列文章:Vue 2.0 升(cai)级(keng)之旅Vuex — The core of Vue applic...
    6ed7563919d4阅读 4,541评论 2 58
  • Vuex是什么? Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件...
    萧玄辞阅读 3,106评论 0 6
  • 安装 npm npm install vuex --save 在一个模块化的打包系统中,您必须显式地通过Vue.u...
    萧玄辞阅读 2,926评论 0 7
  • vuex是一个状态管理模式,通过用户的actions触发事件,然后通过mutations去更改数据(你也可以说状态...
    Ming_Hu阅读 2,016评论 3 3