您现在的位置是:首页 >技术杂谈 >SpringBoot+thymeleaf+antd vue 学习记录网站首页技术杂谈

SpringBoot+thymeleaf+antd vue 学习记录

pllpllpll0307 2024-08-23 12:01:02
简介SpringBoot+thymeleaf+antd vue 学习记录

SpringBoot+thymeleaf+antd vue 学习记录

  目前就是先简单做个列表和增删改查的页面,最终实现还要继续学习和调试;
  之前也看过vue,实在是看不懂,这次直接照着组件api来写,把过程记录在这里,防止以后忘记。

一、需要的引用包

<script type="text/javascript" th:src="@{/js/vue/vue.min.js}"></script>
<script type="text/javascript" th:src="@{/js/vue/vue-i18n.min.js}"></script>
<script type="text/javascript" th:src="@{/js/vue/vue-router.min.js}"></script>
<script type="text/javascript" th:src="@{/js/vue/antd.min.js}"></script>
<link rel="stylesheet" th:href="@{/css/vue/antd.css}"> 

二、代码结构

  我是springboot的maven项目,每个模块前后端都整合在一起,模块之间互不干扰,需要的时候pom中引入依赖即可。
在这里插入图片描述
thymeleaf相关配置为:
spring.thymeleaf.cache=false spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html spring.thymeleaf.mode=LEGACYHTML5 spring.thymeleaf.encoding=UTF-8

  src/main/java中创建controller包,并创建测试类;这里的view是为了项目启动后这个路径可以直接定位到我的前端页面:

@Controller
@RequestMapping("/project")
public class ProjectController {
    @GetMapping("/index")
    public ModelAndView projectView(HttpServletRequest request) {
        //页面路径为vue文件夹下的index.html
        ModelAndView mav = new ModelAndView("vue/index");
        return mav;
    }

  在src/main/resouces下创建templates文件夹,用于存放html文件;创建static文件夹,用于存放js和css文件;在templates下创建vue文件夹,在vue下创建index.html。

三、页面

我这里用的Ant Design Vue是V1的版本https://1x.antdv.com/components/layout/

1、Layout页面布局

在文档中挑选一个自己喜欢的布局,把包引用好,直接运行就可以了。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>antd+vue</title>
<script type="text/javascript" th:src="@{/js/vue/vue.min.js}"></script>
<script type="text/javascript" th:src="@{/js/vue/vue-i18n.min.js}"></script>
<script type="text/javascript" th:src="@{/js/vue/vue-router.min.js}"></script>
<script type="text/javascript" th:src="@{/js/vue/antd.min.js}"></script>
<link rel="stylesheet" th:href="@{/css/vue/antd.css}">
<!-- vue1是我调试页面用的css -->
<link rel="stylesheet" th:href="@{/css/vue/vue1.css}">
</head>
<body>
    <div id="app" >
        <a-layout id="components-layout-demo-custom-trigger"> 
            <!-- 左侧菜单 -->
            <a-layout-sider v-model="collapsed" :trigger="null" collapsible>
              <div class="logo" ><div class="title" style="height:28px;padding-top: 4px">测试项目</div></div>
              <a-menu theme="dark" mode="inline" :default-selected-keys="['1']"> 
                 <a-menu-item key="1"> <a-icon type="smile" ></a-icon><span>nav 1</span> </a-menu-item> 
                 <a-menu-item key="2"> <a-icon type="setting" ></a-icon><span>nav 2</span> </a-menu-item> 
                 <a-menu-item key="3"> <a-icon type="upload" ></a-icon> <span>nav 3</span> </a-menu-item> 
              </a-menu> 
            </a-layout-sider> 
            <!-- 右侧布局 -->
            <a-layout> 
              <a-layout-header>Header</a-layout-header> 
              <a-layout-content> 
              <!-- content里面可以放主要内容 -->
              <a-card :bordered="false" style="height: 100%">
              内容
              </a-card>
              </a-layout-content>
              <a-layout-footer>Footer</a-layout-footer>
           </a-layout> 
        </a-layout>
    </div>
</body>
<script>
    var app = new Vue({
        el : '#app',
        data() {
            return {
                collapsed : false,
            }
        }
    })
</script>
</html>

最终页面如图:
在这里插入图片描述

2、Table、Button

我要在content中实现一个table数据列表,用< a-table >标签:

<a-layout-content> 
    <a-card :bordered="false" style="height: 100%">
        <a-table :columns="columns" :data-source="data" :scroll="{ x: 1500, y: 300 }"> 
           <template slot="action" slot-scope="text, record"> 
               <a-button icon="edit"></a-button> 
               <a-button type="danger" icon="delete" @click="handleDel">
               </a-button> 
           </template> 
         </a-table> 
     </a-card>
</a-layout-content>

这里先给定data和columns,以后再改成从后台取值

<script>
// columns和data文档中有很多示例,随便找哪个都行
var columns = [ {
        title : 'Name',
        dataIndex : 'name',
        key : 'name',
        width : 120
    }, ..., {
        title : 'Action',
        key : 'action',
        width : 130,
        fixed : 'right',
        scopedSlots : {//自定义渲染,模板中对应的slot-scope可以用来传递参数
            customRender : 'action',
        },
    } ];
    var data = [ {
        key : '1',
        name : 'John Brown',
        age : 32,
        address : 'New York No. 1 Lake Park',
        tags : [ 'nice', 'developer' ],
    }... ];
    var app = new Vue({
        el : '#app',
        data() {
            return {
                columns : columns,
                data : data,
                collapsed : false,
            }
        }
     })
</script>

列表效果如图:
在这里插入图片描述

3、Modal

