webpack+vue項目實戰(二,開發管理系統主頁面)

1.前言

上篇文章(webpack+vue項目實戰(一,搭建運行環境和相關配置))搭建了好了基本的一個項目目錄,安好好了一些要用到的依賴,以及把項目跑了起來。接下來,咱們就進行第二步的操做,第二步就是作好一個開發系統的主頁面,這個頁面主要也就是一個側邊欄,經過側邊欄的各個選項來進行操做(切換各個組件)。好比回款管理,訂單管理,物流管理等等的操做。javascript

2.頂部組件

開始屬於排版這一塊了,是時候在index.js引入一個公用樣式了,至關於一個樣式重置表。css

clipboard.png

需求有一個,頁面上面須要放一個退出的登陸按鈕,我就寫了一個頂部組件的文件。首先就是建立這個文件html

clipboard.png

代碼以下vue

<template>
    <div class="topbar">
        <el-button class="fr mr30 mt15" type="primary" size="small" @click="loginOut">退出登陸</el-button>
    </div>
</template>

<script>
    export default{
        data(){
            return {
                name: 'topbar'
            }
        },
        methods: {
            loginOut(){
                ...
            }
        },
        mounted(){

        }
    }
</script>
<style lang="scss" scoped>
    .topbar {
        width: 100%;
        height: 60px;
    }
</style>

而後入口文件(index.js)引用這個文件,而且在vue中註冊組件import topbarComponent from './../components/admin_base/topbar.vue';java

clipboard.png

而後入口模板文件,index.html引入標籤
clipboard.png
頁面結果(基於上一篇文章,已經跑起來的結果)webpack

clipboard.png

頁面上的class在公用樣式裏面有寫好樣式,還有一些樣式是element-ui提供的,
<el-button>退出登陸</el-button>就是element-ui提供的組件,在入口文件index.js已經引入了element-ui。這裏直接用就好!web

這個比較簡單,我就很少說了。vue-router

3.側邊欄組件

這個側邊欄就是這篇文章的重點,也是整個項目操做的重點。先在目錄上建立這樣一個的側邊欄的組件文件。element-ui

clipboard.png

下面圖片是咱們要實現的效果,那些排版切圖的樣式我很少說了,相信不會難倒你們segmentfault

clipboard.png

1.首先,建立一下這個側邊欄所須要的數據

從上面的效果圖的看到。有3個菜單(首頁,銷售消息通知,銷售管理)。並且首頁這個菜單能夠點擊,執行跳轉,其它兩個菜單又有子菜單,點擊只是一個子菜單顯示與隱藏的操做。
因此,側邊欄的數據確定是一個數組,而且是一個對象數組。每一個對象至少有四個屬性(要顯示的文字,跳轉的url,是否有子菜單,是否當前菜單)。而後對於有子菜單的菜單,要給一個屬性控制是否展開顯示子菜單,要一個屬性,儲存子菜單。
以下面文字

[
    {
        菜單名:'菜單名稱(首頁)',
        跳轉的url:'url(/index)',
        是否當前標識:'一個標誌string(0)',
        是否有子菜單:'是否     true||false'
    },
    {
        菜單名:'菜單名稱(首頁)',
        跳轉的url:'url(/index)',
        是否當前標識:'一個標誌string(0)',
        是否有子菜單:'true||false',
        是否展現:'是否     true||false',
        子菜單:[]
    }
]

對於子菜單,因爲沒有子菜單了,因此須要三個屬性(要顯示的文字,跳轉的url,是否當前標識:'一個標誌string(0)')就好。因爲子菜單不止一個,因此,子子菜單這個確定也是一個數組,每一個子菜單也有屬性,因此,也是一個對象屬性,因此,數據大概以下面。

