基于vue-element UI 后台管理平台 踩坑记录( 一 )

·  阅读 8449

最近在做基于vue -element ui 的 admin 管理平台,踩坑还是不少。一些比较实用的,还有一些坑, 希望记录下来, 如果有你们需要的,恰好有解决办法, 那是荣幸之至呀,

使用的基础模板来自于 github.com/PanJiaChen/… ) (在此感谢作者!)

利用vue-router 与 element UI 的 NavMenu 动态渲染 sideBar

一级route属性 如:
    var routersSingle = {
       path: '/' + routers[i].url,
       component: Layout,
       name: routers[i].url,
       meta: { title: routers[i].name, icon: 'tree', id: routers[i].id }, 
       children: [],
       alwaysShow: true
    };
    

二级route属性 如:
    var routersSingleChildren = {
        component: () => import(`@/views/${state.addRouters[i].name}/${routers[j].url}`),
        path: routers[j].url,
        name: routers[j].url,
        meta: { title: routers[j].name }
    }
    
定义之后,我们用一个简单的方式去组装路由形成我们需要的路由列表,由于路由是后端给予的,所以除了最公共的路由,所有都是要重新生成的

/* 存储可以访问的模块 */
  state.modules = routers
  state.addRouters = []
  /* 如果用户有访问的路由才进行路由组合 */
  if (routers.length) {
    /* 渲染父模块 */
    for (let i = 0; i < routers.length; i++) {
      /* 用layout包裹,找出pid为0的父级模块来渲染 */
      if (routers[i].pid === 0) {
        var routersSingle = {
          path: '/' + routers[i].url,
          component: Layout,
          name: routers[i].url,
          meta: { title: routers[i].name, icon: 'tree', id: routers[i].id },
          children: [],
          alwaysShow: true
        };
        state.addRouters.push(routersSingle)
      }
    }
    /* 渲染子模块 */
    for (let i = 0; i < state.addRouters.length; i++) {
      for (let j = 0; j < routers.length; j++) {
        /* 如果id 与 父模块的pid 相同 放入其children */
        if (state.addRouters[i].meta.id === routers[j].pid) {
          var routersSingleChildren = {
            component: () => import(`@/views/${state.addRouters[i].name}/${routers[j].url}`), 
            /* 此处的坑,一定要用let循环,或者IIFE 不然你得到的永远是 i = router.length */
            path: routers[j].url,
            name: routers[j].url,
            meta: { title: routers[j].name }
          }
        }
      }
    }
  } else {
    console.log('用户没有路由')
  }
  state.addRouters  /* 后端回来的路由组装完毕~~~ */
  
  这个时候我们需要一个JS,单独去管理路由的跳转,此套模板已经配置和介绍,那么按照介绍去撸即可(在这个js里 permission.js)。
复制代码

路由跳转的钩子 router.beforeEach(to, from, next)

这是啥: 在路由切换时,此函数会触发
参数: 
    to: 即将进入路由的 route 信息 
    from: 离开路由的 route 信息
    next: 继续执行的函数,没有 next() 的此钩子 会彻底 阻止你 进入下一个路由
有啥用: 如果你需要在访问不同路由时候去获取 离开页面 或 者即将进入页面 的动态数据,那么这个地方是个好地方。

例子: 
    import router from './router'; 
    import NProgress from 'nprogress'; /* Progress 进度条 */
    import 'nprogress/nprogress.css'; /* Progress 进度条样式 */ 
    import { getToken } from '@/utils/auth'; /* 权限检查 */ (自己设定的,根据各自情况定义)
    
    router.beforeEach((to, from, next) => {
        /* 来做点事情 */
        /* 根据用户的token是否存在做判断 */
        if(getToken()) {
            /* 如果token存在的话,也就是用户保持登陆状态的话,那跳登陆页面的都给我跳主页 */
            if(to.path === 'login') {
                next({path: '/'})
            } else {
                /* 如果不是的话,那就做你需要做的事情啦,例如 获取每一个页面的权限城市 */
                ...do something
                next()
            }
        }
    })
复制代码

Element Table 坑系列

1.
    如果你有这样的需求, 一个页面有几个状态,对应的table的column有增加或减少,一定给每一个column加上key.
不然你就会发现,每次切换状态的时候column的位置变化了,或者在网速略慢的情况下,甚至table会崩溃. 
当然 一定要记得 element table 的这个方法, doLayout()

doLayout	对 Table 进行重新布局。当 Table 或其祖先元素由隐藏切换为显示时,可能需要调用此方法
使用方法: <el-table ref="yourTable"><el-table>  <script> this.$refs.yourTable.doLayout() <script>

2.
    如果你需要让页面不出现滚轮, 并且在PC上要兼容到 1366*768  我使用的办法是:
        <el-table max-height="tableHeight"><el-table> 
        <script>data() { return{ tableHeight: document.body.clientHeight - 某一个固定值(例如 200) } }<script>
    这样不管是1366 还是 1920 分辨率打开这个页面 ,都可以保证 不会出现滚动条
    (如果有更好的办法请告诉我,不胜感激!!!)

3.
    table在 Loading 和 border 的情况下. 数据重新渲染下,table的border left 和 top 会消失一下,然后在table加载完成之后 显示. 那么就造成table 抖动一下.
    
     处理方法:
         /* element 2.2.1 在有border, v-loading 情况下,会把border left 和 top 干掉 */
        .el-table--border.el-loading-parent--relative {
          border-left: solid 1px #ebeef5;
          border-top: solid 1px #ebeef5
        }
    但是在safari的情况下 处理之后...貌似有一定的偏移.. 官方貌似也是因为这个原因 把 left 和 top 设置为了None
    如果不兼容 safari 的话 这个是比较不错的解决方法
复制代码

Element TimePicker 修改之路

  如果你们的需求是选择一个 字符串时间,且 希望是先选时间,再选分钟这样的形式的话, 
我这边有根据 Element Cascader选择器  制作的一个 小组件~   给出来的值,是字符串 例如 :'14 : 00' 如此。
有一些业务要求,例如 开始时间 选择之后 , 结束时间 不能选择 开始时间之前的任何时间,  结束时间也限制开始时间的选择。  
  回显的时候也只需要是字符串即可.
复制代码

点击sideBar 更新当前路由

更新的含义:
    重新加载此组件,生命周期都会走一次.
    之前采用的方法是先在sideBar里,带上一个随机参数query,例如 new Date() 然后每一个页面里Watch路由的变化,并执行请求数据的函数.
为了简单,所以我们暂时采用以下方法,如果有更好的方法,也希望能告诉我呀...........

<router-view v-if="aliveRouter" ><router-view>
添加一个状态值  aliveRouter

什么时候去改变aliveRouter呢

如果左侧sideBar 没有触发 router.beforeEach(to, from, next) 的时候, 证明没有跳转路由。
这个时候就:
  this.aliveRouter = false;
  this.$nextTick(() => {
    this.aliveRouuter = true;
  )
这样这个路由也就重新加载了。
那如果是触发路由了 那么久不执行这个代码, 这个时候控制的方法有很多种 ,我是自己设置了一个flag。 如果进入了beforeEach 会改变flag = false  那么  上面的代码 只会在 flag = true 的时候才会执行
复制代码
分类:
前端
标签:
分类:
前端
标签: