vuex在项目中的使用

1、在项目目录下建立store目录,store目录下家里index.js文件,在index.js文件中安装vuex,且注册store仓库等相关的插件

 这是index.js代码

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex)

// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const store = new Vuex.Store({
  plugins: [
    createPersistedState({
      storage: window.sessionStorage, //这里是将state中的user对象存放在浏览器本地存储中
      reducer(val) {
        return {
        // 只储存state中的user
          user: val.user
        }
      }

    })
  ],
  modules,
  getters
})

export default store

2、因为项目可能页面多较复杂,所以state和mutations,actions等不能写在同一个文件下,这个时候可以利用modules来区分开来,使用起来更加的简洁明了

这是getters代码

const getters = {
  sidebar: state => state.app.sidebar,
  language: state => state.app.language,
  size: state => state.app.size,
  device: state => state.app.device,
  visitedViews: state => state.tagsView.visitedViews,
  cachedViews: state => state.tagsView.cachedViews,
  token: state => state.user.token,
  avatar: state => state.user.avatar,
  name: state => state.user.name,
  introduction: state => state.user.introduction,
  roles: state => state.user.roles,
  user: state => state.user.user,
  permission_routes: state => state.permission.routes,
  errorLogs: state => state.errorLog.logs,
  baseApi: state => state.api.baseApi,
  dictionary: state => state.user.dictionary,
  updateAvatarApi: state => state.api.updateAvatarApi
}
export default getters

这是user.js代码

import { getInfo, login, logout } from '@/api/auth' //这里是登录接口
import { getToken, removeToken, setToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'
import { getDictionary, getBasePort } from '@/api/commonApi' //这里是调用的后台接口,数据字典

const state = {
  count: 0,
  userId: 1234,
  token: getToken(),
  name: '',
  avatar: '',
  introduction: '',
  roles: [],
  user: {},
  loadMenus: false,
  dictionary: {}
}

// const user = {
//   state: {
//     token: getToken(),
//     user: {},
//     roles: [],
//     // 第一次加载菜单时用到
//     loadMenus: false
//   }
// }

const mutations = {
  ADD_COUNT: (state, amount) => {
    if (amount) {
      state.count = 0
      return
    }
    state.count++
  },
  SET_DICTIONARY: (state, data) => {
    state.dictionary = { ...state.dictionary, ...data }
  },
  SET_USERINFO: (state, data) => {
    state.user = data
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_INTRODUCTION: (state, introduction) => {
    state.introduction = introduction
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_ROLES: (state, roles) => {
    state.roles = roles
  },
  SET_LOAD_MENUS: (state, loadMenus) => {
    state.loadMenus = loadMenus
  }
}

const actions = {
  /**
   * 页面初始化,加载数据字典
   */
  loadDitionary({ commit, state }, code) {
    return new Promise((resolve, reject) => {
      const params = 'ship status,biz status,purpose,fixtrue status,emailAnalyCode,Fixture Rate Unit,vessel service status,voyage type,voyage status' +
      ',sailing record type,loadStatus,vessel history type,loadarea,disloadarea,ship ais status,positionStatus,Freight Index,Bunker Index,Group Type' +
      ',consumption type,dataStatus,fence type,loadStatus,S&P Fixture Type,Analysis Series'
      getDictionary(params).then(e => {
        commit('SET_DICTIONARY', e.data)
        resolve(true)
      }).catch(error => {
        reject(error)
      })
      getBasePort().then(res => {
        if (res.data) {
          const data = res.data.map(item => {
            return { name: item.name, code: item.code }
          })
          commit('SET_DICTIONARY', { 'load area': data, 'load area detail': res.data })
          resolve(true)
        }
      })
    })
  },
  // user login
  login({ commit }, userInfo) {
    const { username, password, code, uuid } = userInfo
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password, code, uuid }).then(response => {
        const { data } = response
        commit('SET_TOKEN', data.token)
        setToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // get user info
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token).then(response => {
        const { data } = response
        if (!data) {
          reject('Verification failed, please Login again.')
        }
        const { roles, user } = data
        // roles must be a non-empty array
        if (!roles || roles.length <= 0) {
          reject('getInfo: roles must be a non-null array!')
        }
        commit('SET_USERINFO', user)
        commit('SET_ROLES', roles)
        // commit('SET_NAME', name)
        // commit('SET_AVATAR', avatar)
        // commit('SET_INTRODUCTION', introduction)
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  updateLoadMenus({ commit }) {
    return new Promise((resolve, reject) => {
      commit('SET_LOAD_MENUS', true)
    })
  },
  // user logout
  logout({ commit, state, dispatch }) {
    return new Promise((resolve, reject) => {
      logout(state.token).then(() => {
        commit('SET_TOKEN', '')
        commit('SET_ROLES', [])
        removeToken()
        resetRouter()

        // reset visited views and cached views
        // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
        dispatch('tagsView/delAllViews', null, { root: true })

        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // remove token
  resetToken({ commit }) {
    return new Promise(resolve => {
      commit('SET_TOKEN', '')
      commit('SET_ROLES', [])
      removeToken()
      resolve()
    })
  },

  // dynamically modify permissions
  changeRoles({ commit, dispatch }, role) {
    return new Promise(async resolve => {
      const { roles } = await dispatch('getInfo')

      resetRouter()

      // generate accessible routes map based on roles
      const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })

      // dynamically add accessible routes
      router.addRoutes(accessRoutes)

      // reset visited views and cached views
      dispatch('tagsView/delAllViews', null, { root: true })

      resolve()
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

modules中的其他js同user.js类似,分别用作不同的模块

3、页面中的使用用例

<template>
  <div>
    <el-button @click="Add">Add</el-button>
    <div>{{ userId }}</div>
    <div>{{ count }}</div>
    <!-- 一个按钮,点击一次count变量加一,userId是直接获取store中的state状态 -->
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex' // mapState  mapMutations 是vuex的两个辅助函数,还有mapGetters等
import store from '@/store'
export default {
  computed: mapState({
    // Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。
    // 就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
    userId: state => store.getters.user.gender, // 这里在index.js中可以看到在浏览器临时存储了user.js的state状态
    count: state => state.user.count // 直接获取store中user分支下的count状态
  }),
  methods: {
    Add() {
      if (store.state.user.count > 9) {
        store.commit('user/ADD_COUNT', true)
      } else {
        store.commit('user/ADD_COUNT')
      }
    },
    // 这里使用的是mapMutations辅助函数,映射了el-button的点击事件
    // ...mapMutations([
    //   'user/ADD_COUNT'
    // ])
    //mapMutations辅助函数的第二种方式
    ...mapMutations({
      ADD_COUNT: 'user/ADD_COUNT'
    })
  }
}
</script>

<style lang='scss' scoped>

</style>

注意:mutations并不是只能使用同步操作,但是官方特意说明,只能使用同步操作,因为是为了代码的维护,具体可以查看vue官方文档,如果有任何的异步操作请使用actions,去操作mutation

4、action的触发使用dispatch

this.$store.dispatch('user/loadDitionary')

分发的是user.js中的loadDionnary方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值