[
    {
        菜單名:'菜單名稱   (首頁)',
        跳轉的url:'url  (/index)',
        是否當前標識:'一個標誌string   (0)',
        是否有子菜單:'是否     true||false'
    },
    {
        菜單名:'菜單名稱  (首頁)',
        跳轉的url:'url  (/index)',
        是否當前標識:'一個標誌string    (1)',
        是否有子菜單:'是否     true||false',
        是否展現:'是否    true||false',
        子菜單:[
            {
                菜單名:'菜單名稱    (首頁)',
                跳轉的url:'url   (/index)',
                是否當前標識:'一個標誌string   (1_1)'
            },
            {
                菜單名:'菜單名稱   (首頁)',
                跳轉的url:'url   (/index)',
                是否當前標識:'一個標誌string   (1_2)'
            }
        ]
    }
]

最後,整理出來的數據就是!(tag這個標識數據,是我本身起的,你們也能夠隨意起。這個標識在下面會用到,在這裏能夠暫時不關注)

data(){
    return {
        currentTag: '0',
        menus: [
            {
                name: '首頁',
                url: '/index',
                tag: '0',
                hasExtend: false, //是否有二級菜單
            },
            {
                name: '銷售消息通知',
                url: '/saleR',
                tag: 'sale',
                hasExtend: true, //是否有二級菜單
                fold: true, //是否展開
                extend: [
                    {
                        name: '待確認訂單',
                        url: '/order/list/0?ordConfirmStatus=0',
                        tag: '1_1',
                    },
                    {
                        name: '待出庫物流',
                        url: '/logistics/logisticsList/0',
                        tag: '1_2'
                    },
                    {
                        name: '待發貨物流',
                        url: '/logistics/logisticsList/1',
                        tag: '1_3'
                    },
                    {
                        name: '待收貨物流',
                        url: '/logistics/logisticsList/2',
                        tag: '1_4'
                    },
                    {
                        name: '待確認回款',
                        url: '/cash/cashList/0',
                        tag: '1_5'
                    },
                    {
                        name: '待開票申請',
                        url: '/invoice/invoiceWriteList/0',
                        tagIndex: '1_6'
                    }
                ]
            },
            {
                name: '銷售管理',
                url: '/workbench',
                hasExtend: true, //是否有二級菜單
                fold: true,  //是否展開
                extend: [
                    {
                        name: '建立銷售單',
                        url: '/order/create',
                        tag: '2_1'
                    },
                    {
                        name: '銷售單管理',
                        url: '/order/list',
                        tag: '2_2'
                    },
                    {
                        name: '物流管理',
                        url: '/logistics/logisticsList',
                        tag: '2_3'
                    },
                    {
                        name: '回款管理',
                        url: '/cash/cashList',
                        tag: '2_4'
                    },
                    {
                        name: '開票管理',
                        url: '/invoice/invoiceWriteList',
                        tag: '2_9'
                    },
                    {
                        name: '票據管理',
                        url: '/invoice/invoiceManageList',
                        tag: '2_5'
                    },
                    {
                        name: '提成管理',
                        url: '/commission/commissionList',
                        tag: '2_6'
                    },
                    {
                        name: '提成設置',
                        url: '/commission/commissionSet',
                        tag: '2_7',
                    },
                    {
                        name: '合同管理',
                        url: '/contract/contractList',
                        tag: '2_8'
                    },
                ]
            },
        ],
    }
},

上面的數據相信你們都沒什麼問題,一一對應上就好(name--菜單名稱, url--跳轉的url,tag--當前的標識, hasExtend--是否有二級菜單,fold--是否展開extend--子菜單)

2.遍歷側邊欄的數據

