Vuex + modules 管理导航菜单和帐号信息

思想:请求导航菜单数据和帐号信息数据后,存到vuex中,方便后期使用。

如何根据账号权限动态渲染导航菜单

        请求到当前帐号信息后,在导航渲染区域加上如下代码。此时,导航已被请求到的menuList所渲染完毕。若此账号的权限不包含此项菜单的路径,则disabled掉(permissions为数组,每一项是此账号被授权的路径):

<el-menu-item :disabled="accountInfo.permissions.indexOf(children.path) === -1" >

home.vue组件部分代码:

<!--  -->
<template>
  <div>
    <el-container>
      <!-- 导航 -->
      <el-aside style="width: auto">
        <el-menu
          default-active="1-4-1"
          class="el-menu-vertical-demo"
          :collapse="isCollapse"
          :collapse-transition="false"
          v-if="menuList && accountInfo"
        >
          <!-- 以防ajax没请求回来,下面若用到menuList,accountInfo会报undefined错 -->
          <el-menu-item>
            <i class="el-icon-location"></i>
            <span slot="title">首页</span>
          </el-menu-item>
          <el-submenu
            v-for="item in menuList"
            :key="item.uid"
            :index="item.path"
          >
            <!-- 一级菜单模版区域 -->
            <template slot="title">
              <i :class="iconsObj[item.id]"></i>
              <span slot="title">{{ item.name }}{{ item.path }}</span>
            </template>
            <el-menu-item
              v-for="children in item.children"
              :key="children.uid"
              :index="children.path"
              :disabled="accountInfo.permissions.indexOf(children.path) === -1"
            >
              <!-- 二级菜单模版区域 -->
              <template slot="title">
                <i :class="iconsObj[children.id]"></i>
                <span slot="title">{{ children.name }}{{ children.path }}</span>
              </template>
            </el-menu-item>
          </el-submenu>
        </el-menu>
      </el-aside>
      <!-- 右侧 -->
      <!-- 以防ajax没请求回来,下面若用到accountInfo会报undefined错 -->
      <el-main v-if="accountInfo">
        <div style="height: 50px; line-height: 50px; background: #ccc">
          <el-row>
            <el-col :span="12">
              <el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
                <el-radio-button :label="false">展开</el-radio-button>
                <el-radio-button :label="true">收起</el-radio-button>
              </el-radio-group>
            </el-col>
            <el-col :span="12">
              <div style="text-align: right; padding-right: 40px">
                当前用户:
                <router-link to="/info" style="color: deepskyblue">
                  {{ accountInfo.profile.name }}
                </router-link>
              </div>
            </el-col>
          </el-row>
        </div>
        <div>
          <router-view></router-view>
        </div>
      </el-main>
    </el-container>
  </div>
</template>

<script>
import api from "../../utils/api/home";
import { mapState } from "vuex";
export default {
  name: "",
  data() {
    return {
      isCollapse: false,
      iconsObj: {
        1: "el-icon-setting",
        2: "el-icon-tickets",
        4: "el-icon-user",
        12: "el-icon-s-custom",
        21: "el-icon-s-check",
        17: "el-icon-menu",
        22: "el-icon-collection",
        41: "el-icon-s-order",
        46: "el-icon-document-add",
        42: "el-icon-document",
        45: "el-icon-folder-opened",
      },
    };
  },
  computed: {
    //state
    ...mapState({
      menuList: (state) => state.menu.menuList,
      accountInfo: (state) => state.user.accountInfo,
    })
  },
  created() {},
  mounted() {
    this.getMenu();
    this.getAccountInfo();
  },
  methods: {
    //获取导航菜单数据
    getMenu() {
      api
        .getMenuList()
        .then((res) => {
          //修改导航状态树
          this.$store.commit("setMenu", res.data);
        })
        .catch((err) => {
          console.log(err);
        });
    },
    //获取当前帐号信息
    getAccountInfo() {
      api
        .getAccountInfo()
        .then((res) => {
          //修改帐号状态树
          this.$store.commit("setInfo", res.data);
          console.log(res);
        })
        .catch((err) => {
          console.log(err);
        });
    },
  },
};
</script>

<style scoped>
</style>

main.js:

import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue'
import router from './router/index'
import store from './store/index'

//全局使用
Vue.use(ElementUI);

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

store > index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

import menu from './modules/menu'
import user from './modules/user'

export default new Vuex.Store({
  modules: {
    menu,user
  }
})

// export default new Vuex.Store({
//   state,//数据
//   getters,//计算属性,可以重新计算state,用法相当于computed
//   mutations,//同步函数 要想改变state,得在组件的方法中调用mutations的方法,具体操作写在mutations中
//   actions,//提交mutations——可以包括异步如setTimeout一个mutation方法,也可以在里面写条件判断决定提交哪个mutations,不能直接变更state
// })

store > modules > menu.js

export default {
  //局部
  state: {
    menuList: []
  },
  //全局
  mutations: {
    //修改导航菜单数据
    setMenu(state, data) {
      //console.log(this.state);//若想调取其它modules下js的state
      state.menuList = data
    }
  }
}

store > modules > user.js

export default {
  state: {
    accountInfo: ''
  },
  mutations: {
    //修改当前帐号信息
    setInfo(state, data) {
      state.accountInfo = data
    }
  }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值