webpack+vue project (2, development and management system homepage)

Keywords: Javascript Attribute Vue Webpack

1. Preface

Last article( webpack+vue project reality (1, build running environment and related configuration) ) Build a basic project catalogue, secure some dependencies to be used, and run the project. Next, we will proceed to the second step of operation, the second step is to do a good job of the main page of the development system, this page is mainly a sidebar, through the various options of the sidebar to operate (switching components). For example, repayment management, order management, logistics management and so on.

2. Top components

It's time to introduce a common style in index.js, which is equivalent to a style reset table.

There's one requirement. You need to put an exit login button on the page. I wrote a file for the top component. The first step is to create this file.

The code is as follows

<template>
    <div class="topbar">
        <el-button class="fr mr30 mt15" type="primary" size="small" @click="loginOut">Log out</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>

Then the entry file (index.js) refers to this file and registers the component import topbar Component from'. /. / components / admin_base / topbar. vue'in vue.

Then import the template file, index.html, and import the label

Page results (based on the results of the previous article that have already run)

The class es on the page have written styles in common styles, and some are provided by element-ui.
< el-button > logout </el-button > is the component provided by element-ui, and element-ui has been introduced in the entry file index.js. Just use it here!

It's relatively simple, so I won't say much about it.

3. Side Bar Components

This sidebar is the focus of this article, and also the focus of the whole project operation. First create such a sidebar component file on the directory.

The following pictures are the effect we want to achieve. I don't say much about the style of typesetting. I believe it won't be difficult for you.

1. First, create the data needed for this sidebar

Seen from the effect diagram above. There are three menus (Home page, Sales Message Notification, Sales Management). And the home page menu can be clicked to perform jumps, the other two menus have sub-menus, clicking is only a sub-menu display and hidden operation.
So the sidebar data must be an array and an array of objects. Each object has at least four attributes (the text to be displayed, the url to be jumped, whether there is a submenu, whether there is a current menu). Then for menus with submenus, we need to give an attribute to control whether to expand the display submenu, and we need an attribute to store the submenu.
As follows

[
    {
        Menu Name:'Menu Name (Home Page)',
        Jump url:'url(/index)',
        Is the current identifier:'A flag string(0)'?
        Is there a submenu:'true||false'
    },
    {
        Menu Name:'Menu Name (Home Page)',
        Jump url:'url(/index)',
        Is the current identifier:'A flag string(0)'?
        Is there a submenu:'true | false'?
        Whether to show:'true | false',
        Submenu: []
    }
]

For submenu, since there is no submenu, three attributes are needed (text to be displayed, url to jump, whether the current identifier is:'a flag string(0)'). Since there are more than one submenu, so the submenu must also be an array, each submenu has attributes, so it is also an object attribute, so the data is probably as follows.

[
    {
        Menu Name:'Menu Name (Home Page)',
        Jump url:'url (/ index)',
        Is the current identifier:'A flag string (0)'?
        Is there a submenu:'Is it true||false'
    },
    {
        Menu Name:'Menu Name (Home Page)',
        Jump url:'url (/ index)',
        Is the current identifier:'a flag string (1)'?
        Is there a submenu:'Is it true | false'?
        Is it displayed:'Is it true | false'?
        Submenu:[
            {
                Menu Name:'Menu Name (Home Page)',
                Jump url:'url (/ index)',
                Is the current identifier:'A flag string (1_1)'
            },
            {
                Menu Name:'Menu Name (Home Page)',
                Jump url:'url (/ index)',
                Is the current identifier:'A flag string (1_2)'
            }
        ]
    }
]