<template>
    <ul class="snav-menu" @click="show=false">
        <li v-for="(item,index) in menus" :class="{active:item.fold,hasextend:item.hasExtend}">
            <!--若是沒有二級菜單-->
            <!--若是遍歷到的標識等於當前的標識,就加上active類名,改變樣式-->
            <!--點擊事件爲觸發跳轉路由,就好比點擊‘首頁’,就是跳轉到‘首頁’的對應的路由-->
            <a  v-if="!item.hasExtend" href="javascript:;" class="tit" @click="switchNav(item.url,item.tag)"
               :class="{active:item.tag==currentTag}">
                <em>{{item.name}}</em>
            </a>
            <!--若是有二級菜單-->
            <!--點擊事件爲觸發子元素的顯示或隱藏 好比點擊‘銷售消息通知’,就觸發‘銷售消息通知’下面子菜單的顯示或者隱藏。若是顯示就隱藏,隱藏就顯示-->
            <a v-else href="javascript:;" class="tit" @click.stop="flod(index)">
                <em>{{item.name}}</em>
            </a>
            <!--若是有二級菜單,遍歷子菜單-->
            <!--若是有二級菜單,而且fold屬性爲true(子菜單展開顯示)。就加上active類名,改變樣式-->
            <div class="extend-nav level2" v-if="item.hasExtend" :class="{active:item.fold}">
                <p v-for="(extend1,deep1) in item.extend">
                    <!--若是遍歷到的標識等於當前的標識,就加上active類名,改變樣式-->
                    <!--點擊切換路由(頁面的操做)-->
                    <a href="javascript:;" :class="{active:extend1.tag==currentTag}"
                       @click="switchNav(extend1.url,extend1.tag)">
                        <em>{{extend1.name}}</em>
                    </a>
                </p>
            </div>
        </li>
    </ul>
</template>

flodswitchNav這個兩個屬性你們暫時不須要關注,下面會用到

遍歷數據這個,你們看了上面的代碼和註釋,很好理解。我就很少說了!而後,在index.js裏面,引入和註冊這個組件。

clipboard.png

而後index.html頁面引用
clipboard.png

