bootstrap vue 后台管理_bootstrap-vue 管理后台 - CSDN
  • 撰写本文档目的是让后续开发者在理解该系统架构的基础上遵循一定规范保持系统架构的合理性;同时也能够达到允许没有开发经验仅有web基础的入门开发者能够通过复制粘贴的方式仿照demo示例进行开发的目的。...

    撰写本文档目的是让后续开发者在理解该系统架构的基础上遵循一定规范保持系统架构的合理性;同时也能够达到允许没有开发经验仅有web基础的入门开发者能够通过复制粘贴的方式仿照demo示例进行开发的目的。

     

    目  录

    1       案例调研与选取... 2

    1.1      案例调研... 2

    1.2      UI选取... 3

    2       系统实现... 3

    2.1      实现效果... 3

    2.2      开发规范... 6

    3       详细设计... 7

    3.1      框架介绍... 7

    3.2      数据库设计... 8

    3.3      菜单管理... 8

    3.4      权限管理/角色管理... 11

    3.5      权限管理/权限分配... 13

    3.6      权限管理/用户管理... 14

    4       延伸思考... 14

    5       致谢! 14

    6       文档说明... 15

    7       参考文献... 15

     

     

     

    1. 案例调研与选取
      1. 案例调研

    1)easyUI(No1)

    图片

    2)easyUI(No2)

    图片

    3)Bootstrap

    图片

    4)vue/iview

    图片

     

    以上四套UI框架对比分析,可以得出如下结论

    结论:

    easyUI功能完善,界面简洁友好,非常方便后端开发人员开发,是优秀的前端开源框架,尤其适合后台管理,但是非响应式,页面不会随屏幕大小而变化,美观方面(仁者见仁);

    bootstrap是响应式开源框架,支持插件广泛,界面相对酷炫,美观方面(有目共睹),同样也非常适合管理平台的开发;

    至于Vue和其它一些前端人员自己写的UI框架,必须要承认Vue是不错的开源框架,但是个人感觉对管理平台来说Vue增加了开发人员的学习成本、兼容性、美观等方面的调试成本,开发周期偏长,至于是否适合管理品台开发就……;

    综上分析,对于管理平台开发建议选用easyUI或基于bootstrap搭建好的管理平台,本文选择基于bootstrap的管理平台进行说明。

     

      1. UI选取

    经过调研,选取了一套业内好评率较高的UI(ace-master),

    Ace是一个基于Twitter bootstrap3开发的后台模板。

    GitHub Ace地址:https://github.com/bopoda/ace

    Ace演示:http://ace.jeka.by/

    主体界面如下:

     

     

     

    此框架功能多多,详细功能请看演示。

     

     

    1. 系统实现
      1. 实现效果
    1. 登录

    2)首页

    3)以下是权限管理的具体模块

     

     

     

     

     

     

     

     

      1. 开发规范

    下图为框架的三个区域,其中主面板区域采用为一个div(没有采用iframe设计),每个菜单的内容均会更新主面板区域,故在主面板区域内容需要遵循一定的规范:

    1. 建议每个一级菜单在一个包中,每个包中的二级菜单均为一个单独的控制器。建议页面也需按同样方式设计。
    2. 每个页面中的字段必须全局唯一(very import

    每个页面中的字段可采用驼峰式也可用下划线式,但必须确保每个页面以及下面多级页面中的每个字段名必须不同(即使业务上为同一张表的同一个字段),不可在模态框与主面板区用同一个页面。(如此设计的原因是:由于主页面采用div设计,故为防止js检测异常)

    1. (important)由于主面板区域采用div设计,父页面(main.jsp)中已经有了

    <script src="view/manage/assets/js/jquery-2.1.4.min.js"></script>

    故子页面面不要引入这个js了(也无需引入),否则会引起密码修改的模态框无法弹出;

    如果想要引入的话,请修改密码修改的模态框弹出效果。

     

     

    命名规范示例:

    每个页面中字段命名(包括方法名、表单字段、div等元素的id等):  模块名+页面名+数据库字段名

    示例:userManageListAccountName

           或者    user_manage_list_account_name

    这样组成了全局唯一字段,防止浏览器缓存导致的页面插件功能异常和表单提交异常等问题;

     

     

    1. 详细设计
      1. 框架介绍

    1)页面布局

    页面布局见开发规范中截图,三个主要区域。

    2)功能

    功能上主要为权限管理和其它的项目相关的开发人员自定义的菜单模块。前后端交互采用ajax技术,页面核心的公共区域的交互在

    <script src="view/manage/assets/js-ylz/utils.js"></script> 该文件中封装了菜单url调用和菜单效果切花、主面板区域更新的ajax、菜单树的动态加载、解析、拼装等功能。

    3)权限

    权限管理中包括用户管理、菜单管理、角色管理、权限分配和密码修改。

    4)菜单加载

    用户状态为启用时可登录到系统,进入到主板面后根据用户对应角色查找相应的菜单加载到菜单区域,从而实现不同角色的用户能够看到不同的菜单权限。

    5)插件

    框架中整合的插件主要如下(部分):

    Bootstrap-table、bootstrap-datetimepicker、jquery.gritter(右上角弹框插件)、bootstrap-treeview、bootstrap-switch、jQuery.ui(确认框)。

    其中datetimepicker样式似乎并没有想象中的好,需要进一步确认原因还是切换其它插件,如果对样式要求不高可临时使用,但考虑到后续扩展,故而建议尽快确认(修复or更换)。

      1. 数据库设计

    数据库中权限管理模块设计了用户表、角色表、菜单表、用户角色关联表、角色菜单关联表,共计5张表,sql代码详见数据库文件。

    用户表:

     

    角色表:

     

    菜单表:

     

    用户角色关联表:

     

    角色菜单关联表:

     

      1. 菜单管理

    菜单包括主页面菜单区域的菜单也包含“权限管理à菜单管理”中的菜单。

     

    1)主页菜单封装:

    菜单表设计,见数据库设计。

    菜单最大设计四级菜单,拼装的json格式(下文为大致示例,以实际为准);

     

    读取库中菜单信息,拼接采用何种算法?

    方案一:循环遍历,多重循环遍历

    方案二:递归

    此处选择递归,原因一是效率高(内存需要或许也高,完全可容忍),二是不受限于菜单级别,

    递归核心代码如下(详见源码

    /**
    
          * 递归查找子菜单
    
          * @param id
    
          * @param rootMenu
    
          * @return
    
          */
    
         private List<Map> getChilds(Long id, List<SysMenu> rootMenu){
    
             // 子菜单
    
             List<Map> childList = new ArrayList<Map>();
    
            
    
             Iterator<SysMenu> it = rootMenu.iterator();
    
             while(it.hasNext()) {
    
                  SysMenu menu = it.next();
    
                  // 遍历所有节点,将父菜单id与传过来的id比较
    
                  if (String.valueOf(menu.getLong("menu_pa_id")).equals(String.valueOf(id))){
    
                       Map<String,Object> mapcc = new HashMap<String,Object>();
    
                       mapcc.put("id", menu.getLong("id"));
    
                       mapcc.put("menu_name", menu.getStr("menu_name"));
    
                       mapcc.put("menu_url", menu.getStr("menu_url"));
    
                       childList.add(mapcc);
    
                       it.remove();
    
                  }
    
             }
    
             // 把子菜单的子菜单再循环一遍
    
             for (Map map : childList) {
    
                  //递归
    
                  map.put("childMenus", getChilds(Long.parseLong(map.get("id").toString()), rootMenu));
    
             }
    
             //递归退出条件
    
             if (childList.size() == 0) {
    
                  return null;
    
             }
    
             return childList;
    
         }
    
    拼接得到json菜单格式为(如下为二级菜单示例,其它详见源码、界面操作):
    
    {
        "status":"200",
        "data":[
            {
                "id":1,
                "childMenus":null,
                "menu_url":"/manage/systemInfo.do",
                "menu_name":"系统信息"
            },
            {
                "id":2,
                "childMenus":[
                    {
                        "id":5,
                        "childMenus":null,
                        "menu_url":"/redis/main.do",
                        "menu_name":"查询redis"
                    },
                    {
                        "id":6,
                        "childMenus":null,
                        "menu_url":"/redis/writeRdisPage.do",
                        "menu_name":"写redis"
                    }
                ],
                "menu_url":null,
                "menu_name":"redis管理"
            },
            {
                "id":3,
                "childMenus":[
                    {
                        "id":7,
                        "childMenus":null,
                        "menu_url":null,
                        "menu_name":"榴莲短视频"
                    },
                    {
                        "id":8,
                        "childMenus":null,
                        "menu_url":"/haohuolab/haohuoPage.do",
                        "menu_name":"东龙实验室"
                    }
                ],
                "menu_url":null,
                "menu_name":"东龙实验室"
            },
            {
                "id":4,
                "childMenus":[
                    {
                        "id":9,
                        "childMenus":null,
                        "menu_url":"/system/users/userPages.do",
                        "menu_name":"用户管理"
                    },
                    {
                        "id":10,
                        "childMenus":null,
                        "menu_url":null,
                        "menu_name":"角色管理"
                    },
                    {
                        "id":11,
                        "childMenus":null,
                        "menu_url":null,
                        "menu_name":"权限分配"
                    },
                    {
                        "id":12,
                        "childMenus":null,
                        "menu_url":null,
                        "menu_name":"菜单管理"
                    },
                    {
                        "id":13,
                        "childMenus":null,
                        "menu_url":"/manage/updatePwdPages.do",
                        "menu_name":"密码修改"
                    }
                ],
                "menu_url":null,
                "menu_name":"权限管理"
            }
        ],
        "msg":"success"
    }

     

    2)菜单解析

    上面是拼接菜单代码,下面是解析菜单代码:

    解析菜单的时候踩了一个坑,就是二级菜单在浏览器端始终无法打开,反复调试到晚上十一二点始终不知道什么原因,第二天来了之后继续调试,最终发现是a标签上缺少了一个属性(class='dropdown-toggle'),有时可能就是很小的一个问题让你耽误很长很长的时间还弄的自己焦头烂额,深感有时阻碍你前进的可能不是那万里征程(搭建整套完善框架),却可能是脚下的一粒沙子。

     

    废话少说,直接上递归核心代码(实际略有改动,详见源码):

    /**
    
     * 递归遍历子树
    
     * @param list
    
     */
    
    function mainPageRecurSubTree(ctx,list){
    
             if(null==list || ""==list || "null"==list){
    
                       return "";
    
             }
    
             var mainPageRecurSubTreeStr = "";
    
             mainPageRecurSubTreeStr +=
    
                       "<ul class='submenu'>";
    
             for(var m=0;m<list.length;m++){
    
                       var menuSub = list[m];
    
                       mainPageRecurSubTreeStr +=
    
                                "<li class='' id='mainPageMenuTreeId"+menuSub.id+"'>"+
    
                                         "<a onclick=\"javascript:updateMenuTree('mainPageMenuTreeId"+menuSub.id+"','"+ctx+"','"+menuSub.menu_url+"');\" class='dropdown-toggle'>"+
    
                                                   "<i class='menu-icon fa fa-caret-right'></i>"+
    
                                                   menuSub.menu_name;
    
                                                   if(null!=menuSub.childMenus && ""!=menuSub.childMenus && "null"!=menuSub.childMenus){
    
                                                            mainPageRecurSubTreeStr +=
    
                                                            "<b class='arrow fa fa-angle-down'></b>";
    
                                                   }
    
                       mainPageRecurSubTreeStr +=
    
                                         "</a>"+
    
                                         "<b class='arrow'></b>"+
    
                                         mainPageRecurSubTree(ctx,menuSub.childMenus)+
    
                                "</li>";
    
             }
    
             mainPageRecurSubTreeStr +=
    
                       "</ul>";
    
             return mainPageRecurSubTreeStr;
    
    }

     

    3)权限管理/菜单管理

    菜单插件采用bootstrap-treeview插件,

    开关按钮采用bootstrap-switch插件;注意:将所需的开关插件放入到main.jsp中,开关样式方可正常引用,否则如果放到每个功能模块的子页面中会导致插件无法完全加载而导致的样式显示的问题。

    菜单管理页面中添加根菜单,也可添加子菜单,选择/修改菜单的上级菜单,修改菜单信息等功能。

     

      1. 权限管理/角色管理

    权限管理à角色管理:

    角色管理中的菜单权限修改(修改角色对应的菜单信息):

    也采用了bootstrap-TreeView插件,但是此原生的树菜单没有级联选项,故添加级联选择的js,核心代码如下:

    //级联选择:选中
    
                          $("#roleManageUpdateRoleMenuAllTreeMes").on('nodeChecked',function(event,node){
    
                                         roleManageUpdateRoleMenuNodeChecked(event, node);;
    
                                     });
    
                                     //级联选择:取消选中
    
                                     $("#roleManageUpdateRoleMenuAllTreeMes").on('nodeUnchecked',function(event,node){
    
                                         roleManageUpdateRoleMenuNodeUnchecked(event, node);;
    
                                     });
    
    //如下是响应菜单选中和取消选中的操作
    
                  var roleManageUpdateRoleMenuNodeCheckedSilent = false;
    
                  function roleManageUpdateRoleMenuNodeChecked(event, node){
    
                       if(roleManageUpdateRoleMenuNodeCheckedSilent){
    
                            return;
    
                       }
    
                       roleManageUpdateRoleMenuNodeCheckedSilent = true;
    
                       roleManageUpdateRoleMenuCheckAllParent(node);
    
                       roleManageUdpateRoleMenuCheckAllSon(node);
    
                       roleManageUpdateRoleMenuNodeCheckedSilent = false;
    
                  }
    
    
    
                  var roleManageUpdateRoleMenuNodeUncheckedSilent = false;
    
                  function roleManageUpdateRoleMenuNodeUnchecked(event, node){
    
                       if(roleManageUpdateRoleMenuNodeUncheckedSilent){
    
                           return;
    
                       }
    
                       roleManageUpdateRoleMenuNodeUncheckedSilent = true;
    
                       roleManageUpdateRoleMenuUncheckAllParent(node);
    
                       roleManageUpdateRoleMenuUncheckAllSon(node);
    
                       roleManageUpdateRoleMenuNodeUncheckedSilent = false;
    
                  }
    
    
    
                  //选中全部父节点
    
                  function roleManageUpdateRoleMenuCheckAllParent(node){
    
                       $("#roleManageUpdateRoleMenuAllTreeMes").treeview('checkNode',node.nodeId,{silent:true});
    
                       var parentNode = $("#roleManageUpdateRoleMenuAllTreeMes").treeview('getParent',node.nodeId);
    
                       if(!("nodeId" in parentNode)){
    
                           return;
    
                       }else{
    
                           roleManageUpdateRoleMenuCheckAllParent(parentNode);
    
                       }
    
                  }
    
                  //取消全部父节点
    
                  function roleManageUpdateRoleMenuUncheckAllParent(node){
    
                       $("#roleManageUpdateRoleMenuAllTreeMes").treeview('uncheckNode',node.nodeId,{silent:true});
    
                       var siblings = $("#roleManageUpdateRoleMenuAllTreeMes").treeview('getSiblings', node.nodeId);
    
                       var parentNode = $("#roleManageUpdateRoleMenuAllTreeMes").treeview('getParent',node.nodeId);
    
                       if(!("nodeId" in parentNode)) {
    
                           return;
    
                       }
    
                       var isAllUnchecked = true;  //是否全部没选中
    
                       for(var i in siblings){
    
                           if(siblings[i].state.checked){
    
                                isAllUnchecked=false;
    
                                break;
    
                           }
    
                       }
    
                       if(isAllUnchecked){
    
                           roleManageUpdateRoleMenuUncheckAllParent(parentNode);
    
                       }
    
                  }
    
    
    
                  //级联选中所有子节点
    
                  function roleManageUdpateRoleMenuCheckAllSon(node){
    
                       $("#roleManageUpdateRoleMenuAllTreeMes").treeview('checkNode',node.nodeId,{silent:true});
    
                       if(node.nodes!=null&&node.nodes.length>0){
    
                           for(var i in node.nodes){
    
                                roleManageUdpateRoleMenuCheckAllSon(node.nodes[i]);
    
                           }
    
                       }
    
                  }
    
                  //级联取消所有子节点
    
                  function roleManageUpdateRoleMenuUncheckAllSon(node){
    
                       $("#roleManageUpdateRoleMenuAllTreeMes").treeview('uncheckNode',node.nodeId,{silent:true});
    
                       if(node.nodes!=null&&node.nodes.length>0){
    
                           for(var i in node.nodes){
    
                                roleManageUpdateRoleMenuUncheckAllSon(node.nodes[i]);
    
                           }
    
                       }
    
                  }

     

      1. 权限管理/权限分配

    权限管理à权限分配:为不同用户分配不同角色。

    在权限分配è角色分配  页面中,使用了一个多选框的插件(用于选择多个角色),如下图:

    在使用中发现这个选择框第一次打开时正常,之后再打开始终不正常,调试发现是因为select中动态添加了一个div并且这个div的style=“width:0px”;导致select的展示出现问题。试了各种方式,网上搜了各种方案均失败。最终万般无奈之下猜想可能是引用的js文件中生成这个内部div时导致宽度获取的问题,于是便修改引用的js源码,修改如下:

    <script src="view/manage/assets/js/chosen.jquery.min.js"></script>

    至此问题解决。

    问:如何知道要修改这个宽度(如何定位到是要修改这个宽度的)?

    答:在浏览器中调试时发现在select中生成的div的id是在select的id的基础之上添加了“_chosen”,于是搜索“_chosen”发现整个js源码中只有一个“_chosen”,于是在此附近寻找width相关的代码,终于发现了并尝试修改成功。

     

      1. 权限管理/用户管理

    权限管理à用户管理:功能为对能够登录到系统的管理用户的增、查、修改、停用操作。

    此页面中的table采用bootstrap原生表格,增改查的逻辑完全为自己实现。没有使用bootstrap-table插件。

    本系统设计者建议使用bootstrap-table插件(why? 我也不知道,就是感觉成熟开源的业内小有名气的东东一定比自己写的好),插件demo见系统demo示例。

    此模块中的用户为系统的管理人员。

     

    1. 延伸思考

     

    1. Iframe为子页面,可不受父页面干扰,但是究竟用还是不用好,有待深思的问题;
    2. bootstrap-switch boostrap的开关按钮插件并未能初始化开或者关状态,此功能关乎开关的美观,需探究如何修改或选用其它插件待进一步深思。

    3)系统待优化之处:

    权限访问控制该如何优化(内存?redis?)

    Mybatis整合

    严格的mvc设计模式

     

    1. 致谢!

     

    初级入门:泽宇、老申、昊总

    问题修复:金凤

    问题修复:系统参与的全体java同仁

     

     

    开发者:战神,彭玉,ylz,东龙;

    零碎不重要的整理工作(高大上的名字:秘书):本人。

    向以上四位开发者致敬!

     

     

    1. 文档说明

    本文档由四位开发者在开发过程中心得记录,由秘书整理汇总而成。最终解释权归四位开发者所有。

     

    1. 参考文献

    https://blog.csdn.net/weixin_41981080/article/details/81912941

     

     

     

    文末福利:

    想要与大家一起交流,可进企鹅群:589847567

    群共享文件中有源码下载。

     

     

    说明:该系统由以上四位开发者在工作之余抽时间分工开发完成,因工作较忙,时间有限等原因,系统中难免有瑕疵不足之处需进一步完善,望大家谅解,在后续版本中我们会不断完善。同时诚邀大才雄心的有志之士加入我们共同开发。

     

    展开全文
  • 基于vue2和bootstrap做的一个购物后台管理平台
  • 本篇文章介绍如何使用vue做一个后台管理框架。  在如今的科技公司中有很多前端的需求都是要写一个类似于后台管理框架,日常的工作中会有太多重复的内容加重我们程序员的工作,浪费我们的时间,导致不能早点下班...

    系列教程《一步步带你做vue后台管理框架》第一课

    github地址:vue-framework-wz

    线上体验地址:立即体验

      在如今的科技公司中有很多前端的需求都是要写一个类似于后台管理框架,日常的工作中会有太多重复的内容加重我们程序员的工作,浪费我们的时间,导致不能早点下班回家吃饭。

      普通程序员拿到一个项目总是会重新写,写路由花了两小时,写vuex花了两小时,写个Header组件花了1小时,侧边栏又要1小时,这样下来项目拿到手一天的时间都没真正去做项目的需求,再加上改bug,写css,准备工作都要花三四天,等到产品过来催,还没有真正去实现功能。这样是极大的浪费时间

     

      那么我们怎么才能成为一个高效率的程序员呢?

     

      成功的秘籍就在于需要有一个自己的后台管理框架,当你拿到一个项目,所有的UI组件、路由、状态管理、登录鉴权功能、等等都已经写好,你只需要去复用代码再加上少量的逻辑,当你一个小时做完准备工作,出去买杯咖啡回来看到你的同事还在苦逼的写vue路由,你肯定会会心一笑:“框架在手,天下我有”。

      表格是我们工作中最常见的组件。就拿写一个表格来举例吧

     

       高下立判。传统写一个表格需要大量重复html,且需要自己写css,自己定义数据渲染方式。效率低下且质量不高,而我们的框架已经定义好表格组件,只需要把注意力放在数据获取上,工作瞬间轻松了很多。

     

       再来看下wz框架表格组件在实际应用中的强大之处吧。

     

       我们的框架已经定义好表格组件,上手即用,是不是又美观又简单好用啊。

      不止表格,我们还有各种你工作中会遇到的组件,轻松完成工作中出现的复杂需求。

      UI组件已经有了,我们的框架还有哪些特性呢? 

      自适应!!!  现在很多vue框架都没有自适应功能,而很多使用场景也在手机上会有,这也是wz后台管理框架诞生的原因之一。想想要自己每次做自适应就头疼,现在有了wz框架老板再也不用担心我的界面适配问题了。

         我们看下效果:

      

     

       是不是很棒!wz框架基于bootstrap,采用了row和col的思想,Row为一行,Col为一列,配置Col 的sm md lg 等属性就可以做到无缝自适应。

      代码如下例

    <Row>
       <Col :md="8" :sm="12" :lg="9">
    
      </Col>
    </Row>

     

      简单好上手,没有用过bootstrap或vue的程序员也能轻松使用。

      还有什么令人激动的特性呢?

      莫过于登录鉴权功能了!

      产品要做登录功能你把希望寄托于后端,后端不背锅把锅甩你身上?求人不如求己,wz框架已经替你封装好登录鉴权,只需发送服务端验证一下用户名密码即可。

      来看下我们炫酷的登录界面

      

        

       炫酷狂拽吊炸天是不是。

      原理就是登录的时候输入密码存到cookie里,可以由个人选择加密方式,每次在路由跳转的时候利用router.beforeEach((to, from, next) 判断是否有token,如果有,发送到服务端验证,如果通过,就继续路由,如果没有,就重定向到登录界面。

      鉴权也是一样的道理,在router配置中加上 meta: { role: ['Administrator'] },在router.beforeEach()中判断要去的那个界面是否需要权限。并且侧边栏是根据可访问的路由动态生成的,不同级别的用户可以看到的侧边栏是不一样的,这就在一定程度上做到了简单的权限管理的功能。

      可以看一下这端代码,就是登录鉴权的核心。

    router.beforeEach((to, from, next) => {
      // console.log(to)
      NProgress.start(); // 开启Progress
      if (store.getters.token) { // 判断是否有token
    
    
                // alert('dont need login ');
               if (to.path === '/login') {
                  next({ path: '/' });
                }  
                 else {//如果不是去login 而是其他需要判定权限的
                  // console.log(store.getters.roles)
                  if (store.getters.roles.length === 0) { // 如果当前用户没有拉取完user_info信息
                    store.dispatch('GetInfo').then(res => { // 拉取user_info
                      const roles = res.data.role;
                      store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表
                        router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
                        // console.log(store.getters.addRouters);
                        next({ ...to }); // hack方法 确保addRoutes已完成
                      })
                    })
                  } else {
                    // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
                    if (hasPermission(store.getters.roles, to.meta.role)) {
                      // console.log(to.meta.role)
                      // console.log("has permission");
                      next();//
                    } else {
                      // console.log("has no permission");
    
                      next({ path: '/', query: { noGoBack: true } });
                    }
                    // 可删 ↑
                  }
                }
    
    
      } else {
        if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
          next()
        } else {
          alert('please login');
          next('/login'); // 否则全部重定向到登录页
          NProgress.done(); // 在hash模式下 改变手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行!
        }
      }
    });

     

      

      说完特性,我们再来看看框架的目录结构。

      build和config是webpack的配置文件,src中存放着框架的主要文件,api是已经封装好的api请求,components是我们的UI组件。mock是便于我们前端调试的一个工具,可以截获http请求,返回数据,从而做到独立于后端开发,加快我们的开发进度,当我们需要请求服务器的时候要把这个文件夹删掉。

      我们需要新加页面就在views里面加上新的界面文件,然后在router里配置好路由就可以正常访问了。

      当我们需要提交页面放到服务器上也很简单,运行

    npm run build:prod

     

      项目目录下就会多出一个dist文件夹,里面有index.html文件和static文件夹,放在服务器上就行。不需要在服务器上安装任何环境,甚至不需要node即可。

      再也不用为发布项目操心了。

    ├── build                      // 构建相关  
    ├── config                     // 配置相关
    ├── src                        // 源代码
    │   ├── api                    // 所有请求
    │   ├── components             // 全局UI组件
    │   ├── directives              // 全局指令
    │   ├── mock                   // mock数据
    │   ├── router                 // 路由
    │   ├── store                  // 全局store管理
    │   ├── utils                  // 全局公用方法
    │   ├── containers              // 自适应布局组合
    │   ├── vendor                  // UI组件依赖js
    │   ├── views                   // views界面
    │   │    ├── charts             //图表组件
    │   │    ├── components         //首页组件
    │   │    ├── login              //登录界面
    │   │    ├── pages              //错误界面
    │   │    └── permission        //权限测试界面
    │   ├── App.vue                // 入口页面
    │   └── main.js                // 入口 加载组件 初始化等
    ├── static                     // 静态资源
    │   ├── bower_components        //七牛SDK
    │   ├── css                     //css
    │   ├── js                      //js
    │   └── Jquery.min.js           // jq
    ├── .babelrc                   // babel-loader 配置
    ├── eslintrc.js                // eslint 配置项
    ├── .gitignore                 // git 忽略项
    ├── favicon.ico                // favicon图标
    ├── index.html                 // html模板
    └── package.json               // package.json

     关于框架的介绍就基本是这些了,wz框架的特点就在于自适应、登录鉴权、封装好UI组件、简单易上手、稳定高效。

    希望大家多多使用,多多宣传。

    后续教程会尽快出,下节课讲下怎么上手使用。

    github地址:vue-framework-wz

    线上体验地址:立即体验


    展开全文
  • 使用bootstrap搭建后台管理系统页面《一》

    万次阅读 多人点赞 2018-03-24 12:51:38
    1. 使用bootstrap搭建后台管理系统页面《一》 一般的后台管理系统页面主体包括四个部分,顶部导航栏,左侧菜单栏,中间正文页和底部的页脚。 其中左侧和顶部使用的是bootstrap的导航和下拉菜单组件,主体页面为了...



    1. 使用bootstrap搭建后台管理系统页面《一》

    一般的后台管理系统页面主体包括四个部分,顶部导航栏,左侧菜单栏,中间正文页和底部的页脚。 其中左侧和顶部使用的是bootstrap的导航和下拉菜单组件,主体页面为了演示方便,使用了iframe框架。

    接下来简单介绍一下nav组件常见的几种样式
    1. 标准标签页
    标准标签页

    <ul class="nav nav-tabs">
      <li role="presentation" class="active"><a href="#">Home</a></li>
      <li role="presentation"><a href="#">Profile</a></li>
      <li role="presentation"><a href="#">Messages</a></li>
    </ul>
    • 1
    • 2
    • 3
    • 4
    • 5

    tab页的样式通过外边框线条和内置padding构建出来

    .nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover{
        color:#555;
        cursor:default;
        background-color:#fff;
        border:1px solid #ddd;
        border-bottom-color:transparent
    }
    .nav>li>a{
        position:relative;
        display:block;
        padding:10px 15;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.2 胶囊式标签页
    胶囊式标签页

    <ul class="nav nav-pills">
      <li role="presentation" class="active"><a href="#">Home</a></li>
      <li role="presentation"><a href="#">Profile</a></li>
      <li role="presentation"><a href="#">Messages</a></li>
    </ul>
    • 1
    • 2
    • 3
    • 4
    • 5

    和标准的tab页不相同的是,通过填充背景颜色构成胶囊状的导航块,区别的样式代码如下:

    .nav-pills>li.active>a, .nav-pills>li.active>a:focus, .nav-pills>li.active>a:hover{
        color:#fff;
        background-color:#337ab7;
    }
    • 1
    • 2
    • 3
    • 4

    胶囊是标签页也是可以垂直方向堆叠排列的,只需添加 .nav-stacked 类。

    堆叠式胶囊标签页

    正常情况ul标签下的li标签都是垂直排列的,之前的.nav-pills下的li标签之所以可以横向排列,是加了float属性。

    .nav-pills>li{
        float:left;
    }
    • 1
    • 2
    • 3

    而此处在.nav-stack类下的li标签则去除了元素的float属性:

    .nav-stacked>li{
        float:none;
    }
    • 1
    • 2
    • 3

    这块你可能会有疑问了,如何能确保下面的样式生效呢?因为.nav-pills>li和.nav-stacked>li这两种选择器其实优先级是一样的,在优先级一样的情况下,后声明的选择器会最终生效,当然在bootstrap中也能看到使用简单粗暴的!important去提高优先级的做法。

    1.3 下拉菜单组件

    下拉菜单依赖单独的插件,我们可以在任何组件(比如导航栏,标签页,胶囊式导航菜单,按钮等)中添加下拉菜单,可以通过单独引用 dropdown.js,或者引用bootstrap.js 或压缩版的 bootstrap.min.js。

    它包括2中调用方式,通过data属性或者通过JS直接调用,接下来仅简单介绍通过data属性进行调用的情况。

    下拉菜单组件

    <ul class="nav navbar-nav">
        <li class="active"><a href="#">iOS</a></li>
        <li><a href="#">SVN</a></li>
        <li class="dropdown">
           <a href="#" class="dropdown-toggle" data-toggle="dropdown">Java<b class="caret"></b>
           </a>
           <ul class="dropdown-menu">
               <li><a href="#">Java</a></li>
               <li><a href="#">C#</a></li>
               <li class="divider"></li>
               <li><a href="#">Python</a></li>
            </ul>
        </li>
    </ul>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    将二级菜单的内容放在类dropdown-menu 修饰的ul标签中,向链接或按钮添加 data-toggle=”dropdown” 来切换下拉菜单,但通常情况下下拉菜单的样式不太好看,我们可以微调样式来达到我们需要的效果。

    2.后台管理系统模板

    这里写图片描述

    管理系统页面源代码:

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <%
        String path = request.getContextPath();
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!-- 引入样式文件和动态控制 -->
            <link href="<%=path %>/css/bootstrap.min.css" rel="stylesheet">
            <script src="<%=path %>/js/jquery-3.2.1.min.js"></script>
            <script src="<%=path %>/js/bootstrap.min.js"></script>
            <!--主要样式控制-->
            <link href="<%=path %>/css/main.css" rel="stylesheet">
    
    <title>bootstrap后台模板设计</title>
    
    </head>
    <body>
    <!--顶部导航栏部分-->
    <nav class="navbar navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" title="logoTitle" href="#">logo</a>
           </div>
           <div class="collapse navbar-collapse">
               <ul class="nav navbar-nav navbar-right">
                   <li role="presentation">
                       <a href="#">当前用户:<span class="badge">柒晓白</span></a>
                   </li>
                   <li>
                       <a href="../login/logout">
                             <span class="glyphicon glyphicon-lock"></span>退出登录</a>
                    </li>
                </ul>
           </div>
        </div>      
    </nav>
    
    <!-- 中间主体内容部分 -->
    <div class="pageContainer">
         <!-- 左侧导航栏 -->
         <div class="pageSidebar">
             <ul class="nav nav-stacked nav-pills">
                 <li role="presentation">
                     <a href="nav1.html" target="mainFrame" >课程管理</a>
                 </li>
                 <li role="presentation">
                     <a href="nav2.html" target="mainFrame">学生管理</a>
                 </li>
                 <li role="presentation">
                     <a href="nav3.html" target="mainFrame">教师管理</a>
                 </li>
                 <!-- 开始 -->
                 <li class="dropdown">
                     <a class="dropdown-toggle" data-toggle="dropdown" href="nav4.html" target="mainFrame">
                         个人设置<span class="caret"></span>
                     </a>
                     <ul class="dropdown-menu">
                         <li>
                             <a href="nav1.html" target="mainFrame">修改密码</a>
                         </li>
                         <li>
                             <a href="nav2.html" target="mainFrame">退出系统</a>
                         </li>
                         <li>
                             <a href="nav3.html" target="mainFrame">查看个人信息</a>
                         </li>
                     </ul>
                 </li>
                 <!-- 结束 -->
                 <li role="presentation">
                     <a href="nav5.html" target="mainFrame">权限设置</a>
                 </li>
    
    
    
             </ul>
         </div>
    
          <!-- 左侧导航和正文内容的分隔线 -->
         <div class="splitter"></div>
         <!-- 正文内容部分 -->
         <div class="pageContent">
           <iframe src="welcome.jsp" id="mainFrame" name="mainFrame" 
           frameborder="0" width="100%"  height="100%" frameBorder="0">
           </iframe> 
         </div>
    
     </div>
      <!-- 底部页脚部分 -->
     <div class="footer">
         <p class="text-center">
             2018 &copy; 柒晓白.
         </p>
     </div>
    
     <script type="text/javascript">
     $(".nav li").click(function() {
            $(".active").removeClass('active');
            $(this).addClass("active");
        }); 
    
    
     </script>
    </body>
    </html>

    稍微调整了一下导航栏和下拉菜单的样式,这样整体的风格能更好一些,修改了min-width,margin-left和background-color属性,是下拉框出现的位置更加美观一些

    修改后的下拉菜单

    main.css的源代码:

    /* 后台管理框架的样式 */
    
    /* 下拉菜单和导航 */
    .navbar-collapse{
        padding-left: 5px;
        padding-right: 5px;
     }
     .nav>li{
         text-align: center;
     }
     .nav>li>a{
         color:#444;
         margin: 0 5px;
     }
     .nav-pills>li.active>a, .nav-pills>li.active>a:focus, .nav-pills>li.active>a:hover{
         background-color: #222222;
     }
     .dropdown-menu{
         float: none;
         position: initial;
         min-width: 200px;
         margin-left: 0;
         background-color: #E3E3E3;
         box-shadow: none;
         text-align: center;
     }
     .dropdown-menu>li>a{
         padding: 10px 15px;
     }
    
     /* 主体样式 */
     body {
        width: 100%;
        height: 100%;
        margin: 0;
        overflow: hidden;
        background-color: #FFFFFF;
        font-family: "Microsoft YaHei", sans-serif;
     }
     .pageSidebar{
        width: 240px;
        height:100%;
        padding-bottom: 30px;
        overflow: auto;
        background-color: #e3e3e3;
     }
     .splitter {
         width: 5px;
         height: 100%;
         bottom: 0;
         left: 240px;
         position: absolute; 
         overflow: hidden;
         background-color: #fff;
     }
     .pageContent{
         height: 100%;
         min-width: 768px;
         left: 246px;
         top: 0;
         right: 0;
         z-index: 3;
         padding-bottom: 30px;
         position: absolute;
     }
     .pageContainer{
         bottom: 0;
         left:0;
         right: 0;
         top: 53px;
         overflow: auto;
         position: absolute;
         width: 100%;
     }
     .footer {
         width: 100%;
         height: 30px;
         line-height: 30px;
         margin-top: 0;
         left: 0;
         right: 0;
         bottom: 0;
         position: absolute; 
         z-index: 10;
         background-color:#DFDFDF;
     }
    

    另外我们观察到左侧导航栏的点击样式,是通过active类来控制,需要添加一段JS代码来控制鼠标点击时,移除兄弟节点的active样式,并为当前元素添加active样式。

     <script type="text/javascript">
     $(".nav li").click(function() {
            $(".active").removeClass('active');
            $(this).addClass("active");
        }); 
     </script>

    以上就是使用bootstrap搭建一个简单的后台管理系统的页面。因为主页面采用了iframe框架,你只需要在主面板区域写成这样:

    <!-- 主区域部分 -->
         <div class="pageContent">
           <iframe src="welcome.jsp" id="mainFrame" name="mainFrame" 
           frameborder="0" width="100%"  height="100%" frameBorder="0">
           </iframe> 
         </div>

    其他页面的a标签后面加入:

    target="mainFrame" 属性。

    那么其他页面也是会主动显示在主面板中,不会新打开一个窗口显示内容。


    You got a dream, you gotta protect it.
    如果你有梦想的话,就要去捍卫它 。 ——《当幸福来敲门》

    展开全文
  • Bootstrap-vue 详细介绍 使用 Vue.js 和世界上最流行的前端 CSS 库—Bootstrap V4 在 Web 上构建响应式,移动优先项目。 Bootstrap-VueVue.js 2.4+ 提供了 Bootstrap V4 组件和最全面的网格系统的实现,它...

    Bootstrap-vue 详细介绍

    使用 Vue.js 和世界上最流行的前端 CSS 库—Bootstrap V4 在 Web 上构建响应式,移动优先项目。

    Bootstrap-Vue 为 Vue.js 2.4+ 提供了 Bootstrap V4 组件和最全面的网格系统的实现,它具有广泛的自动化 WAI-ARIA 辅助功能标记。

    Alert:

    Button:

    展开全文
  • 基于springboot bootstrap mybatis,vue ,mysql 前后端管理脚手架,已有菜单管理,权限管理,角色管理,用户管理,字典管理,文件管理,任务管理,websocket通信。
  • # npm npm install vue bootstrap-vue bootstrap # yarn yarn add vue bootstrap-vue ...import { BootstrapVue, IconsPlugin } from 'bootstrap-vue' //可选地安装BootstrapVue图标插件组件 Vue.use(IconsPlugin)
  • 今天想到了Bootstrapvue.js的区别

    千次阅读 2019-07-06 07:36:00
    Bootstrap和layui是开源工具包。Jquery是js的库 vueangular react才是框架为什么是框架呢,因为受到了后台的OOPAOC的思想的影响。 转载于:https://www.cnblogs.com/fuckingPangzi/p/10442761.html...
  • Vue.js 结合bootstrap 前端实现分页效果
  • vue+bootstrap 实现一个简单分页器

    千次阅读 2018-09-02 16:32:33
    当数据有很多条时,如果我们一次性请求的话,加载会比较慢,这个时候就会用到分页功能了,通过向后台发送请求数据的页码和条数,就可以实现分页功能。 由于项目比较简单,要求不是很高,实现简单分页即可。按钮用的...
  • vue项目中导入BootstrapVue的方法

    千次阅读 2019-05-17 17:21:45
    打开命令行工具,安装BootstrapVue npm i bootstrap-vue -S 安装后,打开main.js主程序入口文件 import BootstrapVue from 'bootstrap-vue' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap-vue/...
  • vue 使用bootstrap(一)

    千次阅读 2019-02-27 11:43:33
    vue-cli3项目中引入bootstrap走的弯路 在vue项目中引入bootstrap框架一开始依旧使用原来引入第三方库的方法。 由于Bootstrap 的所有 JavaScript 插件都依赖 jQuery,因此 jQuery 必须在 Bootstrap 之前引入。 ...
  • Bootstrap官方出品:BootstrapVue去官网看看吧 上一篇:BootstrapVue的使用《关于Bootstrap工具样式-----边距相关》 关于工具样式,官方文档(快速通道)
  • vue-cli3.x引入bootstrap

    2019-06-25 13:28:23
    局部安装bootstrap npm install bootstrap -D 修改src下的main.js import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import './...
  • https://juejin.im/post/5ba9d5cce51d450e805b59b0-比官方文档更易懂的Vue.js教程!包你学会!
  • 1. 请问vue脚手架搭配bootstrap使用会冲突吗? 2. 怎么在script做数据渲染呢?是export default{}下的methods:{}里吗?
  • vue cli3 引入Bootstrap-vue

    2020-06-30 15:15:28
    1、npm install vue bootstrap-vue bootstrap 下载 2、npm install jquery -S 3、在vue.config加入 constwebpack=require("webpack"); module.exports={ configureWebpack:{ plugins:[ newwebpack....
  • Bootstrap框架和vue哪个好-天道酬勤

    千次阅读 2020-05-30 15:01:50
    vue是功能开发框架(功能代码如何组织),他搭建好了功能架子,居于他你可以快速开发功能 bootstrap是界面效果框架(界面效果什么样子),他定义好了界面显示效果,比如按钮是什么样,输入框是什么样 ...
  • 基于Vue.js和Bootstrap构建和响应式管理面板
  • http://blog.csdn.net/ansu2009/article/details/53305134
1 2 3 4 5 ... 20
收藏数 20,830
精华内容 8,332
关键字:

bootstrap vue 后台管理