基于springboot+mybatisplus构建系统管理平台(二) 原 荐

栏目: Java · 发布时间: 5年前

内容简介:上一篇主要说到了spring security和mybatis-plus的使用,当然都是使用过程中的一些描述,可能在理解上与实际有一些出入,毕竟是学习的过程,循序渐渐才更有价值。其实后台的服务基本在之前的基础上已经有了,现在的关键就是前段的界面与后台的集成,当然现在很多应用前后端都已经分离,当我们作为两个服务去部署时,其实又会有很多新问题需要处理,同时会有更多的知识需要去了解,当然毕竟在目前阶段这不属于核心的东西,所有此次依旧将前端代码与后台带打包在一起使用。一直说到使用vue,其实很早就接触过,但确实也没

上一篇主要说到了spring security和mybatis-plus的使用,当然都是使用过程中的一些描述,可能在理解上与实际有一些出入,毕竟是学习的过程,循序渐渐才更有价值。

其实后台的服务基本在之前的基础上已经有了,现在的关键就是前段的界面与后台的集成,当然现在很多应用前后端都已经分离,当我们作为两个服务去部署时,其实又会有很多新问题需要处理,同时会有更多的知识需要去了解,当然毕竟在目前阶段这不属于核心的东西,所有此次依旧将前端代码与后台带打包在一起使用。

一直说到使用vue,其实很早就接触过,但确实也没怎么去使用,一是因为目前工作环境影响;其次前端框架太多,在选择上没有做过过多的评估与对比,所以一直不知道选用什么样的框架与当前工作内容更贴切 。当然由于现在不是vue的教学,我们需要的是一个成型的界面,可供操作,所以vue只是其中的一个技术点,在项目中会结合thymeleaf与ivew来使用。

项目结构大致如下:

基于springboot+mybatisplus构建系统管理平台(二) 原 荐

其中pages存放的是页面相关内容,static则是一些js、css等,由于我们引入了安全框架,同时由于权限配置关系,导致所有的脚步样式图片等资源都会被拦截,因此我们有必要忽略这些镜头资源,在WebSecurityConfigurerAdapter的子类中配置即可:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/static/**").antMatchers("/favicon.ico")
            .mvcMatchers("/webjars/**")
            .mvcMatchers("/js/**")
            .mvcMatchers("/css/**");
}

为什么把pages分了这么多,主要是将一个完整的html页面进行了分割,比如头部分,会引入css以及一些其他相关配置,页面也会有相应的布局,比如分为上下左中几个部分,其实只是做了一下分离,这个完全是因人而异。

可以看下common:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <body>
        <th:block th:fragment="common-css">
            <link rel="stylesheet" th:href="@{/webjars/iview/dist/styles/iview.css}">
            <link rel="stylesheet" th:href="@{/static/css/main.css}">
        </th:block>

        <th:block th:fragment="common-js">
            <!-- import vue-->
            <script type="text/javascript" th:src="@{/webjars/vue/dist/vue.min.js}"></script>
            <!-- import axios -->
            <script type="text/javascript" th:src="@{/webjars/axios/dist/axios.min.js}"></script>
            <!-- import iView -->
            <script type="text/javascript" th:src="@{/webjars/iview/dist/iview.min.js}"></script>
            <!-- i18n -->
            <script type="text/javascript" th:src="@{/webjars/iview/dist/locale/zh-CN.js}"></script>
        </th:block>
    </body>
</html>

因为是通过webjars引入的前端依赖库,所有都是通过maven来管理的:

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>webjars-locator</artifactId>
    <version>0.32-1</version>
</dependency>
<dependency>
    <groupId>org.webjars.npm</groupId>
    <artifactId>vue</artifactId>
    <version>2.6.10</version>
</dependency>
<dependency>
    <groupId>org.webjars.npm</groupId>
    <artifactId>iview</artifactId>
    <version>3.4.0</version>
</dependency>
<dependency>
    <groupId>org.webjars.bower</groupId>
    <artifactId>axios</artifactId>
    <version>0.17.1</version>
</dependency>
<dependency>
    <groupId>org.webjars.bower</groupId>
    <artifactId>jquery</artifactId>
    <version>3.4.1</version>
</dependency>

这里没有使用vue的一些脚手架,主要也是用最基本的功能区完成一些效果,主要是为了使用与理解。这里要提到webjars-locator这样一个jar,帮助我们处理了所有版本问题,所以在引入的时候不会有相关的版本信息在路径中。

其次核心的框子都在layout.html中,主要帮我们完成了布局,菜单数据加载,以及以下菜单路由相关的工作:

<head>
    <title th:text="管理系统"></title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="Shortcut Icon" href="favicon.ico">
    <!-- import css -->
    <div th:replace="common/commons::common-css"></div>
    <!-- import js -->
    <div th:replace="common/commons::common-js"></div>
    <script type="text/javascript" th:inline="javascript">
        iview.lang('zh-CN');
        /*<![CDATA[*/
            window['contextPath'] = /*[[@{/}]]*/
        /*]]>*/
    </script>
