一、CRUD实现
1.1 后台CRUD编写
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.2 配置访问路径
src/api/action.js :
//获取书本信息 'BOOKMSG_BOOKINFO_REQ': '/book/queryBookPager', //新增书本 'BOOK_ADD': '/book/addBook', //修改书本 'BOOK_EDIT': '/book/editBook', //删除书本 'BOOK_DEL': '/book/delBook',
1.3 前端编写(及窗口)
<template> <div class="Book" style="padding: 30px;"> <!-- 输入框搜索 --> <el-form :inline="true" class="demo-form-inline"> <el-form-item label="书籍名称 : "> <el-input v-model="bookname" placeholder="书籍名称"></el-input> </el-form-item> <el-form-item> <el-button type="warning" @click="onSubmit()">查询</el-button> <el-button type="warning" icon="el-icon-plus" @click="addBook()">新增</el-button> </el-form-item> </el-form> <!-- 书籍的书籍表格 --> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="id" label="书籍ID"></el-table-column> <el-table-column prop="bookname" label="书籍名称"></el-table-column> <el-table-column prop="price" label="书籍价格"></el-table-column> <el-table-column prop="booktype" label="书籍类型"></el-table-column> <!-- “编辑”“删除”功能连接 --> <el-table-column label="操作"> <!-- 在<template>上使用特殊的slot-scope 特性,可以接收传递给插槽的prop slot-scope:类似将每一行的row对象封装到槽中,之后直接从scope中获取 row对象信息和行索引index信息即可 --> <template slot-scope="scope"> <el-button size="mini" @click="handleEdit(scope.row)">编辑</el-button> <el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button> </template> </el-table-column> </el-table> <!-- 分页 --> <div class="block" style="padding: 20px;"> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page" background :page-sizes="[10, 20, 30, 40]" :page-size="rows" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> </div> <!-- 弹出窗口:增加和修改书本信息共用一个弹出窗口,需要根据用户的选择动态的设置弹出窗口的标题 :tile 通过绑定值的方式设置dialog的标题 :visible.sync 控制弹出窗口的显示或隐藏,.sync同步修饰符 @close="closeBookForm",设置窗口关闭时调用的处理函数,可用于清空表单 :model="bookForm":用于定义表单对应的model,具体model的定义可见data部分。 v-show="optiontype == 'update'" 通过操作类型控制是否显示书本编号字段,如果当前操作类型为 新增,则不用显示,书本编号在数据表中是自增的。 :label-width="formLabelWidth" 统一定义标签的宽度。 :style="{width: formEleWidth}" 统一定义form元素的宽度。 --> <el-dialog :title="dialogName" :visible.sync="dialogFormVisible" @close="closeBookForm" width="500px"> <el-form :model="bookForm"> <el-form-item v-show="optiontype == 'update'" label="编号" :label-width="formLabelWidth"> <el-input v-model="bookForm.id" autocomplete="off" :style="{width: formEleWidth}"></el-input> </el-form-item> <el-form-item label="书名" :label-width="formLabelWidth"> <el-input v-model="bookForm.bookname" autocomplete="off" :style="{width: formEleWidth}"></el-input> </el-form-item> <el-form-item label="价格" :label-width="formLabelWidth"> <el-input v-model="bookForm.price" autocomplete="off" :style="{width: formEleWidth}"></el-input> </el-form-item> <el-form-item label="类型" :label-width="formLabelWidth"> <el-select v-model="bookForm.booktype" placeholder="选择类型" :style="{width:formEleWidth}"> <el-option label="名著" value="mz"></el-option> <el-option label="小说" value="xs"></el-option> </el-select> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormVisible = false">取 消</el-button> <el-button type="primary" @click="saveBook()">确 定</el-button> </div> </el-dialog> </div> </template>
注1:隐藏显示设置,通过Vue实例对象中的dialogFormVisible="true|false"来控制dialog显示隐藏
:visible.sync="dialogFormVisible"
注2:通过close或closed事件,在关闭dialog弹出框时清空form表单数据和验证信息;
@close="dialogClose"
1.4 增删改查实现
<script> export default { name: 'BookList', data() { return { bookname: '', tableData: [], rows: 10, total: 0, page: 1, //控制对话框是否显示,默认是隐藏状态 dialogFormVisible: false, //统一控制标签的宽度 formLabelWidth: '40px', //统一控制表单元素的宽度 formEleWidth: '400px', //对话框标题,默认为新增,如果是点击修改按钮打开对话框,则标题应为修改。 dialogName: '新增书本', //操作类型,默认为添加,如果是点击修改打开对话框,则操作类类型应变为修改 //该变量用于控制是否显示书本编号字段,当操作类型为新增时不需显示(书本编号数据表字段为自增) //当操作类型为修改时,需要显示。 optiontype: 'add', //定义验证规则 rules:{ bookname: [{ required: true, message: '请输入书籍名称', trigger: 'blur' }, { min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: 'blur' } ], price: [{ required: true, message: '请输入价格', trigger: 'blur' }], booktype: [{ required: true, message: '请输入书籍类别', trigger: 'blur' }] }, //定义表单对应的model bookForm: { id: '', bookname: '', price: null, booktype: '' } } }, methods: { /* 新增书本 */ saveBook() { this.$refs['bookForm'].validate((valid) => { if (valid) { //默认新增 var url = this.axios.urls.BOOK_ADD; if (this.optiontype == 'update') { url = this.axios.urls.BOOK_EDIT; } console.log(url) this.axios.post(url, this.bookForm).then(d => { //关闭窗口 this.closeBookForm(); this.dialogFormVisible = false; this.query({}); }).catch(); } else { console.log('error submit!!'); return false; } }); }, //选择分页 handleSizeChange(r) { //当页大小发生变化 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); }, //查询方法 query(params) { //获取后台请求书籍数据的地址 let url = this.axios.urls.BOOKMSG_BOOKINFO_REQ; this.axios.get(url, { params: params }).then(d => { this.tableData = d.data.rows; this.total = d.data.total; }).catch(e => {}); }, onSubmit() { let params = { bookname: this.bookname } console.log(params) this.query(params); this.bookname = '' }, //当关闭对话框时,该方法用于清空表单 closeBookForm() { this.bookForm.id = null; this.bookForm.bookname = null; this.bookForm.booktype = null; this.bookForm.price = null; }, //打开对话框,将对话框标题设置为新增,操作类型设置为'add' addBook() { this.dialogName = '新增书本信息'; this.dialogFormVisible = true; this.optiontype = 'add'; }, //打开对话框,将对话框标题设置为修改,操作类型设置为'update', //并使用获取的待修改的记录的值设置对应的表单元素 handleEdit(row) { this.dialogName = '编辑书本信息'; this.dialogFormVisible = true; this.bookForm.id = row.id; this.bookForm.bookname = row.bookname; this.bookForm.booktype = row.booktype; this.bookForm.price = row.price; this.optiontype = 'update'; }, //删除书本记录 handleDelete(row) { this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { //获取删除书本访问路径 var url = this.axios.urls.BOOK_DEL; this.axios.post(url, { id: row.id }).then(r => { this.$message({ type: 'success', message: '删除成功!' }); this.query({}); }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); } }, created() { this.query({}) } } </script>
1.4.1 新增示例
1.4.2 修改示例
1.4.3 删除示例
二、表单验证
2.1 设置表单验证属性
Form 组件提供了表单验证的功能,只需要通过 rules
属性传入约定的验证规则,并将 Form-Item 的 prop
属性设置为需校验的字段名即可。校验规则参见 async-validator
2.2 自定义验证规则
//定义验证规则 rules:{ bookname: [{ required: true, message: '请输入书籍名称', trigger: 'blur' }, { min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: 'blur' } ], price: [{ required: true, message: '请输入价格', trigger: 'blur' }], booktype: [{ required: true, message: '请输入书籍类别', trigger: 'blur' }] },
2.3 使用规则
/* 新增书本 */ saveBook() { this.$refs['bookForm'].validate((valid) => { if (valid) { //默认新增 var url = this.axios.urls.BOOK_ADD; if (this.optiontype == 'update') { url = this.axios.urls.BOOK_EDIT; } console.log(url) this.axios.post(url, this.bookForm).then(d => { //关闭窗口 this.closeBookForm(); this.dialogFormVisible = false; this.query({}); }).catch(); } else { console.log('error submit!!'); return false; } }); },