餓了麼組件庫,element-ui開發精美的後臺管理系統系列之(一)開發伸縮菜單


涉及到路由,權限等等相關內容的部分,跟本文主旨關係不大,因此我將會在另一篇文章中詳述,混在一塊兒的話內容太多了html


基於element-ui的左側可伸縮的菜單
經過vuejs來開發支持展開收縮的菜單是很是簡單的,只須要v-if v-else便可簡單實現,下面我分步驟詳細講解過程,並在後續的系列文章中詳細講解權限菜單、路由過濾等等一些實用的技巧。固然還包括完整實現後臺管理頁面所要重點關注的細節。vue

如何把權限菜單展現出來呢?
首先,這是一個動態菜單,該顯示什麼樣的菜單須要從後端獲取,規則方面以下:html5

[
    {
        'label': '這個菜單',
        'id': 001,
        'parntid': 0
    },
    {
        'label': '那個菜單',
        'id': 002,
        'parntid': 0
    },
    {
        'label': '二個菜單',
        'id': 003,
        'parntid': 001
    },
    {
        'label': '三個菜單',
        'id': 003,
        'parntid': 001
    },
    {
        'label': '四個菜單',
        'id': 003,
        'parntid': 002
    },
    {
        'label': '吳個菜單',
        'id': 003,
        'parntid': 002
    }
]

注意:我這裏是用的兩級菜單,一樣的原理能夠很簡單的生成多級的。json中經過id來實現父子關聯,也能夠改爲多級的json,用child來表示子級,子級的子級。這樣也能夠很容易的生成多級的多級菜單。不過一般也就兩級或者三級。原理相同很容易擴展,若是不知道怎麼擴展歡迎加入qq羣:478694438來探討。
下面看一下菜單的展現,須要aside標籤,aside標籤是html5的標籤,沒見過aside ?沒關係換成div也行。先看效果,再看代碼(代碼看上去有點長,別被嚇着,我後面詳細講解):
這是收縮的狀態:
clipboard.pngelement-ui

這是展開的狀態:
clipboard.pngjson

<aside :class="collapsed?'menu-expanded':'menu-collapsed'">
                <el-menu default-active="/ManageRole" v-if="collapsed" class="el-menu-vertical-demo"  router>
                    <template v-for="(item,index) in authMenu">
                        <el-submenu :index="index+''" v-if="item.parentPermissionCode==0">
                            <template slot="title">&nbsp;&nbsp;&nbsp;<i :class="getIcon(item.permissionName)">&nbsp;&nbsp;&nbsp;</i>{{item.permissionName}}</template>
                            <el-menu-item v-for="child in authMenu" :index="child.uri" :key="child.permissionMark" v-if="item.permissionCode==child.parentPermissionCode">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i :class="getIcon(child.permissionName)">&nbsp;&nbsp;&nbsp;</i>{{child.permissionName}}</el-menu-item>
                        </el-submenu>    
                    </template>
                </el-menu>
                <ul class="el-menu collapsed" ref="menuCollapsed" v-else>
                    <li v-for="(item,index) in authMenu" v-if="item.parentPermissionCode==0" class="el-submenu item">
                        <template>
                            <div class="el-submenu__title" style="padding-left: 20px;" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)"><i :class="getIcon(item.permissionName)"></i></div>
                            <ul class="el-menu tipMenu" :class="'submenu-hook-'+index" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)"> 
                                <li v-for="child in authMenu" :key="child.uri" v-if="item.permissionCode==child.parentPermissionCode" class="el-menu-item" style="padding-left: 40px;" :class="$route.path==child.path?'is-active':''" @click="$router.push(child.uri)"><i :class="getIcon(child.permissionName)"></i>&nbsp;&nbsp;&nbsp;{{child.permissionName}}</li>
                            </ul>
                        </template>
                    </li>
                </ul>
                <div class="changeState" @click="collapsed=!collapsed">
                    <i v-if="collapsed" class="iconfont icon-zuoyou1"></i>
                    <i v-else class="iconfont icon-zuoyou"></i>
                </div>    
            </aside>