</head>

<body>
    <div id="app" class="layout layout-full">
        <layout class="menu-container">
            <header v-cloak>
                <i-menu mode="horizontal" theme="dark" active-name="1">
                    <div class="layout-logo"><span class="log-text">管理系统</span></div>
                    <div class="layout-nav">
                        <menu-item name="1">
                            <icon type="ios-notifications-outline"></icon>
                            消息
                        </menu-item>
                        <menu-item name="2">
                            <icon type="md-volume-down" />
                            提醒
                        </menu-item>
                        <menu-item name="3">
                            <icon type="ios-mail-outline"></icon>
                            邮件
                        </menu-item>
                    </div>
                    <divider type="vertical" />
                </i-menu>
                <i-menu mode="horizontal" theme="dark" class="layout-header-rignt">
                    <div class="">
                        <menu-item>
                            <span>管理员</span>
                        </menu-item>
                        <menu-item>
                            <icon type="md-exit" style="font-size: 18px"></icon>
                            <a th:href="@{/logout}"></a>
                        </menu-item>
                    </div>
                </i-menu>
            </header>
            <layout>
                <sider hide-trigger :style="{background: '#fff'}" class="layout-menu">
                    <!--@on-select="goPage"-->
                    <i-menu ref="side_menu" :open-names="openNames" :active-name="activeName"  theme="light" width="auto" accordion  class="app-left">
                        <submenu v-for="menu in menus" :name="menu.id" v-cloak>
                            <template slot="title">
                                <icon :type="menu.style"></icon>
                                {{menu.name}}
                            </template>
                            <!--@click.native="goPage"-->
                            <menu-item v-for="m in menu.children" :name="m.id" :to="m.path">{{m.name}}</menu-item>
                        </submenu>
                    </i-menu>
                </sider>
                <layout :style="{padding: '0 24px 24px'}">
                    <breadcrumb :style="{margin: '24px 0','padding-left': '200px',position: 'absolute',top: '60px'}" v-cloak>
                        <breadcrumb-item v-for="menu in menuNav">{{menu}}</breadcrumb-item>
                    </breadcrumb>
                    <content class="app-main">
                        <div th:replace="::app-content"></div>
                    </content>
                </layout>
            </layout>
        </layout>
    </div>
<script th:inline="javascript">
    var vm = new Vue({
        el:'#app',
        data(){
            return {
                menus:[],
                openNames:[],
                activeName:'',
                menuNav:['主页']
            };
        },
        created:function () {
            var that = this;
            /*<![CDATA[*/
                var _menuNav = /*[[${menuNav}]]*/
                    _openNames = /*[[${openNames}]]*/
                    _activeName = /*[[${activeName}]]*/
                _menuNav && (this.menuNav = _menuNav);
                _openNames && (this.openNames = _openNames);
                _activeName && (this.activeName = _activeName);
            /*]]>*/
            axios.get(contextPath+'system/menu/tree')
                .then(function (res) {
                    that.menus = res.data;
                    //自动构建的菜单需要加上处理
                    that.$nextTick(() => {
                        that.$refs.side_menu.updateOpened()
                        that.$refs.side_menu.updateActiveName()
                    })
                });
        },
        methods:{
            goPage:function (name) {
                // window.location.hash = name;
                // name && (window.location.href = name);
            }
        }
    });

