vue项目页面,按钮权限控制

vue项目页面,按钮权限控制,第1张

基于vue/cli3.0+脚手架搭建Vue项目(15)

文章目录 基于vue/cli3.0+脚手架搭建Vue项目(15)前言一、登录后进入首页或者刷新页面时,从后台接口获取用户权限数据首页请求权限接口 二、权限模块下,菜单栏和按钮的展示1.首页渲染模块2.渲染菜单栏和按钮 总结


前言
一、登录后进入首页或者刷新页面时,从后台接口获取用户权限数据 首页请求权限接口

home页面代码:

<template>
  <div class="content">
    <div class="header" @click="$router.push('/home')">TG</div>
    <div class="homePage" v-if="homePage">
      <div class="modules">
        <span class="module" v-for="item in permissionData" :key="item.id" @click="moduleDetails(item)">
          {{ item.name }}
        </span>
      </div>
    </div>
    <div class="module-content" v-else>
      <div class="sideBar">
        <side-bar
          :sideBar="sideBar"
          :checkedNumber.sync="checkedNumber"
          @jumpModuleDetails="jumpModuleDetails"
        ></side-bar>
      </div>
      <div class="main">
        <router-view></router-view>
      </div>
    </div>
  </div>
</template>
<script>
import sideBar from '@/views/sideBar';
import permissionDictionary from '@/utils/permissionData';
export default {
  components: { sideBar },
  data() {
    return {
      permissionData: [],
      sideBar: {},
      checkedNumber: '',
      flatPermissionData: new Map(),
    };
  },
  computed: {
    homePage() {
      return this.$store.getters.getHomePage;
    },
  },
  watch: {
    $route(val) {
      if (val.fullPath !== '/home') {
        this.flatPermison(this.sideBar.children);
        let tempObj = this.flatPermissionData.get(val.path);
        // 设置选中菜单栏active
        this.setCheckedNumber(tempObj);
      }
    },
  },
  created() {
    this.getPermission();
  },
  methods: {
    moduleDetails(item) {
      if (item.children) {
        this.sideBar = item;
        this.checkedNumber = item.children[0].number;
        this.$router.push(item.path);
      }
    },
    jumpModuleDetails(item) {
      // 设置选中菜单栏active
      this.setCheckedNumber(item);
      this.$router.push(item.path);
    },
    setCheckedNumber(item) {
      if (item.children && item.children.length) {
        let idx = item.children.findIndex(item => item.type === 'page');
        if (idx !== -1) {
          this.checkedNumber = item.children[idx].number;
        } else {
          this.checkedNumber = item.number;
        }
      } else {
        this.checkedNumber = item.number;
      }
    },
    // 路径扁平化
    flatPermison(data) {
      data.forEach(item => {
        this.flatPermissionData.set(item.path, item);
        if (item.children && item.children.length) {
          this.flatPermison(item.children);
        }
      });
    },
    getPermission() {
      setTimeout(() => {
        this.permissionData = permissionDictionary;
        if (this.$route.fullPath !== '/home') {
          // 设置菜单栏
          this.setSideBarData(this.permissionData);
        }
        // 存储权限数据备用
        this.$store.commit('OP_PERMISSION', this.permissionData);
        localStorage.setItem('permissionData', JSON.stringify(this.permissionData));
      }, 500);
    },
    setSideBarData(data) {
      try {
        let url = this.$route.fullPath;
        let leng = data.length;
        if (leng) {
          for (let i = leng - 1; i >= 0; i--) {
            if (data[i].children && data[i].children.length) {
              if (data[i].children.some(item => item.path === url)) {
                this.checkedNumber = data[i].children[0].number;
                this.sideBar = data[i];
              }
            }
          }
        }
      } catch (error) {
        console.log(error);
      }
    },
  },
};
</script>

<style lang="scss" scoped>
//...样式代码
</style>

模拟权限数据,并渲染权限里的模块页面

const permissionDictionary = [
    {
      name: '人员管理',
      id: '01',
      path: '/personnelManagement',
      number: 'personnelManagement',
      children: [
        {
          name: '人员',
          id: '011',
          path: '/personnelManagement/personnel',
          type: 'page',
          number: 'personnelManagement-personnel',
          children: [
            {
              name: '新增',
              id: '0111',
              path: '',
              type: 'button',
              number: 'personnelManagement-personnel-new',
            },
          ],
        },
        {
          name: '绩效管理',
          id: '014',
          path: '/personnelManagement/performance',
          type: 'page',
          number: 'personnelManagement-performance',
        },
        {
          name: '薪酬管理',
          id: '013',
          path: '/personnelManagement/salary/basis',
          type: 'page',
          number: 'personnelManagement-salary',
          children: [
            {
              name: '基础工资',
              id: '0131',
              path: '/personnelManagement/salary/basis',
              type: 'page',
              number: 'personnelManagement-salary-basis',
            },
            {
              name: '提成工资',
              id: '0132',
              path: '/personnelManagement/salary/commission',
              type: 'page',
              number: 'personnelManagement-salary-commission',
            },
          ],
        },
      ],
    },
    {
      name: '客户',
      id: '02',
      path: '/personnelManagement',
      number: 'customer',
    },
    //...其他模块
];
export default permissionDictionary

