一,动态树
本文章为上一篇文章拓展内容==》》实现首页导航及左侧菜单
将左侧菜单结构更换为下面代码:
菜单结构:
<el-menu> <el-submenu index="" key=""> <template slot="title"> <i class=""></i> <span></span> </template> <el-menu-item index="" key=""> <i class=""></i> <span></span> </el-menu-item> </el-submenu> </el-menu>
第一级节点
el-submenu
中key属性唯一,index属性唯一,而index属性用于控制菜单折叠; 第二级节点el-menu-item
中key属性唯一,index属性唯一,而index属性用于控制页面跳转;
配置action.js
action.js:
'SYSTEM_MENUS': '/module/queryRootNode', //左侧动态树
vue+element的el-menu组件实现路由跳转及当前项的设置:
<el-menu router :default-active="$route.path"> </el-menu>
注1:要实现路由跳转,先要在
el-menu
标签上添加router属性,然后只要在每个el-menu-item
标签内的index属性设置一下url即可实现点击el-menu-item
实现路由跳转注2:导航当前项,在
el-menu
标签中绑定 :default-active="$route.path",注意是绑定属性,不要忘了加“:”,当$route.path等于el-menu-item
标签中的index属性值时则该item为当前项。注3:el-submenu标签中的url属性不能为空,且不能相同,否则会导致多个节点收缩/折叠效果相同的问题
1.1 前端导航菜单
<template> <el-menu router :default-active="$route.path" default-active="2" class="el-menu-vertical-demo" background-color="#334157" text-color="#fff" active-text-color="#ffd04b" :collapse="collapsed"> <!-- <el-menu default-active="2" :collapse="collapsed" collapse-transition router :default-active="$route.path" unique-opened class="el-menu-vertical-demo" background-color="#334157" text-color="#fff" active-text-color="#ffd04b"> --> <div class="logobox"> <img class="logoimg" src="../assets/img/logo.png" alt=""> </div> <el-submenu v-for="m in menus" :index="'idx_'+m.id" :key="'Key1'+m.id"> <template slot="title"> <i :class="m.icon"></i> <span>{{m.text}}</span> </template> <el-menu-item v-for="m2 in m.modules" :index="m2.url" :key="'Key2_'+m2.id"> <i :class="m2.icon"></i> <span>{{m2.text}}</span> </el-menu-item> </el-submenu> </el-menu> </template>
1.2 后端数据controller:
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<List<Book>> queryBookPager(Book book, HttpServletRequest req){ try { PageBean pageBean=new PageBean(); pageBean.setRequest(req); List<Book> 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<String, Object> 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); } } }
1.3 数据绑定
<script> export default { data() { return { collapsed: false, menus: [] } }, created() { this.$root.Bus.$on('aaa', r => { this.collapsed = r; }); let url = this.axios.urls.SYSTEM_MENUS; this.axios.get(url, {}).then(r => { console.log(r); this.menus = r.data.rows; }).catch(e => { }) } } </script>
1.4 路由绑定页面编写
2.3.1 编写vue界面以便数据的显示与跳转:
AddBook:
<template> <h1>书籍新增</h1> </template> <script> </script> <style> </style>
BookList.vue:
<template> <div> <!-- 上搜索框 --> <div class="books"> <el-form :inline="true" class="demo-form-inline" style="margin-top: 40px; margin-left: 20px;"> <el-form-item label="书本名称"> <el-input v-model="bookname" placeholder="请输入书本名称..."></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">查询</el-button> </el-form-item> </el-form> </div> <!-- 中 数据表格 --> <el-table :data="tableData" style="width: 100%"> <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="书本价格"></el-table-column> <el-table-column prop="booktype" label="书本类型"></el-table-column> </el-table> <!-- 下 分页条 --> <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> </div> </template>
在index.js路由绑定页面
在index.js配置:
indedx.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 Register from '@/views/Register' 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: '/Register', name: 'Register', component: Register, }, { 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 }] }] })
二,数据表格与分页
首先我们分析一下,我们右侧有那些内容?然后去到我们ELementUI官网查找相对应的案例代码,我们首先需要一个form表单提供我们输入书籍名称进行模糊查询,还需要数据表格展示数据,其次就是底部的分页条来完成分页效果,知道了需求我们直接去找案例代码即可
2.1 后端接口定义Controller:
@RequestMapping("/queryBookPager") @ResponseBody public JsonResponseBody<List<Book>> queryBookPager(Book book, HttpServletRequest req){ try { PageBean pageBean=new PageBean(); pageBean.setRequest(req); List<Book> books = bookService.queryBookPager(book, pageBean); return new JsonResponseBody<>("OK",true,pageBean.getTotal(),books); } catch (Exception e) { e.printStackTrace(); return new JsonResponseBody<>("分页查询书本失败",false,0,null); } }
action.js文件添加下列接口
'BOOK_LIST': '/book/queryBookPager', //书籍查询
2.2 前端编写:
<template> <div> <!-- 上搜索框 --> <div class="books"> <el-form :inline="true" class="demo-form-inline" style="margin-top: 40px; margin-left: 20px;"> <el-form-item label="书本名称"> <el-input v-model="bookname" placeholder="请输入书本名称..."></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">查询</el-button> </el-form-item> </el-form> </div> <!-- 中 数据表格 --> <el-table :data="tableData" style="width: 100%"> <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="书本价格"></el-table-column> <el-table-column prop="booktype" label="书本类型"></el-table-column> </el-table> <!-- 下 分页条 --> <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> </div> </template> <script> export default{ data(){ return{ bookname:'', tableData:[], rows:10, page:1, total:0 } }, methods:{ query(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=>{ }) }, onSubmit(){ let params={ bookname:this.bookname } this.query(params); }, //当页大小发生变化 handleSizeChange(r){ console.log("当前源码") let params={ bookname:this.bookname, rows:r, page:this.page } this.query(params) }, //当前页码发生变化 handleCurrentChange(p){ let params={ bookname:this.bookname, rows:this.rows, page:p } this.query(params); } }, created(){ this.query({}); } } </script>
效果图: