vueComponent / ant-design-vue-pro

👨🏻‍💻👩🏻‍💻 Use Ant Design Vue like a Pro! (vue2)
https://pro.antdv.com
MIT License
10.75k stars 3.11k forks source link

动态加载左侧栏菜单报错 #1157

Open zilong24 opened 3 years ago

zilong24 commented 3 years ago

在 BasicLayout.vue 文件中,修改代码动态加载菜单数据报错: vue-router.esm.js?8c4f:2314 Error: Cannot find module './BasicLayout' at eval (eval at .ciews lazy recursive ^.\/.*$ (app.js:7433), :4976:12)

/** BasicLayout.vue 文件开始 ***/

<template>
  <a-layout :class="['layout', device]">
    <!-- SideMenu -->
    <a-drawer
      v-if="isMobile()"
      placement="left"
      :wrapClassName="`drawer-sider ${navTheme}`"
      :closable="false"
      :visible="collapsed"
      @close="drawerClose"
    >
      <side-menu
        mode="inline"
        :menus="menus"
        :theme="navTheme"
        :collapsed="false"
        :collapsible="true"
        @menuSelect="menuSelect"
      ></side-menu>
    </a-drawer>

    <side-menu
      v-else-if="isSideMenu()"
      mode="inline"
      :menus="menus"
      :theme="navTheme"
      :collapsed="collapsed"
      :collapsible="true"
    ></side-menu>

    <a-layout :class="[layoutMode, `content-width-${contentWidth}`]" :style="{ paddingLeft: contentPaddingLeft, minHeight: '100vh' }">
      <!-- layout header -->
      <global-header
        :mode="layoutMode"
        :menus="menus"
        :theme="navTheme"
        :collapsed="collapsed"
        :device="device"
        @toggle="toggle"
      />

      <!-- layout content -->
      <a-layout-content :style="{ height: '100%', margin: '24px 24px 0', paddingTop: fixedHeader ? '64px' : '0' }">
        <multi-tab v-if="multiTab"></multi-tab>
        <transition name="page-transition">
          <route-view />
        </transition>
      </a-layout-content>

      <!-- layout footer -->
      <a-layout-footer>
        <global-footer />
      </a-layout-footer>

      <!-- Setting Drawer (show in development mode) -->
      <setting-drawer v-if="!production"></setting-drawer>
    </a-layout>
  </a-layout>

</template>

<script>
import { triggerWindowResizeEvent, } from '@/utils/util'
import { mapState, mapActions } from 'vuex'
import { mixin, mixinDevice } from '@/utils/mixin'
import config from '@/config/defaultSettings'

import RouteView from './RouteView'
import SideMenu from '@/components/Menu/SideMenu'
import GlobalHeader from '@/components/GlobalHeader'
import GlobalFooter from '@/components/GlobalFooter'
import SettingDrawer from '@/components/SettingDrawer'
import { convertRoutes } from '@/utils/routeConvert'

import { myMenu } from '@/api/modular/system/menuManage'    //引入文件加载菜单数据