Finally, the data is sorted out! (tag, the identification data, is my own, you can also start at will. This logo will be used below, where you can ignore it for the time being.

data(){
    return {
        currentTag: '0',
        menus: [
            {
                name: 'home page',
                url: '/index',
                tag: '0',
                hasExtend: false, //Is there a secondary menu?
            },
            {
                name: 'Sales Information Notification',
                url: '/saleR',
                tag: 'sale',
                hasExtend: true, //Is there a secondary menu?
                fold: true, //Whether to expand or not
                extend: [
                    {
                        name: 'Confirmed order',
                        url: '/order/list/0?ordConfirmStatus=0',
                        tag: '1_1',
                    },
                    {
                        name: 'Out-of-warehouse Logistics',
                        url: '/logistics/logisticsList/0',
                        tag: '1_2'
                    },
                    {
                        name: 'Standby cargo flow',
                        url: '/logistics/logisticsList/1',
                        tag: '1_3'
                    },
                    {
                        name: 'Received cargo flow',
                        url: '/logistics/logisticsList/2',
                        tag: '1_4'
                    },
                    {
                        name: 'Recognized Return',
                        url: '/cash/cashList/0',
                        tag: '1_5'
                    },
                    {
                        name: 'Pending application for invoice',
                        url: '/invoice/invoiceWriteList/0',
                        tagIndex: '1_6'
                    }
                ]
            },
            {
                name: 'Sales Management',
                url: '/workbench',
                hasExtend: true, //Is there a secondary menu?
                fold: true,  //Whether to expand or not
                extend: [
                    {
                        name: 'Create sales orders',
                        url: '/order/create',
                        tag: '2_1'
                    },
                    {
                        name: 'Sales Order Management',
                        url: '/order/list',
                        tag: '2_2'
                    },
                    {
                        name: 'Physical distribution management',
                        url: '/logistics/logisticsList',
                        tag: '2_3'
                    },
                    {
                        name: 'Payment Management',
                        url: '/cash/cashList',
                        tag: '2_4'
                    },
                    {
                        name: 'Invoice management',
                        url: '/invoice/invoiceWriteList',
                        tag: '2_9'
                    },
                    {
                        name: 'Bill Management',
                        url: '/invoice/invoiceManageList',
                        tag: '2_5'
                    },
                    {
                        name: 'Commission Management',
                        url: '/commission/commissionList',
                        tag: '2_6'
                    },
                    {
                        name: 'Commission settings',
                        url: '/commission/commissionSet',
                        tag: '2_7',
                    },
                    {
                        name: 'contract management',
                        url: '/contract/contractList',
                        tag: '2_8'
                    },
                ]
            },
        ],
    }
},

The above data is believed to be all right, just one by one (name -- menu name, URL -- jump url,tag -- current logo, hasExtend -- whether there is a secondary menu, fold -- expand -- submenu)

2. Data traversing sidebars

<template>
    <ul class="snav-menu" @click="show=false">
        <li v-for="(item,index) in menus" :class="{active:item.fold,hasextend:item.hasExtend}">
            <! - If there is no secondary menu --> ___________
            <! -- If the traversed identifier equals the current identifier, add the name of the active class and change the style - >
            <! - Click on the event to trigger the jump routing, such as clicking on'Home Page', which is the corresponding route to jump to'Home Page'- >
            <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>
            <! - If there's a secondary menu - > ___________
            <! - Click events to trigger the display or hiding of sub-elements, such as clicking on'Sales Message Notification', trigger the display or hiding of sub-menus under'Sales Message Notification'. If the display is hidden, the hide is displayed - >.
            <a v-else href="javascript:;" class="tit" @click.stop="flod(index)">
                <em>{{item.name}}</em>
            </a>
            <! - If there is a secondary menu, traverse the submenu - >
            <! -- If there is a secondary menu, and the fold attribute is true (submenu expansion display). Add the name of the active class and change the style - >.
            <div class="extend-nav level2" v-if="item.hasExtend" :class="{active:item.fold}">
                <p v-for="(extend1,deep1) in item.extend">
                    <! -- If the traversed identifier equals the current identifier, add the name of the active class and change the style - >
                    <! - Click Switch Routing (Page Operations) -->
                    <a href="javascript:;" :class="{active:extend1.tag==currentTag}"
                       @click="switchNav(extend1.url,extend1.tag)">
                        <em>{{extend1.name}}</em>
                    </a>
                </p>
            </div>
        </li>
    </ul>
</template>

flod and switchNav are two attributes that you don't need to pay attention to for the time being.

Traversing through the data, you have seen the above code and comments, very good understanding. I won't say much! Then, in index.js, the component is introduced and registered.

Then the index.html page reference

Then ctrl+s, you can see the effect (previously in webpack.config.label.js has been configured with hot refresh. So you can directly see the effect, save it, or change some code, after a period of time no operation, the browser will refresh, as shown below.

Seeing the result of the operation, the sidebar came out. Then, next step!

3. Write down some operations related to the sidebar

About the operation of the sidebar, it is relatively simple, just click on the menu, jump routing, mark the current item and the display and hiding of the submenu under the menu.
1. First, trigger the routing jump and flag the current item
We use the switchNav method of the above code.
Let's briefly analyze this method to realize jump routing and mark the current item. You have to accept two parameters (to jump the url of the route, the current identity). Here's the implementation

switchNav(url,tag){
    //Identify the current navigation
    this.currentTag = tag;
    //router navigation
    this.$router.push({
        'path': url,
        'query': {
            "tag": tag
        }
    });
}

Look at the code is not particularly simple, every click, with a variable this.currentTag record the current tag, in html traversal, if the tag traversal is equal to currentTag, then add the active class name, mark the current item, does not mean not add the class name.

For example,'this. current Tag='0'at the beginning, and then the tag on the home page is equal to'0', so when traversing the'home page', the menu of'home page' will be given the class name of activity.


Then jump routing, which has nothing to say, just pass in url as a parameter.

2. Finally, display and hide the submenu under the menu. This method is one line of code.

 //Unfold the Navigation Panel
flod(index){
    this.menus[index].fold = !this.menus[index].fold;
},

Because there are only two levels, the menus array is manipulated only according to the incoming index, and the fold attribute of the item to be manipulated is reversed.

Run it and find that the routing has changed, the current item has been marked, and the display and hiding of submenu have also been done! The principle is also simple.

Running out, the code attached to this file (snav-component.vue) is probably like this.

<template>
    <ul class="snav-menu" @click="show=false">
        <li v-for="(item,index) in menus" :class="{active:item.fold,hasextend:item.hasExtend}">
            <!--If there is no secondary menu--><!--If the logo traversed equals the current logo, add active Class name, change style-->
            <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>
            <!--If there is a secondary menu-->
            <a v-else href="javascript:;" class="tit" @click.stop="flod(index)">
                <em>{{item.name}}</em>
            </a>
            <!--If you have a secondary menu, traverse the submenu--><!--If there is a secondary menu, and fold Attribute is true(Submenu expansion display. Add active Class name, change style-->
            <div class="extend-nav level2" v-if="item.hasExtend" :class="{active:item.fold}">
                <p v-for="(extend1,deep1) in item.extend">
                    <!--If the logo traversed equals the current logo, add active Class name, change style--><!--Click Switch Routing (Page Operation)-->
                    <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 {
                //Record the current identity
                currentTag: '0',
                menus: [
                    {
                        name: 'home page',
                        url: '/index',
                        tag: '0',
                        hasExtend: false, //Is there a secondary menu?
                    },
                    {
                        name: 'Sales Information Notification',
                        url: '/saleR',
                        tag: 'sale',
                        hasExtend: true, //Is there a secondary menu?
                        fold: true, //Whether to expand or not
                        extend: [
                            {
                                name: 'Confirmed order',
                                url: '/order/list/0?ordConfirmStatus=0',
                                tag: '1_1',
                            },
                            {
                                name: 'Out-of-warehouse Logistics',
                                url: '/logistics/logisticsList/0',
                                tag: '1_2'
                            },
                            {
                                name: 'Standby cargo flow',
                                url: '/logistics/logisticsList/1',
                                tag: '1_3'
                            },
                            {
                                name: 'Received cargo flow',
                                url: '/logistics/logisticsList/2',
                                tag: '1_4'
                            },
                            {
                                name: 'Recognized Return',
                                url: '/cash/cashList/0',
                                tag: '1_5'
                            },
                            {
                                name: 'Pending application for invoice',
                                url: '/invoice/invoiceWriteList/0',
                                tagIndex: '1_6'
                            }
                        ]
                    },
                    {
                        name: 'Sales Management',
                        url: '/workbench',
                        hasExtend: true, //Is there a secondary menu?
                        fold: true,  //Whether to expand or not
                        extend: [
                            {
                                name: 'Create sales orders',
                                url: '/order/create',
                                tag: '2_1'
                            },
                            {
                                name: 'Sales Order Management',
                                url: '/order/list',
                                tag: '2_2'
                            },
                            {
                                name: 'Physical distribution management',
                                url: '/logistics/logisticsList',
                                tag: '2_3'
                            },
                            {
                                name: 'Payment Management',
                                url: '/cash/cashList',
                                tag: '2_4'
                            },
                            {
                                name: 'Invoice management',
                                url: '/invoice/invoiceWriteList',
                                tag: '2_9'
                            },
                            {
                                name: 'Bill Management',
                                url: '/invoice/invoiceManageList',
                                tag: '2_5'
                            },
                            {
                                name: 'Commission Management',
                                url: '/commission/commissionList',
                                tag: '2_6'
                            },
                            {
                                name: 'Commission settings',
                                url: '/commission/commissionSet',
                                tag: '2_7',
                            },
                            {
                                name: 'contract management',
                                url: '/contract/contractList',
                                tag: '2_8'
                            },
                        ]
                    },
                ],
            }
        },
        methods: {
            //Switching component
            switchNav(url,tag){
                //Identify the current navigation
                this.currentTag = tag;
                //router navigation
                this.$router.push({
                    'path': url,
                    'query': {
                        "tag": tag
                    }
                });
            },
            //Unfold the Navigation Panel
            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>

One thing to note is that besides clicking on the home page to see a picture, clicking on other menus, the right side is white. Because of the url of other menus. There is no corresponding component.

For example, this url has no corresponding component in the routing.

How do you know? In router.js mentioned in the previous file, there is no component corresponding to the url'/ order/list/0?ordConfirmStatus=0'. So the output of <router-view> </router-view> in index.html is a blank piece. Now here is a review of the content of the last article. It's also a foreshadowing for the next article. This configuration will be discussed in the next article.

4. Unfinished

That's all for today. Mainly a main page, mainly a sidebar development. This sidebar is based on changes in hiring control. The technology stack is mainly Vue and vue-router. The principle is to switch components according to changes in routing. To achieve a page Jump effect. The next article will talk about configuring the components that correspond to routing and routing. I hope I can help you. Finally, there's the old saying - if you find out where I'm wrong or where I'm not good, please give me some advice.

Posted by paddymull on Sun, 16 Jun 2019 17:20:07 -0700