sideBar页面代码:

<template>
  <div class="sideBar-content">
    <div class="sideBar-content-title">{{ sideBar.name }}</div>
    <div class="sideBar-content-modules">
      <div class="sideBar-content-module" v-for="item in sideBar.children" :key="item.id">
        <template v-if="item.type === 'page'">
          <div class="sideBar-content-module-main" @click="moduleDetails(item)">
            <span :class="checkedNumber === item.number ? 'is-active' : ''">{{ item.name }} </span>
          </div>
        </template>
        <div v-for="(subItem, index) in item.children" :key="subItem.id" @click="moduleDetails(subItem)">
          <template v-if="subItem.type === 'page'">
            <div
              class="sideBar-content-module-sub"
              :class="item.children.length - 1 === index ? 'sideBar-content-module-sub-last' : ''"
            >
              <span :class="checkedNumber === subItem.number ? 'is-active' : ''">{{ subItem.name }} </span>
            </div>
          </template>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    sideBar: {
      type: Object,
      default: {},
    },
    checkedNumber: {
      type: String,
      default: '',
    },
  },
  methods: {
    moduleDetails(item) {
      this.$emit('jumpModuleDetails', item);
    },
  },
};
</script>
<style lang="scss" scoped>
//...样式代码
</style>

router代码(用home嵌套各模块路由(routers),token没过期继续next(),过期则跳转到login页面):

import Vue from 'vue';
import VueRouter from 'vue-router';
import routers from './importModel';
import store from '@/store/index';

Vue.use(VueRouter);
const router = new VueRouter({
  routes: [
    {
      path: '/',
      redirect: "/home"
    },
    {
      name: 'login',
      path: '/login',
      component: () => import('@/views/login.vue'),
    },
    {
      name: 'home',
      path: '/home',
      component: () => import('@/views/home'),
      children: [
        ...routers
      ]
    }
  ]
});

router.beforeEach((to, from, next) => {
  store.commit('OP_HOMEPAGE', to.path.includes('home'))
  if (localStorage.getItem('TOKEN') &&localStorage.getItem('UUID')) {
    cacheCookie();
    next();
  }else {
    if(to.path ==='/login'){
      next();
    } else {
      next('/login');
    }
  }
});

function cacheCookie() {
  // 将localStorage里的token信息缓存在vuex
  store.commit('OP_TOKEN', localStorage.getItem('TOKEN'));
  store.commit('OP_UUID', localStorage.getItem('UUID'));
}

const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

export default router;

人员管理模块为例,路由代码:

const personnelManagement = [
    {
      name: 'personnelManagement',
      path: '/personnelManagement',
      redirect: '/personnelManagement/personnel',
    },
    {
      name: 'personnel',
      path: '/personnelManagement/personnel',
      component: () => import('@/views/personnelManagement/personnel'),
    },
    {
      name: 'salary',
      path: '/personnelManagement/salary',
      component: () => import('@/views/personnelManagement/salary'),
    },
    //...模块下其他路由
  ];
  export default personnelManagement;

人员页面放置按钮(此时会根据权限来渲染新增按钮, 而不是将页面里的新增导出都渲染出来):

<template>
  <div class="personnel">
    <div class="btn">
      <el-button v-for="item in btnArray" :key="item.number">
        {{ item.name }}
      </el-button>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      btn: [
        {
          name: '新增',
          number: 'personnelManagement-personnel-new',
          type: 'button',
        },
        {
          name: '导出',
          number: 'personnelManagement-personnel-export',
          type: 'button',
        },
      ],
      flatPermissionData: new Map(),
    };
  },
  computed: {
    btnArray() {
      let getPermissionData = this.$store.getters.getPermissionData;
      this.flatPermison(getPermissionData);
      if (this.flatPermissionData.size) {
        let leng = this.btn.length;
        for (let i = leng - 1; i >= 0; i--) {
          if (!this.flatPermissionData.has(this.btn[i].number)) {
            this.btn.splice(i, 1);
          }
        }
        return this.btn;
      }
      return [];
    },
  },
  methods: {
    // number扁平化
    flatPermison(data) {
      data.forEach(item => {
        this.flatPermissionData.set(item.number, item);
        if (item.children && item.children.length) {
          this.flatPermison(item.children);
        }
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.personnel {
  padding: 20px;
}
</style>
二、权限模块下,菜单栏和按钮的展示 1.首页渲染模块

2.渲染菜单栏和按钮


项目已重新打包,可访问网站:http://47.106.123.118:8080/#/,获取登录页面账号和密码可查看之前文章:vue项目axios的封装和使用


总结

晚安

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/940208.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-17
下一篇2022-05-17

发表评论

登录后才能评论

评论列表(0条)

    保存