export default {
  name: 'BasicLayout',
  mixins: [mixin, mixinDevice],
  components: {
    RouteView,
    SideMenu,
    GlobalHeader,
    GlobalFooter,
    SettingDrawer
  },
  data () {
    return {
      production: config.production,
      collapsed: false,
      menus: [],
      flowType:'2',
      administrativeCategory:'1'
    }
  },
  computed: {
    ...mapState({
      // 动态主路由
      mainMenu: state => state.permission.addRouters
    }),
    contentPaddingLeft () {
      if (!this.fixSidebar || this.isMobile()) {
        return '0'
      }
      if (this.sidebarOpened) {
        return '256px'
      }
      return '80px'
    }
  },
  watch: {
    sidebarOpened (val) {
      this.collapsed = !val
    },
    // 菜单变化
    mainMenu (val) {
      this.setMenus()
    }
  },
  created () {
    this.setMenus()
    /* const routes = convertRoutes(this.mainMenu.find(item => item.path === '/'))
    this.menus = (routes && routes.children) || [] */
    this.collapsed = !this.sidebarOpened
  },
  mounted () {
    const userAgent = navigator.userAgent
    if (userAgent.indexOf('Edge') > -1) {
      this.$nextTick(() => {
        this.collapsed = !this.collapsed
        setTimeout(() => {
          this.collapsed = !this.collapsed
        }, 16)
      })
    }
  },
  methods: {
    ...mapActions(['setSidebar']),
    // 重新生成
    setMenus () {
      const routes = convertRoutes(this.mainMenu.find(item => item.path === '/'))
      this.menus = (routes && routes.children) || []

         this.menus = [];
        //调用接口动态加载菜单数据报错
         myMenu().then((res)=>{
           this.menus = res.data;
         })

    },
    toggle () {
      this.collapsed = !this.collapsed
      this.setSidebar(!this.collapsed)
      triggerWindowResizeEvent()
    },
    paddingCalc () {
      let left = ''
      if (this.sidebarOpened) {
        left = this.isDesktop() ? '256px' : '80px'
      } else {
        left = (this.isMobile() && '0') || ((this.fixSidebar && '80px') || '0')
      }
      return left
    },
    menuSelect () {
    },
    drawerClose () {
      this.collapsed = false
    },

  }
}
</script>

<style lang="less">
/*
 * The following styles are auto-applied to elements with
 * transition="page-transition" when their visibility is toggled
 * by Vue.js.
 *
 * You can easily play with the page transition by editing
 * these styles.
 */

.page-transition-enter {
  opacity: 0;
}

.page-transition-leave-active {
  opacity: 0;
}

.page-transition-enter .page-transition-container,
.page-transition-leave-active .page-transition-container {
  -webkit-transform: scale(1.1);
  transform: scale(1.1);
}
/**************************** */
.sider.light .logo{
  // background: #1A2C64 !important;
  background: #001529 !important
}
.sider .logo h1{
  font-size: 18px !important;
  color: #fff !important;
}
// .header .ant-menu{
//   // background: #1A2C64 !important;
//   // background: rgba(255, 255, 255, 0.2) !important;
// }
.user-wrapper span{
  color: #fff;
}
/** */
</style>

/*** BasicLayout.vue 文件结束 ****/

menuManage.vue 文件

import { axios } from '@/utils/request'

/**
 * 获取菜单列表
 *
 * @author yubaoshan
 * @param parameter
 * @returns {*}
 */
export function getMenuList (parameter) {
  return axios({
    url: '/sysMenu/list',
    method: 'get',
    params: parameter
  })
}

/**
 * 获取系统菜单树,用于新增,编辑时选择上级节点
 *
 * @author yubaoshan
 * @date 2020/4/23 12:22
 */
export function getMenuTree (parameter) {
  return axios({
    url: '/sysMenu/tree',
    method: 'get',
    params: parameter
  })
}

/**
 * 增加菜单
 *
 * @author yubaoshan
 * @date 2020/4/24 23:23
 */
export function sysMenuAdd (parameter) {
  return axios({
    url: '/sysMenu/add',
    method: 'post',
    data: parameter
  })
}

/**
 * 增加菜单
 *
 * @author yubaoshan
 * @date 2020/4/24 23:23
 */
export function sysMenuDelete (parameter) {
  return axios({
    url: '/sysMenu/delete',
    method: 'post',
    data: parameter
  })
}

/**
 * 查看菜单详情
 *
 * @author yubaoshan
 * @date 2020/4/25 01:11
 */
export function sysMenuDetail (parameter) {
  return axios({
    url: '/sysMenu/detail',
    method: 'post',
    data: parameter
  })
}

/**
 * 编辑系统菜单
 *
 * @author yubaoshan
 * @date 2020/4/25 01:11
 */
export function sysMenuEdit (parameter) {
  return axios({
    url: '/sysMenu/edit',
    method: 'post',
    data: parameter
  })
}

