前后端分离学习笔记 ---[路由嵌套, 查询表单显示]

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.vueRoleLost.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)的使用(代码