而後ctrl+s一下,就能夠看到效果了(前面在webpack.config.label.js已經配置了熱刷新。因此直接就能夠看到效果,保存一下,或者改了一些代碼後,一段時間沒操做了,瀏覽器都會刷新,以下圖

clipboard.png

clipboard.png

看到運行結果,側邊欄出來了。而後,下一步!

3.給側邊欄寫相關的一些操做

關於側邊欄的操做,比較簡單,無非就是點擊菜單,跳轉路由,標誌當前項以及菜單下面子菜單的顯示與隱藏。
1.首先,觸發路由的跳轉和標誌當前項
咱們用到的是是上面代碼的switchNav這個方法;
咱們簡單分析一下,這個方法,要實現跳轉路由,標誌當前項。就必需要接收兩個參數(要跳轉路由的url,當前的標識)。下面就實現下

switchNav(url,tag){
    //標識當前導航
    this.currentTag = tag;
    //router導航
    this.$router.push({
        'path': url,
        'query': {
            "tag": tag
        }
    });
}

看着代碼是否是特別簡單,每次點擊的時候,用一個變量this.currentTag記錄當前的tag,在html遍歷的時候,若是遍歷道的tag等於currentTag的話,就加上active的類名,標誌當前項,不等於就不加類名。

好比一開始‘this.currentTag='0',而後,首頁的tag又是等於'0',因此遍歷道‘首頁’的時候,就會給‘首頁’那個菜單加上active的類名’

clipboard.png
而後跳轉路由那個沒有什麼能夠說的了,就把url當成參數傳進去而已。

2.最後,實現菜單下面子菜單的顯示與隱藏。這個方法就一行代碼。

//展開收起導航面板
flod(index){
    this.menus[index].fold = !this.menus[index].fold;
},

由於只有兩級,因此,只是根據傳進來的索引(index)來操做menus這個數組而已,把要操做的項的fold屬性,取反。

運行一下,發現路由變了,當前項有標識了,子菜單的顯示與隱藏也有了!原理也很簡單。

clipboard.png

運行完了,附上這個文件(snav-component.vue)的代碼大概就是這樣

<template>
    <ul class="snav-menu" @click="show=false">
        <li v-for="(item,index) in menus" :class="{active:item.fold,hasextend:item.hasExtend}">
            <!--若是沒有二級菜單--><!--若是遍歷到的標識等於當前的標識,就加上active類名,改變樣式-->
            <a  v-if="!item.hasExtend" href="javascript:;" class="tit" @click="switchNav(item.url,item.tag)"
               :class="{active:item.tag==currentTag}">
                <em>{{item.name}}</em>
            </a>
            <!--若是有二級菜單-->
            <a v-else href="javascript:;" class="tit" @click.stop="flod(index)">
                <em>{{item.name}}</em>
            </a>
            <!--若是有二級菜單,遍歷子菜單--><!--若是有二級菜單,而且fold屬性爲true(子菜單展開顯示)。就加上active類名,改變樣式-->
            <div class="extend-nav level2" v-if="item.hasExtend" :class="{active:item.fold}">
                <p v-for="(extend1,deep1) in item.extend">
                    <!--若是遍歷到的標識等於當前的標識,就加上active類名,改變樣式--><!--點擊切換路由(頁面的操做)-->
                    <a href="javascript:;" :class="{active:extend1.tag==currentTag}"
                       @click="switchNav(extend1.url,extend1.tag)">
                        <em>{{extend1.name}}</em>
                    </a>
                </p>
            </div>
        </li>
    </ul>
</template>

<script>
    export default{
        data(){
            return {
                //記錄當前的標識
                currentTag: '0',
                menus: [
                    {
                        name: '首頁',
                        url: '/index',
                        tag: '0',
                        hasExtend: false, //是否有二級菜單
                    },
                    {
                        name: '銷售消息通知',
                        url: '/saleR',
                        tag: 'sale',
                        hasExtend: true, //是否有二級菜單
                        fold: true, //是否展開
                        extend: [
                            {
                                name: '待確認訂單',
                                url: '/order/list/0?ordConfirmStatus=0',
                                tag: '1_1',
                            },
                            {
                                name: '待出庫物流',
                                url: '/logistics/logisticsList/0',
                                tag: '1_2'
                            },
                            {
                                name: '待發貨物流',
                                url: '/logistics/logisticsList/1',
                                tag: '1_3'
                            },
                            {
                                name: '待收貨物流',
                                url: '/logistics/logisticsList/2',
                                tag: '1_4'
                            },
                            {
                                name: '待確認回款',
                                url: '/cash/cashList/0',
                                tag: '1_5'
                            },
                            {
                                name: '待開票申請',
                                url: '/invoice/invoiceWriteList/0',
                                tagIndex: '1_6'
                            }
                        ]
                    },
                    {
                        name: '銷售管理',
                        url: '/workbench',
                        hasExtend: true, //是否有二級菜單
                        fold: true,  //是否展開
                        extend: [
                            {
                                name: '建立銷售單',
                                url: '/order/create',
                                tag: '2_1'
                            },
                            {
                                name: '銷售單管理',
                                url: '/order/list',
                                tag: '2_2'
                            },
                            {
                                name: '物流管理',
                                url: '/logistics/logisticsList',
                                tag: '2_3'
                            },
                            {
                                name: '回款管理',
                                url: '/cash/cashList',
                                tag: '2_4'
                            },
                            {
                                name: '開票管理',
                                url: '/invoice/invoiceWriteList',
                                tag: '2_9'
                            },
                            {
                                name: '票據管理',
                                url: '/invoice/invoiceManageList',
                                tag: '2_5'
                            },
                            {
                                name: '提成管理',
                                url: '/commission/commissionList',
                                tag: '2_6'
                            },
                            {
                                name: '提成設置',
                                url: '/commission/commissionSet',
                                tag: '2_7',
                            },
                            {
                                name: '合同管理',
                                url: '/contract/contractList',
                                tag: '2_8'
                            },
                        ]
                    },
                ],
            }
        },
        methods: {
            //切換組件
            switchNav(url,tag){
                //標識當前導航
                this.currentTag = tag;
                //router導航
                this.$router.push({
                    'path': url,
                    'query': {
                        "tag": tag
                    }
                });
            },
            //展開收起導航面板
            flod(index){
                this.menus[index].fold = !this.menus[level1].fold;
            },
        }
    }
</script>

<style lang="scss">
    html,body,.zyl-admin-bd,.zyl-admin-wrap {
        width: 100%;
        height: 100%;
    }
    .zyl-admin-wrap{
        position: fixed;
    }
    .zyl-admin-snav {
        position: fixed;
        z-index: 1;
        width: 210px;
        height: 100%;
        overflow-y: auto;
        background: #2a3542;
        box-shadow: 3px 0 30px rgba(0, 0, 0, .2);
        &::-webkit-scrollbar {
            width: 5px;
            height: 100%;
            border-radius: 2px;
            background: #424448;
        }
        &::-webkit-scrollbar-thumb {
            background: #A2A2A2;
            border-radius: 2px;
        }
        .snav-menu {
            margin-top: 10px;
            > li {
                margin:0 10px 10px 10px;
                &.hasextend {
                    .tit {
                        background: #35404d;
                    }
                }
                &.active {
                    background: #35404d;
                    border-radius: 4px;
                    overflow: hidden;
                    .tit {
                        background: #475669 !important;
                        .icon-options-unfold {
                            display: none;
                        }
                        .icon-options-fold {
                            display: inline-block;
                        }
                    }
                    .extend-nav {
                        display: block;
                    }

                }
                .tit {
                    line-height: 22px;
                    color: #aeb2b7;
                    text-decoration: none;
                    display: block;
                    padding: 5px 0 5px 10px;
                    font-size: 12px;
                    outline: none;
                    transition: all 0.3s ease;
                    &:hover, &.active {
                        background: #35404d;
                        color: #fff;
                        em {
                            color: #FF6C60;
                        }
                    }
                    em {
                        display: inline-block;
                        vertical-align: middle;
                        font-style: normal;
                    }
                }
                .extend-nav {
                    display: none;
                    &.active {
                        display: block;
                    }
                    p {
                        position: relative;
                        a {
                            display: block;
                            font-size: 12px;
                            padding: 6px 0;
                            line-height: 25px;
                            height: 25px;
                            color: #aeb2b7;
                            text-decoration: none;
                            transition: all 0.3s ease;
                            text-indent: 40px;
                            &:hover, &.active {
                                color: #FF6C60;
                                background: #2e3844;
                                .icon-arrow {
                                    display: inline-block;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    .zyl-admin-content {
        height: 100%;
        margin-left: 210px;
        overflow-y: auto;
        &::-webkit-scrollbar {
            width: 5px;
            height: 100%;
            border-radius: 2px;
            background: #424448;
        }
        &::-webkit-scrollbar-thumb {
            background: #A2A2A2;
            border-radius: 2px;
        }
        .wrapper {
            box-sizing: border-box;
            width: 100%;
            height: 100%;
            &::-webkit-scrollbar {
                width: 5px;
                height: 100%;
                border-radius: 2px;
                background: #424448;
            }
            &::-webkit-scrollbar-thumb {
                background: #A2A2A2;
                border-radius: 2px;
            }
        }
    }
</style>

有一點要注意下,除了點擊首頁能看到一張圖片以外,點擊其它的菜單,右邊都是白色的一片。由於其它的菜單的url。並無對應的組件。

好比:這個url在路由裏面並無對應的組件。

clipboard.png

怎麼知道?在上一篇文件說到的router.js裏面,並無配置‘/order/list/0?ordConfirmStatus=0’這個url對應的組件。因此在index.html<router-view></router-view>輸出的就是空白的一片。如今這裏算是複習上一篇的內容了。也是給下一篇埋了一個伏筆。下一篇就講這個配置。
clipboard.png

4.未完待續

今天就到這裏了。主要就是一個主頁面,主要是側邊欄的一個開發。這個側邊欄就是根據控制錄用的變化。技術棧主要也就是vuevue-router。原理就是根據路由的變化執行組件的切換。達到一個頁面跳轉的效果。下一篇就會說到,配置路由和路由對應的組件。但願能幫到你們。最後仍是那句老話-若是你們發現我哪裏寫錯了,或者是哪裏寫得很差,歡迎指點下。

相關文章
相關標籤/搜索