
🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的专栏《ELement》。🎯🎯
👉点击这里,就可以查看我的主页啦!👇👇
🎁如果感觉还不错的话请给我点赞吧!🎁🎁
💖期待你的加入,一起学习,一起进步!💖💖

目录
在上一篇博文我们搭建了首页导航和左侧菜单,但是我们的左侧菜单是死数据今天我们就来把死的变成活的,并且完成右侧内容的书籍数据表格的展示与分页效果,话不多说上代码!!
首先我们将后端的代码写好Controller层代码
- package com.zking.ssm.controller;
-
- import com.zking.ssm.model.Module;
- import com.zking.ssm.model.RoleModule;
- import com.zking.ssm.model.TreeNode;
- import com.zking.ssm.service.IModuleService;
- import com.zking.ssm.util.JsonResponseBody;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
-
- import java.util.List;
-
- @Controller
- @RequestMapping("/module")
- public class ModuleController {
-
- @Autowired
- private IModuleService moduleService;
-
- @RequestMapping("/queryRootNode")
- @ResponseBody
- public JsonResponseBody
> queryRootNode(){
- try {
- List
modules = moduleService.queryRootNode(-1); - return new JsonResponseBody<>("OK",true,0,modules);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("初始化首页菜单错误",false,0,null);
- }
- }
-
- @RequestMapping("/queryElementTree")
- @ResponseBody
- public JsonResponseBody
> queryElementTree(){
- try {
- List
modules = moduleService.queryTreeNode(-1); - return new JsonResponseBody<>("OK",true,0,modules);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("初始化ElementUI的Tree组件错误",false,0,null);
- }
- }
-
- @RequestMapping("/addRoleModule")
- @ResponseBody
- public JsonResponseBody> addRoleModule(RoleModule roleModule){
- try {
- moduleService.addRoleModule(roleModule);
- return new JsonResponseBody<>("新增角色权限成功",true,0,null);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("新增角色权限失败",false,0,null);
- }
- }
-
- @RequestMapping("/queryModuleByRoleId")
- @ResponseBody
- public JsonResponseBody
> queryModuleByRoleId(RoleModule roleModule){
- try {
- List
modules = moduleService.queryModuleByRoleId(roleModule); - return new JsonResponseBody<>("OK",true,0,modules);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("获取角色权限失败",false,0,null);
- }
- }
- }
由此我们可知后端查询的树形菜单的接口为:http://localhost:8080/ssm/module/queryRootNode
数据有了我们只用考虑怎么通过Vue拿到数据以及展示数据就可以了。
找到src下面的api目录下的action.js文件添加下列接口
'SYSTEM_USER_MODULE': '/module/queryRootNode', //左侧菜单
在LeftNav.vue中的钩子函数内编写方法去到后端拿取数据赋予变量
- created() {
- this.$root.Bus.$on('aaa', r => {
- this.collapsed = r;
- });
- //加载页面先去后端拿数据
- let url = this.axios.urls.SYSTEM_USER_MODULE;
- this.axios.get(url, {}).then(r => {
- this.menus=r.data.rows
- }).catch(e => {
-
- })
-
- }
并在data中定义变量 menus:[]
menus:[]
去到我们ELement查找相应的代码进行cv,下面是我找好的你们直接用,我们现在只需要将后端获取到的数据在上面的代码中进行遍历即可。
-
- <el-submenu v-for="m in menus" :index="'ind_'+m.id" :key="'key_'+m.id">
- <template slot="title">
- <i :class="m.icon">i>
- <span>{{m.text}}span>
- template>
- <el-menu-item v-for="ms in m.modules" :index="ms.url" :key="'key_'+ms.id">
- <i :class="ms.icon">i>
- <span>{{ms.text}}span>
- el-menu-item>
- el-submenu>
效果展示:

我们点击下方的子菜单肯定会显示右侧白框里面的内容,所以我们需要实现动态路由
①实现路由跳转及当前项的设置
default-active="$route.path"> - <el-menu-item index="/company/userManager">用户管理el-menu-item>
注意事项:
①要实现路由跳转,先要在
el-menu标签上添加router属性,然后只要在每个el-menu-item标签内的index属性设置一下url即可实现点击el-menu-item实现路由跳转。②导航当前项,在
el-menu标签中绑定 :default-active="$route.path",注意是绑定属性,不要忘了加“:”,当$route.path等于el-menu-item标签中的index属性值时则该item为当前项。③el-submenu标签中的url属性不能为空,且不能相同,否则会导致多个节点收缩/折叠效果相同的问题。
②生成相对应的Vue文件
根据我们点击子菜单所显示的层级关系进行Vue组件的编写,下面以书本管理下面的新增书本为例

AddBook.Vue
- <h1>新增书本h1>
-
- <script>
- script>
-
- <style>
- style>
③配置路由与路由路径的关系
index.js
- import Vue from 'vue'
- import Router from 'vue-router'
- import HelloWorld from '@/components/HelloWorld'
- import AppMain from '@/components/AppMain'
- import LeftNav from '@/components/LeftNav'
- import TopNav from '@/components/TopNav'
-
- import Login from '@/views/Login'
- import Registered from '@/views/Registered'
- import AddBook from '@/views/book/AddBook'
- import BookList from '@/views/book/BookList'
-
-
- Vue.use(Router)
-
- export default new Router({
- routes: [{
- path: '/',
- name: 'Login',
- component: Login
- }, {
- path: '/Registered',
- name: 'Registered',
- component: Registered
- }, {
- path: '/AppMain',
- name: 'AppMain',
- component: AppMain,
- children: [{
- path: '/LeftNav',
- name: 'LeftNav',
- component: LeftNav
- }, {
- path: '/TopNav',
- name: 'TopNav',
- component: TopNav
- }, {
- path: '/book/AddBook',
- name: 'AddBook',
- component: AddBook
- }, {
- path: '/book/BookList',
- name: 'BookList',
- component: BookList
- }]
- }]
- })
④将组件渲染到页面上
在AppMain.js中显示组件就需要加上
- <el-container class="main-container">
- <el-aside v-bind:class="asideClass">
- <LeftNav>LeftNav>
- el-aside>
- <el-container>
- <el-header class="main-header">
- <TopNav>TopNav>
- el-header>
- <el-main class="main-center">
- <router-view>router-view>
- el-main>
- el-container>
- el-container>
-
- <script>
- // 导入组件
- import TopNav from '@/components/TopNav.vue'
- import LeftNav from '@/components/LeftNav.vue'
-
- // 导出模块
- export default {
- components: {
- TopNav,LeftNav
- },data() {
- return {
- asideClass: "main-aside"
- }
- },
- created(){
- this.$root.Bus.$on('aaa',r=>{
- this.asideClass=r ? 'main-aside-collapsed':'main-aside';
- });
- }
- };
- script>
- <style scoped>
- .main-container {
- height: 100%;
- width: 100%;
- box-sizing: border-box;
- }
-
- .main-aside-collapsed {
- /* 在CSS中,通过对某一样式声明! important ,可以更改默认的CSS样式优先级规则,使该条样式属性声明具有最高优先级 */
- width: 64px !important;
- height: 100%;
- background-color: #334157;
- margin: 0px;
- }
-
- .main-aside {
- width: 240px !important;
- height: 100%;
- background-color: #334157;
- margin: 0px;
- }
-
- .main-header,
- .main-center {
- padding: 0px;
- border-left: 2px solid #333;
- }
- style>
效果演示:

首先我们分析一下,我们右侧有那些内容?然后去到我们ELementUI官网查找相对应的案例代码,我们首先需要一个form表单提供我们输入书籍名称进行模糊查询,还需要数据表格展示数据,其次就是底部的分页条来完成分页效果,知道了需求我们直接去找案例代码即可。
AddBook.js
- <div>
-
- <el-form :inline="true" class="form-search" style="padding: 30px;">
- <el-form-item label="书本名称">
- <el-input v-model="bookname" placeholder="请输入书本名称">el-input>
- el-form-item>
- <el-form-item>
- <el-button type="primary" icon="el-icon-search" @click="query(1)">查询el-button>
- el-form-item>
- el-form>
-
-
- <el-table :data="tableData" style="width: 100%" :row-class-name="tableRowClassName">
- <el-table-column prop="id" label="编号" width="180">
- el-table-column>
- <el-table-column prop="bookname" label="书籍名称" width="180">
- el-table-column>
- <el-table-column prop="price" label="书籍价格" width="180">
- el-table-column>
- <el-table-column prop="booktype" label="书籍类别" width="180">
- el-table-column>
- el-table>
-
-
- <div class="block">
- <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage4"
- :page-sizes="[100, 200, 300, 400]" :page-size="100" layout="total, sizes, prev, pager, next, jumper"
- :total="400">
- el-pagination>
- div>
-
- div>
-
-
-
-
- <script>
- export default {
- data() {
- return {
- bookname: "",
- tableData: []
- }
- },
- methods: {
-
- }
- }
- script>
-
-
-
- <style>
- .el-table .warning-row {
- background: oldlace;
- }
-
- .el-table .success-row {
- background: #f0f9eb;
- }
- style>

