vue版本: 2.5.2
首先说一下Vuex是什么:
官方定义Vuex:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。更多内容前往vue中文文档
它的应用场景是:
1.多个视图依赖于同一状态。
2.来自不同视图的行为需要变更同一状态。
简单点理解它就是一个存储仓库,存储着多个视图(或组件)共用的数据(或状态),并且多个视图共同维护并使用该数据。

1.安装vuex

在package.json中定义引入vuex

    "vuex": "^3.0.1",

$ npm install安装

2.定义vuex实例

在src目录下store目录中新建index.js文件
在文件中导入vue, vuex等, 并让vue引用vuex

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
  strict: true,
  modules: {
    user
  },
  getters
})
export default store

3.导入store

vue项目入口文件main.js中导入store并将其传入vue实例

import store from './store'
// ...
new Vue({ // eslint-disable-line
  el: '#app',
  router,
  store,
  i18n,
  template: '<App/>',
  components: { App }
})

4.定义用户角色存储

新建src/store/modules/user.js用于管理与用户相关的值:

import { login} from '@/api/login'
import {
  getToken,
  setToken,
  removeToken,
  getUserInfo,
  setUserInfo
} from '@/utils/auth'

let userAvatar = ''

const user = {
  state: {
    token: getToken(),
    username: '',
    avatar: '',
    roles: ['admin']
  },

  mutations: {
    SET_TOKEN: (state, token) => {
      state.token = token
    },
    SET_USERNAME: (state, username) => {
      state.username = username
    },
    SET_AVATAR: (state, avatar) => {
      state.avatar = avatar
    },
    SET_ROLES: (state, roles) => {
      state.roles = roles
    }
  },

  actions: {
    // 登录
    Login ({ commit }, userInfo) {
      const params = {
        username: userInfo.username.trim(),
        password: userInfo.password
      }
      return new Promise((resolve, reject) => {
        login(params).then(response => {
          const result = response.result
          userAvatar = (result.img && result.img.indexOf('http') === 0) ? result.img : userAvatar
          setToken(result.token)
          setUserInfo({
            token: result.token,
            username: result.email,
            avatar: userAvatar || './static/avatar.png'
          })
          commit('SET_TOKEN', result.token)
          commit('SET_USERNAME', result.email)
          commit('SET_AVATAR', userAvatar)
          // admin
          commit('SET_ROLES', ['admin'])
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },

    // 前端 退出登录
    FedLogout ({ commit }) {
      return new Promise(resolve => {
        commit('SET_TOKEN', '')
        commit('SET_USERNAME', '')
        commit('SET_AVATAR', '')
        setUserInfo()
        removeToken()
        resolve()
      })
    }
  }
}

export default user

5.自定义指令

新建目录src/directive/permission
在其目录下新建 index.jspermission.js
在permission.js中定义指令核心逻辑

import store from '@/store'

function checkPermission(el, binding) {
  const { value } = binding
  const roles = store.getters && store.getters.roles

  if (value && value instanceof Array) {
    if (value.length > 0) {
      const permissionRoles = value

      const hasPermission = roles.some(role => {
        return permissionRoles.includes(role)
      })

      if (!hasPermission) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    }
  } else {
    throw new Error(`need roles! Like v-permission="['admin','editor']"`)
  }
}

export default {
  inserted(el, binding) {
    checkPermission(el, binding)
  },
  update(el, binding) {
    checkPermission(el, binding)
  }
}

在index.js中以directive的形式导入vue, 并将permission指令导出:

import permission from './permission'

const install = function(Vue) {
  Vue.directive('permission', permission)
}

if (window.Vue) {
  window['permission'] = permission
  Vue.use(install); // eslint-disable-line
}

permission.install = install
export default permission

6.使用自定义的指令与store

导入指令与mapGetters

import { mapGetters } from 'vuex'
import permission from '@/directive/permission/index.js'

在computed中定义要使用的状态值; 在directives中导入自定义的指令

export default {
  computed: {
    // 这样之后roles就变成了一个属性
    ...mapGetters([
      'roles'
    ])
  },
  // 
  directives: { permission },
  mounted () {
    console.log("this.roles", this.roles)
  }
}

这样在模板中可使用自定义指令与状态值:

  <el-card class="box-card">
    Welcome !
    <div v-permission="['admin']">
      超级管理员用户
    </div>

    <div v-permission="['test']">
      测试人员
    </div>

    <div v-permission="['dev']">
      开发人员
    </div>

    <div>角色code:{{roles}}</div>
  </el-card>
Logo

前往低代码交流专区

更多推荐