來分析一下這些亂糟糟的代碼(這是我從源碼中截出來的因此看起來有點亂):
<el-menu>、<ul>、changeState這三個都是aside標籤下的同級的標籤,分別對應:展開狀態下的菜單、收縮狀態下的菜單、切換狀態的箭頭。
先看el-menu:後端

<el-menu default-active="/ManageRole" v-if="collapsed" class="el-menu-vertical-demo"  router>
                    <template v-for="(item,index) in authMenu">
                        <el-submenu :index="index+''" v-if="item.parentPermissionCode==0">
                            <template slot="title">&nbsp;&nbsp;&nbsp;<i :class="getIcon(item.permissionName)">&nbsp;&nbsp;&nbsp;</i>{{item.permissionName}}</template>
                            <el-menu-item v-for="child in authMenu" :index="child.uri" :key="child.permissionMark" v-if="item.permissionCode==child.parentPermissionCode">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i :class="getIcon(child.permissionName)">&nbsp;&nbsp;&nbsp;</i>{{child.permissionName}}</el-menu-item>
                        </el-submenu>    
                    </template>
                </el-menu>

collapsed這個值即爲判斷顯示展開仍是收縮狀態的開關。對照ul下的v-else看。經過一個v-for 循環除全部的父級菜單,再次循環尋找子級菜單中parentId==id的子菜單,做爲該父級菜單下的子菜單。這樣就實現了展開狀態下的菜單。
注意:圖標的問題,圖標能夠選擇從後端返回class,這樣作起來起來更簡單,我這裏是經過預設一個getIcon()函數在本地設置顯示,因爲圖標和路由面臨的是相同的實現,因此我會在路由跳轉相關的地方詳細解釋一下,應該在何種場景下選擇何種方式。ide

再看ul:函數

<ul class="el-menu collapsed" ref="menuCollapsed" v-else>
                    <li v-for="(item,index) in authMenu" v-if="item.parentPermissionCode==0" class="el-submenu item">
                        <template>
                            <div class="el-submenu__title" style="padding-left: 20px;" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)"><i :class="getIcon(item.permissionName)"></i></div>
                            <ul class="el-menu tipMenu" :class="'submenu-hook-'+index" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)"> 
                                <li v-for="child in authMenu" :key="child.uri" v-if="item.permissionCode==child.parentPermissionCode" class="el-menu-item" style="padding-left: 40px;" :class="$route.path==child.path?'is-active':''" @click="$router.push(child.uri)"><i :class="getIcon(child.permissionName)"></i>&nbsp;&nbsp;&nbsp;{{child.permissionName}}</li>
                            </ul>
                        </template>
                    </li>
                </ul>

這根element-ui就沒有關係了,簡單的ul li 實現。(路由相關的能夠展現忽略,我會在下一篇文章中詳細描述)優化

最後看:ui

<div class="changeState" @click="collapsed=!collapsed">
                    <i v-if="collapsed" class="iconfont icon-zuoyou1"></i>
                    <i v-else class="iconfont icon-zuoyou"></i>
                </div>

經過collapsed 在v-if v-else中綁定視圖簡單實現了,開關功能。

寫在最後
這個功能看似簡單卻包含了vuejs的十幾個知識點。難倒了不少人,我之全部寫這篇文章,也是由於不少朋友,在此以前不斷的詢問我如何才能優雅的實現這個功能。固然了這隻一個完整的後臺管理的開始,我將會在後面的文章中繼續講解關於你們最關心的要不要使用addRoutes,如何使用addRoutes,不使用addRoutes的狀況下如何使用路由攔截來有沒的實現路由與權限的匹配,包括系統內部不一樣權限展現不一樣的操做界面的問題,固然了這是後話。若是有時間的話,我會把這個系列寫完,知道朋友們能獨立開發一個完整的vuejs的單頁面後臺管理程序。

文中設計的代碼我將會上傳到討論羣中(478694438),不足之處優化共同探討。

相關文章
相關標籤/搜索