基於vue-element UI 後臺管理平臺 踩坑記錄( 一 )

Condee發表於2019-03-04

最近在做基於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 的時候才會執行
複製程式碼

相關文章