  要实现的功能:增加一个add添加按钮,点击按钮打开弹窗,弹窗内容为form表单。

vue我基本没有用过,所以这里费了很多时间,不知道要怎么实现(以前用easyui是直接请求后台controller接口,从接口直接定位到view页面,类似上面的/project/index)

  首先在vue文件夹下创建一个add.html,先把弹窗要显示的内容做好(先随便在文档找了个示例,主要是为了完成绑定添加模板弹窗功能):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div th:fragment="tAdd">
  <template id="vue-add"> 
  <!-- a-model标签为弹窗,v-model用来绑定form -->
   <a-modal :width="modalWidth" title="新增字典" :confimLoading="loading" v-model="show" @ok="handleOk"
           @cancel="handleCancel">
    <a-form :form="form" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }"> 
       <a-form-item label="Note"> 
           <a-input v-decorator="['note', { rules: [{ required: true, message: 'Please input your note!' }] }]" /> 
       </a-form-item> 
       <a-form-item label="Gender"> 
           <a-select v-decorator="['gender',{ rules: [{ required: true, message: 'Please select your gender!' }] },]" 
               placeholder="Select a option and change input text above" @change="handleSelectChange">
             <a-select-option value="male"> male </a-select-option> 
             <a-select-option value="female"> female </a-select-option> 
           </a-select> 
       </a-form-item> 
    </a-form>
    </a-modal>
  </template>
  <script>
     const VueAdd = {
        template: '#vue-add',
        props: {
            value: {
              type: Boolean,
              default: false
            }
          },
        data() {
            return {
                formLayout: 'horizontal',
                form: this.$form.createForm(this, { name: 'coordinated' }),
                show: this.value,
                loading: false,
                modalWidth: window.innerWidth * 0.5,
              };
        },
        methods: {
            handleOk() {
                this.form.validateFields(err => {
                  
                });
                setTimeout(() => {
                  this.$nextTick(() => {
                    this.loading = false;
                  })
                }, 1000);
              },
              handleCancel() {
                this.closeModal(false);
              },
              closeModal(val) {
                this.$emit('input', val);
              },
            handleSelectChange(value) {
                  console.log(value);
                  this.form.setFieldsValue({
                    note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
                  });
                },
        },
        watch: {
            value(val) {
              this.show = val;
            },
            show(val) {
              if (val) {
                this.form.resetFields();
              } else {
                this.closeModal(val);
              }
            }
          },
    } 
</script>
</div>
</html>

在index.html中绑定添加模板:

<template th:replace="@{vue/add}::tAdd"></template>
<a-card :bordered="false" style="height: 100%">
     <div class="editable-add-btn">
           <a-button @click="handleAdd"> 
              <a-icon type="plus" ></a-icon>Add 
            </a-button>
      </div>
      <!-- vue-add即为add.html的模板 -->
      <vue-add v-model="addShow" ></vue-add>
      <a-table :columns="columns" :data-source="data" :scroll="{ x: 1500, y: 300 }"> ...</a-table> 
 </a-card>
<script>
var app = new Vue({
        el : '#app',
        components: {
            'vue-add': VueAdd,
        },
        props: {
            addShow: {
              type: Boolean,
              default: false
            }
          },
        data() {
            return {
                ...,
                addShow: false,
            }
        },
        methods: {
            handleAdd() {
                this.addShow = true;
              },
              handleDel() {
                  this.$confirm({
                    title: '确定要删除这条数据吗?',
                    content: 'Some descriptions',
                    okText: 'Yes',
                    okType: 'danger',
                    cancelText: 'No',
                    onOk() {
                      console.log('OK');
                    },
                    onCancel() {
                      console.log('Cancel');
                    },
                  });
                },
        }
    })
</script>

点击Add,效果如图:
在这里插入图片描述
最后把我的css也贴到这里

#app {
  text-align: center;
}
.ant-layout-header,
.ant-layout-footer {
  background: #263259;
  color: #fff;
}
#app .ant-layout-footer {
  line-height: 1;
}
#app .ant-layout-sider {
  background: #000000;
  color: #fff;
  height:100vh;
}
#app .ant-layout-content {
  color: #fff;
  min-height: 120px;
}
#app > .ant-layout {
  margin-bottom: 48px;
}
#app > .ant-layout:last-child {
  margin: 0;
}
#components-layout-demo-custom-trigger .trigger {
  font-size: 18px;
  line-height: 64px;
  padding: 0 24px;
  cursor: pointer;
  transition: color 0.3s;
}

#components-layout-demo-custom-trigger .trigger:hover {
  color: #1890ff;
}

#components-layout-demo-custom-trigger .logo {
  height: 32px;
  background: rgba(255, 255, 255, 0.2);
  margin: 16px;
}
.ant-menu {
    background: #1f3247;
}
.editable-add-btn {
    margin: 8px 8px 8px 0px;
    text-align: right;
}

  以后还需要调整的有从后台获取数据、添加/编辑提交、列表排序,以及最重要的router跳转…好多东西啊,这次暂时只做到了这里,后续有时间会继续完善,有同样在学习这个的小伙伴可以评论区一起交流~

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。