springboot+thymeleaf+vue页面开发


title: springboot+thymeleaf+vue页面开发
copyright: true
categories: springmvc和springboot
tags: [springboot,VUE]
password:


springboot推荐的页面模板是thymeleaf,在前后端不分离的情况下,springboot推荐用html做页面,然后用thymeleaf做模板引擎,做数据渲染,但是这种方式还是要用js或者jquery手动去操作dom,很难受,研究了一下,可以用springboot也可以用vue,如下:

一、thymeleaf的修改

1、thymeleaf默认的校验规则是HTML5,但是这种规则太严格,需要改成LEGACYHTML5
2、需要引入一个jar包

		<dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>

NekoHTML 是一个简单地HTML扫描器和标签补偿器(tag balancer) ,使得程序能解析HTML文档并用标准的XML接口来访问其中的信息。这个解析器能投扫描HTML文件并“修正”许多作者(人或机器)在编写HTML文档过程中常犯的错误。NekoHTML 能增补缺失的父元素、自动用结束标签关闭相应的元素,以及不匹配的内嵌元素标签。NekoHTML 的开发使用了Xerces
Native Interface (XNI),后者是Xerces2的实现基础。

二、引入vue和iview

vue是一套js框架,虚拟dom,数据双向绑定

iView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品。

页面代码如下所示:


<!DOCTYPE HTML>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">

<head th:include="console/header">
</head>

<body>

<script type="text/javascript" th:inline="javascript">
    var dealMeasureEnum = [[${dealMeasureEnum}]];
</script>

<style type="text/css">
    th.demo-table-info-column {
        text-align: center !important;
    }

    td.demo-table-info-column {
        text-align: center !important;
    }

    span.item {
        margin-left: 10px;
    }
</style>
<!-- import Vue.js -->
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<!-- import stylesheet -->
<link href="https://cdn.bootcss.com/iview/2.14.0/styles/iview.css" rel="stylesheet">
<!-- import iView -->
<script src="https://cdn.bootcss.com/iview/2.14.0/iview.min.js"></script>
<div th:include="console/footer"></div>


<div id="app">

    <div>
        <blockquote class="layui-elem-quote">
            <h1>商家违规管理</h1>
            <!--<small> 销售报表</small>-->
        </blockquote>
        <hr/>
    </div>

    <div style="margin-bottom: 20px">
        <i-input v-model="phone" placeholder="请输入手机号" style="width: 200px;"></i-input>

        <label style="margin-left: 50px;">处罚分类:</label>
        <i-select v-model="dealMeasure" style="width:200px">
            <i-option value="">全部</i-option>
            <i-option th:each="e,eStat:${dealMeasureEnum}"
                      th:value="${e.code}" th:text="${e.desc}"></i-option>
        </i-select>

        <date-picker type="datetime" format="yyyy-MM-dd HH:mm:ss"
                     style="width: 200px;margin-left: 50px" placeholder="申请开始时间"
                     @on-change="dealTimeStartDataChange"/>
        <date-picker type="datetime" format="yyyy-MM-dd HH:mm:ss"
                     style="width: 200px;margin-left: 50px" placeholder="申请结束时间"
                     @on-change="dealTimeEndDataChange"/>
        <i-button style="margin-left: 50px" type="primary" @click="getDataList">搜索</i-button>
    </div>

    <hr style="height: 2px;margin-bottom: 10px">

    <i-button @click="add">添加</i-button>
    <i-table :data="tableData" :columns="tableColumns" border stripe></i-table>
    <div style="margin: 10px;overflow: hidden">
        <div style="float: right;">
            <page :total="totalElements" :page-size="size" show-sizer @on-page-size-change="changePageSizeFun"
                  @on-change="changePagesFun"></page>
        </div>
    </div>

    <modal v-model="myModal" title="添加/修改违规信息" @on-ok="ok" :loading="loading" width="600px">
        <i-form :model="addFormData" :label-width="80">

            <form-item label="商家手机号:">
                <i-input v-model="addFormData.phone" placeholder="请输入手机号" style="width: 200px;"></i-input>
                <i-button @click="see" style="margin-left: 10px">查询</i-button>
            </form-item>

            <hr style="height: 1px;margin-top: -8px;margin-bottom: 10px">

            <div>
                <div style="margin-left: 8px;margin-bottom: 10px">
                    <span class="item">该商家当前扣分:{{addFormData.deductPointAlready}},</span>
                    <span class="item">账户余额:{{addFormData.accountBalance}},</span>
                    <span class="item">冻结金额:{{addFormData.freezeMoney}}</span>
                </div>
                <form-item label="处罚分类:">
                    <i-select v-model="addFormData.dealMeasure" style="width:200px">
                        <i-option v-for="item in dealMeasureEnum" :value="item.code" :key="item.code">
                            {{ item.desc }}
                        </i-option>
                    </i-select>
                </form-item>
                <form-item label="扣分:">
                    <input-number v-model="addFormData.deductPoint" precision="0"></input-number>
                    <date-picker type="date" format="yyyy-MM-dd" v-model="addFormData.deadLineTimeStamp"
                                 style="width: 200px;margin-left: 10px" placeholder="扣分有效期"
                                 @on-change="(data)=>addFormData.deadLineTime=data"/>
                    <span>默认一个月</span>
                </form-item>
                <form-item label="扣款:">
                    <input-number v-model="addFormData.deductFee" step="0.01"
                                  :formatter="value=>decimal(value)"></input-number></form-item>

                <form-item label="违规说明:">
                    <i-input v-model="addFormData.reason" type="textarea" :autosize="{minRows: 2,maxRows: 5}"
                             placeholder="请输入处罚原因"></i-input>
                </form-item>
            </div>

        </i-form>

    </modal>