/**
 * 获取系统菜单树,用于给角色授权时选择
 *
 * @author yubaoshan
 * @date 2020/6/2 17:30
 */
export function SysMenuTreeForGrant (parameter) {
  return axios({
    url: '/sysMenu/treeForGrant',
    method: 'get',
    params: parameter
  })
}

/**
 * 根据系统切换菜单
 *
 * @author yubaoshan
 * @date 2020/6/28 15:25
 */
export function sysMenuChange (parameter) {
  return axios({
    url: '/sysMenu/change',
    method: 'post',
    data: parameter
  })
}

//通过接口动态加载菜单数据
export function myMenu (parameter) {

  return axios({
    url: '/my/menu/'+parameter['id'],
    method: 'get',
    data: parameter
  })
}

@/utils/request.js 文件

import Vue from 'vue'
import axios from 'axios'
import store from '@/store'
import { message, Modal, notification } from 'ant-design-vue' /// es/notification
import { VueAxios } from './axios'
import { ACCESS_TOKEN } from '@/store/mutation-types'

// 创建 axios 实例
const service = axios.create({
  baseURL: '/api', // api base_url
  timeout: 6000 // 请求超时时间
})

const err = (error) => {
  if (error.response) {
    const data = error.response.data
    const token = Vue.ls.get(ACCESS_TOKEN)

    if (error.response.status === 403) {
      console.log('服务器403啦,要重新登录!')
      notification.error({
        message: 'Forbidden',
        description: data.message
      })
    }
    if (error.response.status === 500) {
      if (data.message.length > 0) {
        message.error(data.message)
      }
    }
    if (error.response.status === 401 && !(data.result && data.result.isLogin)) {
      notification.error({
        message: 'Unauthorized',
        description: 'Authorization verification failed'
      })
      if (token) {
        store.dispatch('Logout').then(() => {
          setTimeout(() => {
            window.location.reload()
          }, 1500)
        })
      }
    }
  }
  return Promise.reject(error)
}

// request interceptor
service.interceptors.request.use(config => {
  const token = Vue.ls.get(ACCESS_TOKEN)
  if (token) {
    config.headers['Authorization'] = 'Bearer ' + token
  }
  return config
}, err)

/**
 * response interceptor
 * 所有请求统一返回
 */
service.interceptors.response.use((response) => {
  if (response.request.responseType === 'blob') {
    return response
  }
  const code = response.data.code
  if (code === 1011006 || code === 1011007 || code === 1011008 || code === 1011009) {
    Modal.error({
      title: '提示:',
      content: response.data.message,
      okText: '重新登录',
      onOk: () => {
        Vue.ls.remove(ACCESS_TOKEN)
        window.location.reload()
      }
    })
  } else if (code === 1013002 || code === 1016002 || code === 1015002) {
    message.error(response.data.message)
    return response.data
  } else {
    return response.data
  }
}, err)

const installer = {
  vm: {},
  install (Vue) {
    Vue.use(VueAxios, service)
  }
}

export {
  installer as VueAxios,
  service as axios
}
sendya commented 3 years ago

你的问题在构建动态菜单的地方,根本不在 basiclayout 基础文件,axios请求文件里。 请先确定到出现问题的模块

zilong24 commented 3 years ago

你的问题在构建动态菜单的地方,根本不在 basiclayout 基础文件,axios请求文件里。 请先确定到出现问题的模块

axios请求文件(@/utils/request.js)已更新 (另外:去掉axios请求文件,在 basiclayout 文件中引入 jquery ,使用 $.ajax 可以正常加载动态数据)

sendya commented 3 years ago

你照着仓库源码对比 你改了哪里改吧。,应该能查出来。你这样的反馈不太好测试复现

zilong24 commented 3 years ago

你照着仓库源码对比 你改了哪里改吧。,应该能查出来。你这样的反馈不太好测试复现

通过 ajax 动态加载数据后 点击左侧菜单,右边页面不刷新 是什么原因呢?(备注:菜单组件没有改动,只是换了菜单数据,格式还是按照原来的,a链接的href路由地址也是对的)