vue动态路由搭建后界面出不来

搭建一个vue2的动态路由框架,现状是动态路由能添加成功,但是界面出不来。如下

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store';
import NProgress from 'nprogress' //导航条
import "nprogress/nprogress.css"//导航条样式
import { Message } from 'element-ui'
import { setData1, getData1 } from '@/utils/cache'
import login from '@/views/login'
Vue.use(VueRouter)

// 解决编程式路由往同一地址跳转时会报错的情况
// const originalPush = VueRouter.prototype.push
// VueRouter.prototype.push = function push(location) {
//   return originalPush.call(this, location).catch(err => err)
// }
//静态路由
const routes = [
  {
    path: '/',
    redirect: '/login'
  },
  {
    path: '/login',
    name: '登录',
    component: login
  },
]

const router = new VueRouter({
  routes
})
// 解析路由
function setChild(me, routerList, rootName, rootPath) {
  rootName = rootName + '/' + me.name
  rootPath = rootPath + '/' + me.path
  if (me.children != null && me.children != [] && me.children.length > 0) {
    //如果有下层
    me.children.forEach(node => {
      setChild(node, routerList, rootName, rootPath)
    })
  } else {
    //没有下层则说明这是一个路由
    let rou = {
      name: rootName,
      path: rootPath,
      component: () => import('@/views' + rootPath)
    }
    routerList.push(rou)
  }

}

let isAddRoute = true  //阀门变量 避免重复添加
router.beforeEach(async (to, from, next) => {
  console.log(to);
  if (isAddRoute && store.state.routers.length != 0) {
    let dynamicRoutes = await JSON.parse(JSON.stringify(store.state.routers))
    //添加动态路由
    let routerList = []
    dynamicRoutes.forEach(v => {
      setChild(v, routerList, '', '')
    })
    let initHome = {
      path: '/home',
      name: 'home',
      meta: {
        name: 'home',
      },
      component: () => import('@/views/home'),
      children: dynamicRoutes
    }
    router.addRoute(initHome);
    router.addRoute({
      path: '*',
      hidden: true,
      component: () => import( /* webpackChunkName: "error" */ '@/views/error'),
      name: '404',
    })
    console.log(router.getRoutes());
    isAddRoute = false //关闭阀门,否则会一直循环崩溃
    next({ ...to, replace: true })  // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)
  } else {
    next()
  }
})

router.afterEach((to, from) => {
  NProgress.done()
  window.scrollTo(0, 0)
  if (to.name) {
    document.title = to.name
  }
})

export default router

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:根据你提供的代码,似乎出现问题的地方在于动态路由的组件路径设置。在 setChild 函数中,你使用了如下代码来设置路由的组件:

let rou = {
  name: rootName,
  path: rootPath,
  component: () => import('@/views' + rootPath)
}

这个代码中,rootPath 是路由的路径,而 @/views 则是你的组件所在的根目录。因此,你期望的组件路径应该是 @/views${rootPath},而不是 @/views${rootPath}。这个问题可能会导致找不到组件而导致界面无法展示。
你可以尝试修改这个代码,将 '@/views' + rootPath 改为 '@/views' + rootPath + '.vue',以明确指定组件的路径。例如:

let rou = {
  name: rootName,
  path: rootPath,
  component: () => import('@/views' + rootPath + '.vue')
}

另外,你也可以在浏览器控制台中查看网络请求,以确定是否成功加载了组件。如果组件加载失败,可能会在网络请求中看到错误信息,从而帮助你更好地定位问题。
以下是 setChild 函数的修改后的完整代码:

function setChild(me, routerList, rootName, rootPath) {
  rootName = rootName + '/' + me.name
  rootPath = rootPath + '/' + me.path
  if (me.children != null && me.children != [] && me.children.length > 0) {
    //如果有下层
    me.children.forEach(node => {
      setChild(node, routerList, rootName, rootPath)
    })
  } else {
    //没有下层则说明这是一个路由
    let rou = {
      name: rootName,
      path: rootPath,
      component: () => import('@/views' + rootPath + '.vue')
    }
    routerList.push(rou)
  }
}

在这个代码中,我们将路由组件路径的拼接修改为了 '@/views' + rootPath + '.vue',以确保能够正确地加载组件。其他部分的代码和之前的版本相同。
请注意,这个修改只是针对路由组件路径的问题,如果问题仍然存在,可能需要进一步排查其他可能的原因,例如路由配置、组件代码等。希望这些信息能够帮助你解决问题。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7751379
  • 这篇博客你也可以参考下:vue2实现海康威视根据海康插件进行监控实时预览和回放功能,全套代码,开箱即用。
  • 除此之外, 这篇博客: vue技术点整理中的 2、vue常用的修饰符有哪些?应用场景 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 表单修饰符:

    1. lazy:在我们填完信息,光标离开标签的时候,才会将值赋予给value,也就是在change事件之后再进行信息同步
    2. trim:自动过滤用户输入的首空格字符,而中间的空格不会过滤
    3. number:自动将用户的输入值转为数值类型,但如果这个值无法被parseFloat解析,则会返回原来的值
    <input type="text" v-model.lazy="value">
    <input type="text" v-model.trim="value">
    <input v-model.number="age" type="number">

    事件修饰符:

    • stop 阻止了事件冒泡,相当于调用了event.stopPropagation方法

    • prevent 阻止了事件的默认行为,相当于调用了event.preventDefault方法

    • self 只当在 event.target 是当前元素自身时触发处理函数

    • once 绑定了事件以后只能触发一次,第二次就不会触发

    • capture 使事件触发从包含这个元素的顶层开始往下触发

    • passive 在移动端,当我们在监听元素滚动事件的时候,会一直触发onscroll事件会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll事件整了一个.lazy修饰符

    • native 让组件变成像html内置标签那样监听根元素的原生事件,否则组件上使用 v-on 只会监听自定义事件

    鼠标按钮修饰符:

    • left 左键点击

    • right 右键点击

    • middle 中键点击

    键盘修饰符:

    • 普通键(enter、tab、delete、space、esc、up...)

    • 系统修饰键(ctrl、alt、meta、shift...)

    详见:https://liulibin.blog.csdn.net/article/details/114964657

     

  • 您还可以看一下 徐照兴老师的Vue全家桶从基础入门到进阶项目实战第四篇综合进阶项目篇课程中的 为条件查询设置重置功能小节, 巩固相关知识点