</div>


</body>


<script type="text/javascript">
    /*<![CDATA[*/

    let app = new Vue({
        el: '#app',
        data() {
            return {
                page: 0,
                size: 10,
                totalElements: 0,
                dealMeasureEnum: dealMeasureEnum,
                loading: false,
                addFormData: {
                    deadLineTimeStamp: '',
                    phone: '',
                    deductPoint: 0,
                    deductPointAlready: 0,
                    accountBalance: 0,
                    freezeMoney: 0,
                    dealMeasure: '',
                    deadLineTime: '',
                    deductFee: 0,
                    reason: ''
                },
                myModal: false,
                phone: '',
                dealMeasure: '',
                dealTimeStart: '',
                dealTimeEnd: '',
                tableColumns: [],
                tableData: [],
            }
        },
        created() {
            this.getDataList()
            this.getTableColumns()
        },
        methods: {
            see() {
                var self = this;
                $.get("/console/sp/get?phone=" + self.addFormData.phone, {}, function (res) {
                    if (res && res.status) {
                        let data = res.data;
                        self.addFormData.deductPointAlready = data.userRecord.deductPoint;
                        self.addFormData.accountBalance = self.moneyFenToYuan(data.userAccount.accountBalance);
                        self.addFormData.freezeMoney = self.moneyFenToYuan(data.userAccount.freezeMoney);
                    }
                })
            },
            decimal(value) {
                var value = value.toString();
                value = value.replace(/[^\d.]/g, ""); //清除"数字"和"."以外的字符
                value = value.replace(/^\./g, ""); //验证第一个字符是数字
                value = value.replace(/\.{2,}/g, "."); //只保留第一个, 清除多余的
                value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
                value = value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3'); //只能输入两个小数
                return value;
            }
            ,
            changePagesFun(page) {
                // The simulated data is changed directly here, and the actual usage scenario should fetch the data from the server
                this.page = page - 1;
                this.getDataList();
            }
            ,
            changePageSizeFun(size) {
                // The simulated data is changed directly here, and the actual usage scenario should fetch the data from the server
                this.size = size;
                this.getDataList();
            }
            ,
            dealTimeStartDataChange(data) {
                this.dealTimeStart = data;
            }
            ,
            dealTimeEndDataChange(data) {
                this.dealTimeEnd = data;
            }
            ,
            add() {
                this.addFormData = {
                    deadLineTimeStamp: '',
                    phone: '',
                    deductPoint: 0,
                    deductPointAlready: 0,
                    accountBalance: 0,
                    freezeMoney: 0,
                    dealMeasure: '',
                    deadLineTime: '',
                    deductFee: 0,
                    reason: ''
                };
                this.myModal = 'true';
            }
            ,
            edit(row) {
                var self = this;
                $.get("/console/sp/get?sellerId=" + row.sellerId, {}, function (res) {
                    if (res && res.status) {
                        let data = res.data;
                        self.addFormData = {
                            id: row.id,
                            phone: row.other.phone,
                            deductPoint: row.deductPoint,
                            deductPointAlready: data.userRecord.deductPoint,
                            accountBalance: self.moneyFenToYuan(data.userAccount.accountBalance),
                            freezeMoney: self.moneyFenToYuan(data.userAccount.freezeMoney),
                            dealMeasure: row.dealMeasure,
                            deadLineTime: self.timeFormatter(row.deadLineTime),
                            deadLineTimeStamp: new Date(row.deadLineTime),
                            deductFee: self.moneyFenToYuan(row.deductFee),
                            reason: row.reason
                        };
                        self.myModal = 'true';
                    }
                })
            }
            ,
            ok() {
                var self = this;
                $.post("/console/sp/addAndEdit", this.addFormData, function (data) {
                    if (data && data.status) {
                        self.$Message.success('成功');
                        self.getDataList();
                    } else {
                        self.$Message.error(data.msg);
                    }
                });
            }
            ,
            getTableColumns() {
                let self = this;
                this.tableColumns = [
                    {
                        title: '创建时间',
                        key: 'createTime',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            var row = params.row;
                            return h("div", self.timeFormatter(row.createTime))
                        }
                    },
                    {
                        title: '手机号',
                        key: '-',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            var row = params.row;
                            return h("div", row.other.phone)
                        }
                    },
                    {
                        title: '处罚分类',
                        key: 'dealMeasure',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            var row = params.row;
                            return h("div", getDealMeasure(row.dealMeasure))
                        }
                    },
                    {
                        title: '扣分',
                        key: 'deductPoint',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            var row = params.row;
                            return h("div", row.deductPoint)
                        }
                    },
                    {
                        title: '状态',
                        key: 'deadLineTime',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            var row = params.row;
                            var deadLineTime = row.deadLineTime;
                            if (deadLineTime > new Date()) {
                                return h("div", "已生效");
                            }
                            return h("div", "已过期");
                        }
                    },
                    {
                        title: '说明',
                        key: 'reason',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            var row = params.row;
                            return h("div", row.reason)
                        }
                    },
                    {
                        title: '扣款',
                        key: 'deductFee',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            var row = params.row;
                            return h("div", self.moneyFenToYuan(row.deductFee))
                        }
                    },
                    {
                        title: '操作人',
                        key: 'operatorName',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            var row = params.row;
                            return h("div", row.operatorName)
                        }
                    },
                    {
                        title: '操作',
                        key: '-',
                        className: 'demo-table-info-column',
                        render: function (h, params) {
                            return h('div', [h('Button', {
                                props: {
                                    type: 'primary',
                                    size: 'small'
                                },
                                style: {
                                    marginRight: '5px'
                                },
                                on: {
                                    click: function () {
                                        self.edit(params.row)
                                    }
                                }
                            }, '修改')])
                        }
                    }]
            }
            ,
            getDataList() {
                var self = this;
                $.get("/console/sp/getPage", {
                    page: self.page,
                    size: self.size,
                    phone: self.phone,
                    dealMeasure: self.dealMeasure,
                    dealTimeStart: self.dealTimeStart,
                    dealTimeEnd: self.dealTimeEnd,
                }, function (res) {
                    if (res.status) {
                        self.tableData = res.data.content;
                        self.totalElements = res.data.totalElements;
                        self.tableData = res.data.content;
                    } else {
                        self.$Message.error(res.msg)
                    }
                })
            }
            ,
            moneyFenToYuan(value, row, index) {
                return (value * 0.01).toFixed(2);
            }
            ,
            timeFormatter(value) {
                if (value == null || value == "") {
                    return "";
                }
                var date = new Date(value);
                return format = date.format("yyyy-MM-dd hh:mm:ss");
            }
        }
    })

    function getDealMeasure(value, row, index) {
        var str = "";
        $.each(dealMeasureEnum, function (index, element) {
            var code = element["code"];
            var desc = element["desc"];
            if (value != null && value != "" && value != undefined) {
                if (code == value) {
                    str = desc;
                    return false;
                }
            }
        })
        return str;
    }

    /*]]>*/
</script>
</html>

发布了91 篇原创文章 · 获赞 14 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/u014229652/article/details/82979551
今日推荐