这样我们的基本内容就搭建完成了
和前面一样我们先去后端将接口定义好
- package com.zking.ssm.controller;
-
- import com.zking.ssm.model.Book;
- import com.zking.ssm.service.IBookService;
- import com.zking.ssm.util.JsonResponseBody;
- import com.zking.ssm.util.PageBean;
- import com.zking.ssm.vo.BookFileVo;
- import org.apache.commons.io.IOUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.multipart.MultipartFile;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.URLEncoder;
- import java.util.List;
- import java.util.Map;
-
- @Controller
- @RequestMapping("/book")
- public class BookController {
-
- @Autowired
- private IBookService bookService;
-
- @RequestMapping("/addBook")
- @ResponseBody
- public JsonResponseBody> addBook(Book book){
- try {
- bookService.insert(book);
- return new JsonResponseBody<>("新增书本成功",true,0,null);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("新增书本失败",false,0,null);
- }
- }
-
- @RequestMapping("/editBook")
- @ResponseBody
- public JsonResponseBody> editBook(Book book){
- try {
- bookService.updateByPrimaryKey(book);
- return new JsonResponseBody<>("编辑书本成功",true,0,null);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("编辑书本失败",false,0,null);
- }
- }
-
- @RequestMapping("/delBook")
- @ResponseBody
- public JsonResponseBody> delBook(Book book){
- try {
- bookService.deleteByPrimaryKey(book.getId());
- return new JsonResponseBody<>("删除书本成功",true,0,null);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("删除书本失败",false,0,null);
- }
- }
-
- @RequestMapping("/queryBookPager")
- @ResponseBody
- public JsonResponseBody
> queryBookPager(Book book, HttpServletRequest req){
- try {
- PageBean pageBean=new PageBean();
- pageBean.setRequest(req);
- List
books = bookService.queryBookPager(book, pageBean); - return new JsonResponseBody<>("OK",true,pageBean.getTotal(),books);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("分页查询书本失败",false,0,null);
- }
- }
-
- @RequestMapping("/queryBookCharts")
- @ResponseBody
- public JsonResponseBody> queryBookCharts(){
- try{
- Map
charts = bookService.queryBookCharts(); - return new JsonResponseBody<>("OK",true,0,charts);
- }catch (Exception e){
- e.printStackTrace();
- return new JsonResponseBody<>("查询统计分析数据失败",false,0,null);
- }
- }
-
- @RequestMapping("/upload")
- @ResponseBody
- public JsonResponseBody> upload(BookFileVo bookFileVo){
- try {
- MultipartFile bookFile = bookFileVo.getBookFile();
- System.out.println(bookFileVo);
- System.out.println(bookFile.getContentType());
- System.out.println(bookFile.getOriginalFilename());
- return new JsonResponseBody<>("上传成功",true,0,null);
- } catch (Exception e) {
- e.printStackTrace();
- return new JsonResponseBody<>("上传失败",false,0,null);
- }
- }
-
- @RequestMapping("/download")
- public void download(HttpServletRequest request, HttpServletResponse response){
- try {
- String relativePath = "uploads/1.jpg";
- String absolutePath = request.getRealPath(relativePath);
- InputStream is = new FileInputStream(new File(absolutePath));
- OutputStream out = response.getOutputStream();
- response.setContentType("application/octet-stream");
- response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("1.jpg", "UTF-8"));
- byte[] by = new byte[1024];
- int len = -1;
- while (-1 != (len = is.read(by))) {
- out.write(by);
- }
- is.close();
- out.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- @RequestMapping("/downloadUrl")
- public void downloadUrl(HttpServletRequest request, HttpServletResponse response){
- String relativePath = "uploads/1.jpg";
- String absolutePath = request.getRealPath(relativePath);
- InputStream is = null;
- OutputStream out = null;
-
- try {
- is = new FileInputStream(new File(absolutePath));
- // 设置Content-Disposition
- response.setHeader("Content-Disposition",
- "attachment;filename=" + URLEncoder.encode("1.jpg", "UTF-8"));
- out = response.getOutputStream();
- IOUtils.copy(is, out);
- response.flushBuffer();
- System.out.println("完成");
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- IOUtils.closeQuietly(is);
- IOUtils.closeQuietly(out);
- }
- }
- }
-
由此我们可知后端查询书籍的接口为:http://localhost:8080/ssm/book/queryBookPager
action.js文件添加下列接口
'BOOK_LIST': '/book/queryBookPager', //书籍查询
在AddBook.vue中的钩子函数内编写方法去到后端拿取数据赋予变量
- created() {
- //加载页面先去后端拿数据
- let params={
- bookname:this.bookname
- }
- let url = this.axios.urls.BOOK_LIST;
- this.axios.get(url, {params:params}).then(r => {
- console.log(r)
- this.tableData = r.data.rows
- }).catch(e => {
-
- })
-
- }
由于不止我们初始页面需要用到这个方法模糊查询也要所以我们将该代码进行封装让它有复用性
- methods: {
- //封装查询方法
- list(params) {
- let url = this.axios.urls.BOOK_LIST;
- this.axios.get(url, {
- params: params
- }).then(r => {
- console.log(r)
- this.tableData = r.data.rows
- }).catch(e => {
-
- })
- },
- //模糊查询方法
- query() {
- let params = {
- bookname: this.bookname
- }
- this.list(params)
- }
- },
- created() {
- //加载页面先去后端拿数据
- let params = {
- bookname: this.bookname
- }
- this.list()
-
- }
效果展示:

更改我们的分页栏代码并定义变量,编写分页栏中自带的两个方法,一个是页码发生变化会触发一个是页数发生改变会触发。
- <div class="block">
- <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page"
- :page-sizes="[10, 20, 30, 40]" :page-size="rows" layout="total, sizes, prev, pager, next, jumper"
- :total="total">
- el-pagination>
- div>
- export default {
- data() {
- return {
- bookname: "",
- tableData: [],
- rows: 10,
- page: 1,
- total: 0,
-
- }
- },
- methods: {
- //封装查询方法
- list(params) {
- let url = this.axios.urls.BOOK_LIST;
- this.axios.get(url, {
- params: params
- }).then(r => {
- console.log(r)
- this.tableData = r.data.rows
- this.total = r.data.total
- }).catch(e => {
-
- })
- },
- //模糊查询方法
- query() {
- let params = {
- bookname: this.bookname
- }
- this.list(params)
- },
- //当页发生变化会触发
- handleSizeChange(r) {
- let params = {
- bookname: this.bookname,
- rows: this.rows,
- rows: r
- }
- this.list(params)
- },
- //当前页数发生变化会触发
- handleCurrentChange(p) {
- let params = {
- bookname: this.bookname,
- rows: this.rows,
- page: p
- }
- this.list(params)
- }
-
- },
- created() {
- //加载页面先去后端拿数据
- let params = {
- bookname: this.bookname
- }
- this.list()
-
- }
-
- }
效果展示:


到这里我的分享就结束了,欢迎到评论区探讨交流!!
💖如果觉得有用的话还请点个赞吧 💖
