前后端分离学习笔记 ---[路由嵌套, 查询表单显示]
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前后端分离学习笔记 ---[路由嵌套, 查询表单显示]相关的知识,希望对你有一定的参考价值。
可以参考学习ElementUI框架的API —>ElementUI框架的API
文章目录
1.路由嵌套
上一篇笔记的学习 管理员登录权限分配
点击左侧的操作菜单会生成一个显示的具体的管理表单;
可以设想一下,打开的基本布局就是这样的
这边的view
视图处就写几个目录,作为不同的管理操作页面组件;
比如这个角色管理页面组件RoleList.vue
<template>
<div>
角色管理
</div>
</template>
<script>
</script>
<style>
</style>
管理员管理页面组件AdminList.vue
<template>
<div>
管理员管理
</div>
</template>
<script>
</script>
<style>
</style>
注意左侧栏打开后要在main页面中显示,而不是页面跳转;
router路由目录下的index.js
中导入组件AdminList.vue
和RoleLost.vue
;
将他们嵌套到main页面的子路由下即可;完成路由嵌套
router路由目录下的index.js
import Vue from 'vue';
import router from 'vue-router'; /* 导入路由 */
import Login from '../view/Login.vue'; /* 导入其他页面 */
import Main from '../view/Main.vue'; /* 导入其他页面 */
//导入管理员管理组件和角色管理组件;
import Admin from '../view/admin/AdminList.vue';
import Role from '../view/role/RoleList.vue';
Vue.use(router)
/* 定义组件路由 */
var rout = new router(
routes: [
//登录页面组件;
path: '/login',
name: 'index',
component: Login
,
//主页面组件;
path: '/main',
component: Main,
//嵌套子路由;
children:[
//管理员管理组件;
path: '/admin',
component:Admin,
,
//角色管理组件;
path: '/role',
component:Role,
]
,
/*
path: '/demo',
component: demo
, */
]
);
//导出路由;
export default rout;
//to-将要访问的页面地址,from-从哪个页面访问的,next-放行函数
rout.beforeEach((to, from, next) =>
//如果用户访问的登录页,直接放行;
if (to.path == '/login')
return next();
else
//若没有令牌,则推到登录页面;
var token = window.sessionStorage.getItem("token");
if (token == null)
return next("/login");
else
next();
)
启动前后端服务, 试试;
点击角色管理,则路由到/role路径下;
点击管理员管理,路由到/admin路径下
注意数据表中存储路径时;仅存储路由路径即可
2.查询表单显示信息
这里先分步骤分析情况,最后会进行大总结;
2.1 显示管理员的头像
还记着之前的spring学习中,当时和小伙伴们写的一个小demo中,就涉及到要展示头像;
当时是将存储头像的本地文件夹托管到tomcat服务器的虚拟路径上;
这个在之前的案例有相似的整理笔记–>将本地文件夹部署给tomcat服务器的虚拟路径
而这次前后端分离学习的话,这个springboot这边是自己开了一个服务器;http://127.0.0.1:5277/
,端口为5277;
而前端这个HBuilderX 放置的前端页面部分开了默认服务器http://localhost:8080/
;端口为8080;
那么我这里就为管理员的头像存储单独开一个服务器;
http://localhost:5927/
其实就是我这里本地重新解压安装了一个tomcat服务器;
注意在安装包的conf
配置目录下修改一下该服务器的端口号;我这里是根据自己的需要改成5927
了;
另外,若修改后的端口和其他的路径出现端口冲突时,再改改就行;
注意将访问的图片文件夹放到tomcat安装包的webapps下的ROOT目录下;
同样地,为了效果好一点,这里未管理员准备了默认的头像文件夹目录
default
;
可手动开启存储头像的服务器;
头像显示效果
那么这里前端组件是如何编写的呢
首先这个表格的列属性 prop为newFileName
,是通过发出的请求查询到的管理员表中的新头像文件名newFileName
;
然后利用了ElementUI的表格自定义模板;<template slot-scope="scope">
;
这里的scope.row
就表示当前行的数据;这个scope.row.account
就是当前行的管理员账号名;
scope.row.newFileName
就是当前行的管理员新头像名称;
图片img的绑定路径src
中出现的http
是在下面定义的管理员头像的图片地址;
这里使用 v-if 和v-else指令;
根据得到的管理员是否有头像,判断分配显示的头像;
定义管理员的头像文件存储的服务器地址
http: "http://127.0.0.1:5927/studyspringbootvue/",
就是之前创建的这个;
2.2 自定义显示的格式
例如;列表中的管理员类型和日期显示格式;
在数据库存储管理员类型时使用的是01(0:超管;1:普通管理员)存储;
这里肯定不能直接显示数字;那么就需要自定义显示的模板;
需要的显示效果
可以参考学习ElementUI框架的API —>ElementUI框架的API
先看管理员类型的格式处理;
这里使用了 formatter
函数绑定事件formaterType
在下面的JS绑定事件formatType(row,column)
;
对当前行的管理员类型进行判断;返回数据;
再看看 日期类型的格式处理;
可以使用这个sortable
,生成对时间的排序按钮;
同样使用 formatter
函数绑定事件formaterTime
在下面的JS绑定事件formatTime(row,column)
;
对当前行的管理员操作时间进行格式转换处理;返回数据;
点击^
按照时间升序排序显示,点击v
按照时间降序排序显示;
2.3 对于双重循环数据的处理;
注意这边的话,需要显示当前管理员属于的角色;
那么角色不止一个,也就是说一个管理员可能会对应多个角色;
这里本来的话可以直接用管理员表
左关联管理角色关系表
,然后再左关联角色表
,查询到管理员的对应角色;
SELECT
a.`id`,
a.`account`,
a.`password`,
a.`sex`,
a.`phone`,
a.`new_file_name`,
a.`type`,
a.`oper_time`,
r.`name`
FROM t_admin a
LEFT JOIN t_admin_role am ON am.`admin_id`=a.`id`
LEFT JOIN t_role r ON am.`role_id` = r.`id`
WHERE a.`type` = 1
注意看查询的效果,这个当然要说查询的话也是完全可以的;
但是我这次要搭建的案例,需要对查询到的数据进行数据分页
;
那么到时候数据分页的话就会按照查询的结果进行分页;
要是这样子直接分页的话,显示效果就肯定不太好;
可以这样假设一下;比如某位管理员它的角色右50多种;那么这个查询过来50行数据全是这位管理员的信息,数据冗余,对于系统来说的话,质量效果是不太好的;
那么就得考虑嵌套查询了;回顾之前学到的嵌套查询,懒加载方面的知识;
这是在mybatis学习的时候学过的;
这里有整理的笔记哦—>Mybatis框架学习笔记(6) — [懒加载配置 应用到嵌套查询]
这边的话,考虑先查询到管理员表,根据查询到的管理员Id作为条件,再去查询对应Id的关联角色信息;
在管理员类中也是将
private List<Role> roleList;
在SQL的处理中,使用resultmap
结果集映射作为桥接;
将查询到的管理员Id作为条件,查询一下该Id对应的所有关联角色;最终再把查询的管理列表信息返回;
这里前端组件显示的话,当然表格列的属性prop也就四管理员类中的属性roleList
;
然后再遍历该行的角色列表数据即可; 显示角色的名称即可
显示效果
2.4 表单栏顶部的查询条件设置
这里就需要绑定数据,进行传值;
绑定的数据域
绑定的search事件;这里的话,因为加载页面时就需要发出请求查询列表,这里根据条件查询,
其实用同一条请求即可;然后就是后端的动态SQL绑定使用;
根据是否传入查询条件,决定是否添加查询的条件;
查询效果:
2.5 分页处理,使用PageHelper组件
在ElementUI的分页组件中就可以找到,这是前端的显示效果;
那么这里就需要前后端的数据交互了;
- 前端需要显示数据的总条数,
- 显示当前的页码,
- 显示当前页可以显示几条数据;
- 显示一共有多少页;
实际上,只需要让后端传递过来一共有几条数据即可,这里显示多少页的工作就交给组件的封装计算了;
current-page="1"
默认是第一页
page-sizes="[2, 4, 6, 8]"
生成下拉框的数组(每页显示几条数据)
page-size="2"
默认的每页大小
layout="total, sizes, prev, pager, next, jumper"
布局
total="200"
数据的总条数
@size-change="handleSizeChange"
当下拉框改变页数大小时触发
@current-change="handleCurrentChange"
当改变页码时触发
注意里面有几个是需要绑定的数值;是需要动态传递数据的;
前端先后端发出pageNum
当前的页码; 发出 pageSize
当前页面的数据量;
当然这里直接就用那个查询管理员的通用方法;顺便把当前的页码数据和当前页码显示的数据量传递进去;
选择页码,选择当前页显示的数据量时触发事件;
再来看看后端的处理,分页查询首先想到的是SQL中的limit
限制语句;
但是这里的分页组件也不错;
PageHelper组件
在pom.xml
中导入即可使用;
<!-- pagehelper依赖 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
Sql映射文件这里甚至不用写limit语句,它会自动拼接进去查询
这里案例学习的话,为了接受数据方便,就直接把数据存到Admin管理员类中;
实际使用的话,建议重新定义一个分页实体类;
在调用的服务层方法处;
先用PageHelper
类的startPage
将分页的页码数据和每页显示的数据量传入;
等持久层这边把所有的管理员信息列表查询出来后,
再用PageInfo
类进行分页处理;
那么到时候这个查询的返回值类型也得按照PageInfo
类型的;
然后之前写的通用返回类中也需要定义一个属性,表示数据量的总数;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author by @CSDN 小智RE0
* @date 2021-12-28 16:02
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResult
private Integer code;
private String msg;
private Object data;
//分页使用;数据总量;
private Long total;
public CommonResult(Integer code, String msg, Object data)
this.code = code;
this.msg = msg;
this.data = data;
这时你可能就要问了,由于前端需要数据量的总数,来为分页做准备;
是不是还需要去查询一下管理员的数据总数;
完全不需要;
PageInfo可以调用这个方法getTotal()
得到没有限制条件时,之前查询的管理员信息总数;
需要注意的地方
springboot 2.5 版本之后,要集成这个分页组件时,就得在springboot的yml配置文件中
设置开启循环依赖
注意是spring下的main
中的设置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/day20211126_manage_db?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
filters: stat
initialSize: 5
minIdle: 1
maxActive: 20
main:
allow-circular-references: true
当然,前端需要接受到后端计算出的数据总量;绑定到对应的数据域模块变量total
上;
这个查询表单的整体简易搭建
前端的Main.vue
主页面
权限分配案例搭建时就已经写过了 前后端分离学习笔记(3) --[管理员权限分配操作菜单案例]
管理员列表组件页面
AdminList.vue
<template>
<el-card class="box-card" style="background-color: #E9EEF3;">
<div slot="header" class="clearfix">
<span>管理员列表</span>
<el-button style="float: right; padding: 10px 10px" type="success"
@click="openAddAdmin()">新增</el-button>
</div>
<div class="text">
<!-- 查询条件框-->
<div class="clearfix" style="padding-bottom: 10px;">
<!-- 查询条件-->
<el-row :gutter="20">
<el-col :span="6">
<el-input placeholder="账号" v-model="query.account"></el-input>
</el-col>
<el-col :span="6">
<el-input placeholder="性别" v-model="query.sex"></el-input>
</el-col>
<el-col :span="6">
<el-button type="primary" icon="el-icon-search" @click="search()">搜索</el-button>
</el-col>
</el-row>
</div>
<!-- 数据表格位置-->
<el-table :data="tableData" style="width: 100%" border max-height="450">
<el-table-column fixed type="index" label="编号" width="60">
</el-table-column>
<el-table-column prop="account" label="账号" width="100"></el-table-column>
<el-table-column prop="newFileName" label="头像" width="60">
<template slot-scope="scope">
<!-- 若没有头像,则显示默认头像 -->
<img v-bind:src="http+'default/admin.png'" width="30" height="30"
v-if="scope.row.newFileName === null " />
<!-- 否则显示管理员的头像 -->
<img v-bind:src="http+scope.row.account+'/'+scope.row.newFileName" width="30" height="30"
v-else />
</template>
</el-table-column>
<el-table-column prop="sex" label="性别" width="50"></el-table-column>
<el-table-column prop="phone" label="手机" width="120"></el-table-column>
<el-table-column prop="type" label="类型" width="120" :formatter="formatType"></el-table-column>
<el-table-column prop="roleList" label="角色" width="250" align="center">
<template slot-scope="scope">
<span v-for="(role,index) in scope.row.roleList" :key="index">role.name-</span>
</template>
</el-table-column>
<!-- 时间加上排序 -->
<el-table-column prop="operTime" label="时间" width="200" :formatter="formatTime" sortable>
</el-table-column>
<el-table-column fixed="right" label="操作" width="200">
<template slot-scope="scope">
<el-button size="mini" @click="toUpdate(scope.row.id)">编辑</el-button>
<el-button size="mini" type="danger" @click="toDelAdmin(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件-->
<!--
current-page="1" 默认是第一页
page-sizes="[2, 4, 6, 8]" 生成下拉框
page-size="2" 默认的每页大小
layout="total, sizes, prev, pager, next, jumper" 布局
total="400" 总条数
@size-change="handleSizeChange" 当下拉框改变页数大小时触发
@current-change="handleCurrentChange" 当改变页码时触发
-->
<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-sizes ="[2, 4, 6, 8,10,15]"
:page-size="2"
layout="total, sizes, prev, pager, next, jumper"
:total= "total">
</el-pagination>
</div>
</div>
</el-card>
</template>
<script>
export default
data: function()
return
tableData: [],
//定义的图片服务器位置;
http: "http://127.0.0.1:5927/studyspringbootvue/",
//根据条件搜索时的绑定参数;
query:
account: '',
sex: '',
//当前页码;
pageNum:1,
//当前页面数据量;
pageSize:2
,
//数据总条数;
total:0
,
methods:
//管理员类型的自定义绑定事件;
//row表示此行数据 row.列名 得到当前列的数据
formatType(row, column)以上是关于前后端分离学习笔记 ---[路由嵌套, 查询表单显示]的主要内容,如果未能解决你的问题,请参考以下文章
Python全栈100天学习笔记Day48 前后端分离开发入门
Python全栈100天学习笔记Day48 前后端分离开发入门
SpringBoot+Vue入门并实现前后端分离和数据库查询(入门笔记超详细)
RuoYi 若依后台管理系统-学习笔记-前后端分离项目中下拉框验证失效
RuoYi 若依后台管理系统-学习笔记-前后端分离项目中下拉框验证失效
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)七(品牌查询,品牌提交表单信息以及表单页面信息和校验)以及axios(Ajax)的使用(代码