</script>
</body>

可以看下,最先引入了我们在common中的css与js,之后用到了iview,其实就是在 布局 中拷贝了一个,进行了简单的修改,然后有几点需要说明的:

1、记得一定需要使用new Vue({el:''}),对页面元素处理,这样相关的组件才能进行渲染,因为页面中使用了iview的自定义组件,但又是基于vue的,所以这个必须要加上。

2、页面中一些动态的数据,比如菜单数据、样式相关的配置属性、导航属性等,要优先定义,在之后的页面操作中,进行修改这些属性即可实现动态效果,这个看vue的教程即可。

3、web项目上下文路径会随部署而变化,在thymeleaf中,我们可以通过这样获取,前提是script标签需要th:inline="javascript"声明:

window['contextPath'] = [[@{/}]]

4、围绕vue的生命周期,有很多钩子函数可以在其创建过程中完成我们自定义的修改

5、菜单的路由主要根据iview的提供的属性进行了处理,其中:to会将该元素渲染成a标签,最后其实是全局刷新,其实每个模块就是一个新地址,

<menu-item v-for="m in menu.children" :name="m.id" :to="m.path">{{m.name}}</menu-item>

这个不同于之前的做法,将整个项目作为一个页面,将子页面全部嵌入到注页面中,这次主要是通过layout.html作为一个模板,所有的子页面内容都是加载到

<content class="app-main">
    <div th:replace="::app-content"></div>
</content>

中,同时页面会重新定位,而我们真正的页面则是这样的:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorator="layout/layout">

    <div th:fragment="app-content">
        index
    </div>

</html>

其实前端的构建大致也就是这样,当然会有很多细节,在真正去构建的时候都会遇到各种问题,当然,遇到问题解决问题,这样的方式能够更快的了解并使用新的技术。

目前只是完成了一个用户查询的界面:

<div th:fragment="app-content">
    <div id="user">
        <i-table border
                 :columns="columns"
                 :data="users">
        </i-table>
    </div>
    <script th:src="@{/webjars/jquery/dist/jquery.min.js}"></script>
    <script>
        new Vue({
            el: '#user',
            data() {
                return {
                    users: [],
                    columns: [
                        {
                            title: '登录名',
                            key: 'username'
                        },
                        {
                            title: '用户名',
                            key: 'userCaption'
                        },
                        {
                            title: '年龄',
                            key: 'age'
                        },
                        {
                            title: '电话',
                            key: 'telephone'
                        },
                        {
                            title: '邮箱',
                            key: 'email'
                        }
                    ]
                }
            },
            created(){
                this.getUsers();
            },
            methods: {
                getUsers:function () {
                    var that = this;
                    //异步加载无数据!!
                    // axios.get(contextPath+'system/user')
                    //     .then(function (res) {
                    //         that.users = res.data;
                    //     })
                    $.ajax({
                        url:contextPath+'system/user',
                        async:false,
                        success:function(res){
                            that.users = res;
                        }
                    })
                }
            }
        });
    </script>
</div>

界面大致这样:

基于springboot+mybatisplus构建系统管理平台(二) 原 荐

基于springboot+mybatisplus构建系统管理平台(二) 原 荐 当然这样有个问题一直不知道什么原因,因为请求时使用的是axios,其中users数据一直无法和页面实现双向绑定。

代码: https://github.com/suspring/springboot-mybatisplus-security-ms.git

下一次看下消息队列把...


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

调试九法

调试九法

David J.Agans / 赵俐 / 人民邮电出版社 / 2010-12-7 / 35.00元

硬件缺陷和软件错误是“技术侦探”的劲敌,它们负隅顽抗,见缝插针。本书提出的九条简单实用的规则,适用于任何软件应用程序和硬件系统,可以帮助软硬件调试工程师检测任何bug,不管它们有多么狡猾和隐秘。 作者使用真实示例展示了如何应用简单有效的通用策略来排查各种各样的问题,例如芯片过热、由蛋酒引起的电路短路、触摸屏失真,等等。本书给出了真正能够隔离关键因素、运行测试序列和查找失败原因的技术。 ......一起来看看 《调试九法》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试