前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >webpack+vue项目实战(二,开发管理系统主页面)

webpack+vue项目实战(二,开发管理系统主页面)

作者头像
守候i
发布2018-08-22 17:52:43
1.5K0
发布2018-08-22 17:52:43
举报
文章被收录于专栏:守候书阁守候书阁

1.前言

上篇文章(webpack+vue项目实战(一,搭建运行环境和相关配置))搭建了好了基本的一个项目目录,安好好了一些要用到的依赖,以及把项目跑了起来。接下来,我们就进行第二步的操作,第二步就是做好一个开发系统的主页面,这个页面主要也就是一个侧边栏,通过侧边栏的各个选项来进行操作(切换各个组件)。比如回款管理,订单管理,物流管理等等的操作。

2.顶部组件

开始属于排版这一块了,是时候在index.js引入一个公用样式了,相当于一个样式重置表。

需求有一个,页面上面需要放一个退出的登录按钮,我就写了一个顶部组件的文件。首先就是创建这个文件

代码如下

代码语言:javascript
复制
<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';

然后入口模板文件,index.html引入标签

页面结果(基于上一篇文章,已经跑起来的结果)

页面上的class在公用样式里面有写好样式,还有一些样式是element-ui提供的, <el-button>退出登录</el-button>就是element-ui提供的组件,在入口文件index.js已经引入了element-ui。这里直接用就好!

这个比较简单,我就不多说了。

3.侧边栏组件

这个侧边栏就是这篇文章的重点,也是整个项目操作的重点。先在目录上创建这样一个的侧边栏的组件文件。

下面图片是我们要实现的效果,那些排版切图的样式我不多说了,相信不会难倒大家

1.首先,创建一下这个侧边栏所需要的数据

从上面的效果图的看到。有3个菜单(首页,销售消息通知,销售管理)。而且首页这个菜单可以点击,执行跳转,其它两个菜单又有子菜单,点击只是一个子菜单显示与隐藏的操作。

所以,侧边栏的数据肯定是一个数组,并且是一个对象数组。每个对象至少有四个属性(要显示的文字,跳转的url,是否有子菜单,是否当前菜单)。然后对于有子菜单的菜单,要给一个属性控制是否展开显示子菜单,要一个属性,储存子菜单。

如下面文字

代码语言:javascript
复制
[
    {
        菜单名:'菜单名称(首页)',
        跳转的url:'url(/index)',
        是否当前标识:'一个标志string(0)',
        是否有子菜单:'是否     true||false'
    },
    {
        菜单名:'菜单名称(首页)',
        跳转的url:'url(/index)',
        是否当前标识:'一个标志string(0)',
        是否有子菜单:'true||false',
        是否展示:'是否     true||false',
        子菜单:[]
    }
]

对于子菜单,由于没有子菜单了,所以需要三个属性(要显示的文字,跳转的url,是否当前标识:'一个标志string(0)')就好。由于子菜单不止一个,所以,子子菜单这个肯定也是一个数组,每个子菜单也有属性,所以,也是一个对象属性,所以,数据大概如下面。

代码语言:javascript
复制
[
    {
        菜单名:'菜单名称   (首页)',
        跳转的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这个标识数据,是我自己起的,大家也可以随意起。这个标识在下面会用到,在这里可以暂时不关注)

代码语言:javascript
复制
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.遍历侧边栏的数据

代码语言:javascript
复制
<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里面,引入和注册这个组件。

然后index.html页面引用

然后ctrl+s一下,就可以看到效果了(前面在**webpack.config.label.js**已经配置了热刷新。所以直接就可以看到效果,保存一下,或者改了一些代码后,一段时间没操作了,浏览器都会刷新,如下图

看到运行结果,侧边栏出来了。然后,下一步!

3.给侧边栏写相关的一些操作

关于侧边栏的操作,比较简单,无非就是点击菜单,跳转路由,标志当前项以及菜单下面子菜单的显示与隐藏。

1.首先,触发路由的跳转和标志当前项

我们用到的是是上面代码的switchNav这个方法;

我们简单分析一下,这个方法,要实现跳转路由,标志当前项。就必须要接收两个参数(要跳转路由的url,当前的标识)。下面就实现下

代码语言:javascript
复制
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的类名’

然后跳转路由那个没有什么可以说的了,就把url当成参数传进去而已。

2.最后,实现菜单下面子菜单的显示与隐藏。这个方法就一行代码。

代码语言:javascript
复制
 //展开收起导航面板
flod(index){
    this.menus[index].fold = !this.menus[index].fold;
},

因为只有两级,所以,只是根据传进来的索引(index)来操作menus这个数组而已,把要操作的项的fold属性,取反。

运行一下,发现路由变了,当前项有标识了,子菜单的显示与隐藏也有了!原理也很简单。

运行完了,附上这个文件(snav-component.vue)的代码大概就是这样

代码语言:javascript
复制
<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在路由里面并没有对应的组件。

怎么知道?在上一篇文件说到的router.js里面,并没有配置‘/order/list/0?ordConfirmStatus=0’这个url对应的组件。所以在index.html<router-view></router-view>输出的就是空白的一片。现在这里算是复习上一篇的内容了。也是给下一篇埋了一个伏笔。下一篇就讲这个配置。

4.未完待续

今天就到这里了。主要就是一个主页面,主要是侧边栏的一个开发。这个侧边栏就是根据控制录用的变化。技术栈主要也就是vuevue-router。原理就是根据路由的变化执行组件的切换。达到一个页面跳转的效果。下一篇就会说到,配置路由和路由对应的组件。希望能帮到大家。最后还是那句老话-如果大家发现我哪里写错了,或者是哪里写得不好,欢迎指点下。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年07月04日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.前言
  • 2.顶部组件
  • 3.侧边栏组件
    • 1.首先,创建一下这个侧边栏所需要的数据
      • 2.遍历侧边栏的数据
        • 3.给侧边栏写相关的一些操作
        • 4.未完待续
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档