从零开始使用vue2+element搭建后台管理系统(实现按钮权限控制)

发布时间 2023-09-14 14:35:15作者: 芝麻小仙女

思路:登录后请求用户信息接口,后端返回用户信息中包括权限数组,数据格式be like:

 前端对用户信息进行存储(对没错又是假接口):

    // 获取用户信息
    async getUserInfo(mobile) {
      try {
        this.loading = true;
        const res = await getInfo(mobile);
        if (res.code !== 10000)
          this.$message.error(res.msg || "获取用户信息失败!");
        if (res.code === 10000 && res.data) {
          this.$store.commit("user/SET_NAME", res.data.name);
          this.$store.commit("user/SET_AVATAR", res.data.avatar);
          this.$store.commit("user/SET_PERMISSION", res.data.permissionList);
          this.$store.commit("basic/setMenu", res.data.menuList);
          // 缓存用户信息
          Cookie.setItem(
            "userInfo",
            JSON.stringify({
              name: res.data.name,
              avatar: res.data.avatar,
              permission: res.data.permissionList,
            })
          );
          setTimeout(() => {
            this.$router.push("/home");
          });
        }
      } finally {
        this.loading = false;
      }
    },

  

实际上我们会用store中的actions里的方法进行处理,以下是store下登录模块文件的代码:

import Cookie from "js-cookies";
import { login, logout, getInfo } from "@/api/user";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { resetRouter } from "@/router";

const getDefaultState = () => {
  return {
    token: getToken(),
    name: "",
    avatar: "",
    permission: [], // 按钮权限
  };
};

const state = getDefaultState();

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState());
  },
  SET_TOKEN: (state, token) => {
    state.token = token;
  },
  SET_NAME: (state, name) => {
    state.name = name;
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar;
  },
  SET_PERMISSION: (state, permission) => {
    state.permission = permission;
  },
};

const actions = {
  login({ commit }, userInfo) {
    const { username, password } = userInfo;
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password })
        .then((response) => {
          const { data } = response;
          commit("SET_TOKEN", data.token);
          setToken(data.token);
          resolve();
        })
        .catch((error) => {
          reject(error);
        });
    });
  },
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token)
        .then((response) => {
          const { data } = response;

          if (!data) {
            return reject("验证失败,请重新登录");
          }

          const { name, avatar, permissionList } = data;

          commit("SET_NAME", name);
          commit("SET_AVATAR", avatar);
          commit("SET_PERMISSION", permissionList);
          // 缓存用户信息
          Cookie.setItem(
            "userInfo",
            JSON.stringify({ name, avatar, permission: permissionList })
          );
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  },
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token)
        .then(() => {
          removeToken();
          resetRouter();
          commit("RESET_STATE");
          // 清除用户信息
          Cookie.removeItem("userInfo");
          resolve();
        })
        .catch((error) => {
          reject(error);
        });
    });
  },
  resetToken({ commit }) {
    return new Promise((resolve) => {
      removeToken();
      commit("RESET_STATE");
      resolve();
    });
  },
};

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

  

接下来在components文件夹下创建AuthorizedView.vue,将来会被用来包裹需要控制权限的元素:

<script>
import { checkPermission } from "@/utils/auth";
export default {
  name: "AuthorizedView",
  // 函数式组件
  functional: true,
  props: {
    authority: {
      type: Array,
      required: true,
    },
  },
  render(h, context) {
    const { props, scopedSlots } = context;
    return checkPermission(props.authority) ? scopedSlots.default() : null;
  },
};
</script>

  

可以看到代码中引用了一个utils下的方法:

const TokenKey = "Admin-Token";
import Cookie from "js-cookies";

// 获取Token
export function getToken() {
  return Cookie.getItem(TokenKey);
}

// 存储Token 【cookie有效期设置为客服交班时间14小时】
export function setToken(value) {
  let seconds = 14 * 60 * 60;
  let expires = new Date(new Date() * 1 + seconds * 1000);
  console.log(TokenKey, value, expires);
  return Cookie.setItem(TokenKey, value, expires);
}

// 移除Token
export function removeToken() {
  return Cookie.removeItem(TokenKey);
}

// 获取菜单
export function getMenu() {
  const menuStr = Cookie.getItem("menu");
  if (menuStr) {
    return JSON.parse(menuStr);
  } else {
    return [];
  }
}

// 获取用户信息(用户名、头像、按钮权限等)
export function getUserInfo(key) {
  const userStr = JSON.parse(Cookie.getItem("userInfo") || "") || {};
  if (userStr) {
    if (key === "avatar") return userStr.avatar;
    if (key === "name") return userStr.name;
    if (key === "permission") return userStr.permission;
  } else {
    return "";
  }
}

// 按钮权限校验
export function checkPermission(list) {
  const userStr = JSON.parse(Cookie.getItem("userInfo") || "") || {};
  const authList = userStr.permission;
  return list.some((item) => authList.includes(item));
}

  

因为权限是全局功能,所以直接在main.js中引入:

import AuthorizedView from "@/components/AuthorizedView";


Vue.component("AuthorizedView", AuthorizedView);

  

实际使用(这里是在表格的操作栏中对详情按钮进行控制):

<el-table-column fixed="right" label="操作" width="120">
          <template slot-scope="scope">
            <AuthorizedView :authority="['ACCOUNT_DETAIL']">
              <el-button @click="handleDetail(scope.row)" type="text"
                >详情</el-button
              >
            </AuthorizedView>
          </template>
        </el-table-column>

  

可以看到页面上可以展示按钮:

 再来试一下写个没有的权限:

 发现页面上没有显示这个按钮:

 

以上,一个简单的按钮权限控制功能就实现啦~撒花花~✿✿ヽ(°▽°)ノ✿