• 【Vue.js】使用ElementUI实现增删改查(CRUD)及表单验证


    前言:

    本文根据上篇实现数据表格(查所有)完善增删改功能,数据表格===》查看数据表格的实现链接

    一,增删改查

    ①后端Controller(增删改查方法):

    1. package com.zking.ssm.controller;
    2. import com.zking.ssm.model.Book;
    3. import com.zking.ssm.service.IBookService;
    4. import com.zking.ssm.util.JsonResponseBody;
    5. import com.zking.ssm.util.PageBean;
    6. import com.zking.ssm.vo.BookFileVo;
    7. import org.apache.commons.io.IOUtils;
    8. import org.springframework.beans.factory.annotation.Autowired;
    9. import org.springframework.stereotype.Controller;
    10. import org.springframework.web.bind.annotation.RequestMapping;
    11. import org.springframework.web.bind.annotation.ResponseBody;
    12. import org.springframework.web.multipart.MultipartFile;
    13. import javax.servlet.http.HttpServletRequest;
    14. import javax.servlet.http.HttpServletResponse;
    15. import java.io.File;
    16. import java.io.FileInputStream;
    17. import java.io.InputStream;
    18. import java.io.OutputStream;
    19. import java.net.URLEncoder;
    20. import java.util.List;
    21. import java.util.Map;
    22. @Controller
    23. @RequestMapping("/book")
    24. public class BookController {
    25. @Autowired
    26. private IBookService bookService;
    27. @RequestMapping("/addBook")
    28. @ResponseBody
    29. public JsonResponseBody addBook(Book book){
    30. try {
    31. bookService.insert(book);
    32. return new JsonResponseBody<>("新增书本成功",true,0,null);
    33. } catch (Exception e) {
    34. e.printStackTrace();
    35. return new JsonResponseBody<>("新增书本失败",false,0,null);
    36. }
    37. }
    38. @RequestMapping("/editBook")
    39. @ResponseBody
    40. public JsonResponseBody editBook(Book book){
    41. try {
    42. bookService.updateByPrimaryKey(book);
    43. return new JsonResponseBody<>("编辑书本成功",true,0,null);
    44. } catch (Exception e) {
    45. e.printStackTrace();
    46. return new JsonResponseBody<>("编辑书本失败",false,0,null);
    47. }
    48. }
    49. @RequestMapping("/delBook")
    50. @ResponseBody
    51. public JsonResponseBody delBook(Book book){
    52. try {
    53. bookService.deleteByPrimaryKey(book.getId());
    54. return new JsonResponseBody<>("删除书本成功",true,0,null);
    55. } catch (Exception e) {
    56. e.printStackTrace();
    57. return new JsonResponseBody<>("删除书本失败",false,0,null);
    58. }
    59. }
    60. @RequestMapping("/queryBookPager")
    61. @ResponseBody
    62. public JsonResponseBody> queryBookPager(Book book, HttpServletRequest req){
    63. try {
    64. PageBean pageBean=new PageBean();
    65. pageBean.setRequest(req);
    66. List books = bookService.queryBookPager(book, pageBean);
    67. return new JsonResponseBody<>("OK",true,pageBean.getTotal(),books);
    68. } catch (Exception e) {
    69. e.printStackTrace();
    70. return new JsonResponseBody<>("分页查询书本失败",false,0,null);
    71. }
    72. }
    73. @RequestMapping("/queryBookCharts")
    74. @ResponseBody
    75. public JsonResponseBody queryBookCharts(){
    76. try{
    77. Map charts = bookService.queryBookCharts();
    78. return new JsonResponseBody<>("OK",true,0,charts);
    79. }catch (Exception e){
    80. e.printStackTrace();
    81. return new JsonResponseBody<>("查询统计分析数据失败",false,0,null);
    82. }
    83. }
    84. @RequestMapping("/upload")
    85. @ResponseBody
    86. public JsonResponseBody upload(BookFileVo bookFileVo){
    87. try {
    88. MultipartFile bookFile = bookFileVo.getBookFile();
    89. System.out.println(bookFileVo);
    90. System.out.println(bookFile.getContentType());
    91. System.out.println(bookFile.getOriginalFilename());
    92. return new JsonResponseBody<>("上传成功",true,0,null);
    93. } catch (Exception e) {
    94. e.printStackTrace();
    95. return new JsonResponseBody<>("上传失败",false,0,null);
    96. }
    97. }
    98. @RequestMapping("/download")
    99. public void download(HttpServletRequest request, HttpServletResponse response){
    100. try {
    101. String relativePath = "uploads/1.jpg";
    102. String absolutePath = request.getRealPath(relativePath);
    103. InputStream is = new FileInputStream(new File(absolutePath));
    104. OutputStream out = response.getOutputStream();
    105. response.setContentType("application/octet-stream");
    106. response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("1.jpg", "UTF-8"));
    107. byte[] by = new byte[1024];
    108. int len = -1;
    109. while (-1 != (len = is.read(by))) {
    110. out.write(by);
    111. }
    112. is.close();
    113. out.close();
    114. } catch (Exception e) {
    115. e.printStackTrace();
    116. }
    117. }
    118. @RequestMapping("/downloadUrl")
    119. public void downloadUrl(HttpServletRequest request, HttpServletResponse response){
    120. String relativePath = "uploads/1.jpg";
    121. String absolutePath = request.getRealPath(relativePath);
    122. InputStream is = null;
    123. OutputStream out = null;
    124. try {
    125. is = new FileInputStream(new File(absolutePath));
    126. // 设置Content-Disposition
    127. response.setHeader("Content-Disposition",
    128. "attachment;filename=" + URLEncoder.encode("1.jpg", "UTF-8"));
    129. out = response.getOutputStream();
    130. IOUtils.copy(is, out);
    131. response.flushBuffer();
    132. System.out.println("完成");
    133. } catch (Exception e) {
    134. e.printStackTrace();
    135. } finally {
    136. IOUtils.closeQuietly(is);
    137. IOUtils.closeQuietly(out);
    138. }
    139. }
    140. }

    ②配置action.js

    1. 'Book_LIST': '/book/queryBookPager', //书籍列表
    2. 'Book_ADD': '/book/addBook', //增加
    3. 'Book_UPD': '/book/editBook', //修改
    4. 'Book_DEL': '/book/delBook', // 删除

    ③定义弹窗

    1. <el-dialog title="title" :visible.sync="dialogFormVisible" @close="clear()">
    2. <el-form :model="book" :rules="rules" ref="book">
    3. <el-form-item label="书籍编号" :label-width="formLabelWidth">
    4. <el-input v-model="book.id" autocomplete="off">el-input>
    5. el-form-item>
    6. <el-form-item label="书籍名称" :label-width="formLabelWidth" prop="bookname">
    7. <el-input v-model="book.bookname" autocomplete="off">el-input>
    8. el-form-item>
    9. <el-form-item label="书籍价格" :label-width="formLabelWidth" prop="price">
    10. <el-input v-model="book.price" autocomplete="off">el-input>
    11. el-form-item>
    12. <el-form-item label="书籍类别" :label-width="formLabelWidth" prop="booktype">
    13. <el-select v-model="book.booktype" placeholder="请选择活动区域">
    14. <el-option v-for="t in types" :label="t.name" :value="t.name" :key="'key'+t.id">el-option>
    15. el-select>
    16. el-form-item>
    17. el-form>
    18. <div slot="footer" class="dialog-footer">
    19. <el-button @click="dialogFormVisible = false">取 消el-button>
    20. <el-button type="primary" @click="dosub">确 定el-button>
    21. div>
    22. el-dialog>

    ④ 定义变量

    1. data() {
    2. return {
    3. bookname: '',
    4. tableData: [],
    5. rows: 10,
    6. page: 1,
    7. total: 0,
    8. title: '新增窗体',
    9. dialogFormVisible: false,
    10. formLabelWidth: '100px',
    11. types: [],
    12. book: {
    13. id: '',
    14. bookname: '',
    15. price: '',
    16. booktype: ''
    17. },
    18. }
    19. }

    ⑤ 定义方法

    1. methods: {
    2. del(idx, row) {
    3. this.$confirm('此操作将永久删除id为' + row.id + '的数据,是否继续?', '提示', {
    4. confirmButtonText: '确定',
    5. cancelButtonText: '取消',
    6. type: 'warning'
    7. }).then(() => {
    8. let url = this.axios.urls.Book_DEL;
    9. this.axios.post(url, {
    10. id: row.id
    11. }).then(r => {
    12. this.clear();
    13. this.query({})
    14. this.$message({
    15. type: 'success',
    16. message: '删除成功!'
    17. });
    18. this.query({});
    19. }).catch(e => {
    20. })
    21. }).catch(() => {
    22. this.$message({
    23. type: 'info',
    24. message: '已取消删除'
    25. });
    26. });
    27. },
    28. dosub() {
    29. this.$refs['book'].validate((valid) => {
    30. if (valid) {
    31. let url = this.axios.urls.Book_ADD;
    32. if (this.title == '编辑窗体') {
    33. url = this.axios.urls.Book_UPD;
    34. }
    35. let params = {
    36. id: this.book.id,
    37. bookname: this.book.bookname,
    38. price: this.book.price,
    39. booktype: this.book.booktype
    40. };
    41. console.log(params);
    42. this.axios.post(url, params).then(r => {
    43. this.clear();
    44. this.query({})
    45. }).catch(e => {
    46. })
    47. } else {
    48. console.log('error submit!!');
    49. return false;
    50. }
    51. });
    52. },
    53. //初始化对话框,重置对话框
    54. clear() {
    55. this.dialogFormVisible = false;
    56. this.title = '新增窗体';
    57. this.book = {
    58. id: '',
    59. bookname: '',
    60. price: '',
    61. booktype: ''
    62. }
    63. },
    64. open(idx, row) {
    65. //打开对话框
    66. this.dialogFormVisible = true;
    67. if (row) {
    68. this.title = '编辑窗体';
    69. this.book.id = row.id;
    70. this.book.bookname = row.bookname;
    71. this.book.price = row.price;
    72. this.book.booktype = row.booktype;
    73. }
    74. },
    75. query(params) {
    76. let url = this.axios.urls.Book_LIST;
    77. this.axios.get(url, {
    78. params: params
    79. }).then(r => {
    80. console.log(r);
    81. this.tableData = r.data.rows;
    82. this.total = r.data.total;
    83. }).catch(e => {})
    84. },
    85. onSubmit() {
    86. let params = {
    87. bookname: this.bookname
    88. }
    89. this.query(params);
    90. },
    91. //当页大小发生变化
    92. handleSizeChange(r) {
    93. let params = {
    94. bookname: this.bookname,
    95. rows: r,
    96. page: this.page
    97. }
    98. this.query(params)
    99. },
    100. //当前页码发生变化
    101. handleCurrentChange(p) {
    102. let params = {
    103. bookname: this.bookname,
    104. rows: this.rows,
    105. page: p
    106. }
    107. this.query(params);
    108. }
    109. },
    110. created() {
    111. this.query({});
    112. this.types = [{
    113. id: 1,
    114. name: '恐怖'
    115. }, {
    116. id: 2,
    117. name: '惊悚'
    118. }, {
    119. id: 3,
    120. name: '动画片'
    121. }, {
    122. id: 4,
    123. name: '爱情'
    124. }];
    125. }

    ⑥ 完整代码

    1. <script>
    2. export default {
    3. data() {
    4. return {
    5. bookname: '',
    6. tableData: [],
    7. rows: 10,
    8. page: 1,
    9. total: 0,
    10. title: '新增窗体',
    11. dialogFormVisible: false,
    12. formLabelWidth: '100px',
    13. types: [],
    14. book: {
    15. id: '',
    16. bookname: '',
    17. price: '',
    18. booktype: ''
    19. },
    20. }
    21. },
    22. methods: {
    23. del(idx, row) {
    24. this.$confirm('此操作将永久删除id为' + row.id + '的数据,是否继续?', '提示', {
    25. confirmButtonText: '确定',
    26. cancelButtonText: '取消',
    27. type: 'warning'
    28. }).then(() => {
    29. let url = this.axios.urls.Book_DEL;
    30. this.axios.post(url, {
    31. id: row.id
    32. }).then(r => {
    33. this.clear();
    34. this.query({})
    35. this.$message({
    36. type: 'success',
    37. message: '删除成功!'
    38. });
    39. this.query({});
    40. }).catch(e => {
    41. })
    42. }).catch(() => {
    43. this.$message({
    44. type: 'info',
    45. message: '已取消删除'
    46. });
    47. });
    48. },
    49. dosub() {
    50. this.$refs['book'].validate((valid) => {
    51. if (valid) {
    52. let url = this.axios.urls.Book_ADD;
    53. if (this.title == '编辑窗体') {
    54. url = this.axios.urls.Book_UPD;
    55. }
    56. let params = {
    57. id: this.book.id,
    58. bookname: this.book.bookname,
    59. price: this.book.price,
    60. booktype: this.book.booktype
    61. };
    62. console.log(params);
    63. this.axios.post(url, params).then(r => {
    64. this.clear();
    65. this.query({})
    66. }).catch(e => {
    67. })
    68. } else {
    69. console.log('error submit!!');
    70. return false;
    71. }
    72. });
    73. },
    74. //初始化对话框,重置对话框
    75. clear() {
    76. this.dialogFormVisible = false;
    77. this.title = '新增窗体';
    78. this.book = {
    79. id: '',
    80. bookname: '',
    81. price: '',
    82. booktype: ''
    83. }
    84. },
    85. open(idx, row) {
    86. //打开对话框
    87. this.dialogFormVisible = true;
    88. if (row) {
    89. this.title = '编辑窗体';
    90. this.book.id = row.id;
    91. this.book.bookname = row.bookname;
    92. this.book.price = row.price;
    93. this.book.booktype = row.booktype;
    94. }
    95. },
    96. query(params) {
    97. let url = this.axios.urls.Book_LIST;
    98. this.axios.get(url, {
    99. params: params
    100. }).then(r => {
    101. console.log(r);
    102. this.tableData = r.data.rows;
    103. this.total = r.data.total;
    104. }).catch(e => {})
    105. },
    106. onSubmit() {
    107. let params = {
    108. bookname: this.bookname
    109. }
    110. this.query(params);
    111. },
    112. //当页大小发生变化
    113. handleSizeChange(r) {
    114. let params = {
    115. bookname: this.bookname,
    116. rows: r,
    117. page: this.page
    118. }
    119. this.query(params)
    120. },
    121. //当前页码发生变化
    122. handleCurrentChange(p) {
    123. let params = {
    124. bookname: this.bookname,
    125. rows: this.rows,
    126. page: p
    127. }
    128. this.query(params);
    129. }
    130. },
    131. created() {
    132. this.query({});
    133. this.types = [{
    134. id: 1,
    135. name: '恐怖'
    136. }, {
    137. id: 2,
    138. name: '惊悚'
    139. }, {
    140. id: 3,
    141. name: '动画片'
    142. }, {
    143. id: 4,
    144. name: '爱情'
    145. }];
    146. }
    147. }
    148. script>
    149. <style>
    150. style>

    ⑦ 效果演示

    二、表单验证 

    2.1 添加规则

    需要在里面的form表单里面添加:model="book" :rules="rules" ref="book":model和ref必须是一样的

          "book" :rules="rules" ref="book">

    里面添加prop属性

    注意:该prop属性值要与实体表字段名一致

    2.2 定义规则

    1. rules: {
    2. //定义验证格式
    3. bookname: [
    4. {required: true, message: '请输入书籍名称', trigger: 'blur'},
    5. {min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur'}
    6. ],
    7. price: [
    8. {required: true, message: '请输入书籍价格', trigger: 'change'},
    9. {min: 1, max: 5, message: '长度在 1 到 5 个字符', trigger: 'blur'}
    10. ],
    11. booktype: [
    12. {required: true, message: '请输入书籍类型', trigger: 'blur'}
    13. ]
    14. },

    2.3 提交事件

    在提交的事件里面添加。

    1. this.$refs[formName].validate((valid) => {
    2. if (valid) {
    3. alert('submit!');
    4. } else {
    5. console.log('error submit!!');
    6. return false;
    7. }
    8. });

    ormName:form里面:model="book" 或者ref="book"  的名字

    比例我的提交事件为确定按钮,那我是在确定按钮的事件中添加。比如:

    1. dosub() {
    2. this.$refs['book'].validate((valid) => {
    3. if (valid) {
    4. let url = this.axios.urls.Book_ADD;
    5. if (this.title == '编辑窗体') {
    6. url = this.axios.urls.Book_UPD;
    7. }
    8. let params = {
    9. id: this.book.id,
    10. bookname: this.book.bookname,
    11. price: this.book.price,
    12. booktype: this.book.booktype
    13. };
    14. console.log(params);
    15. this.axios.post(url, params).then(r => {
    16. this.clear();
    17. this.query({})
    18. }).catch(e => {
    19. })
    20. } else {
    21. console.log('error submit!!');
    22. return false;
    23. }
    24. });
    25. },

    当你的规则必配了就执行你的增加修改的方法,或者其他的方法

    2.4 前端完整代码​​​​​​​

    1. <script>
    2. export default {
    3. data() {
    4. return {
    5. bookname: '',
    6. tableData: [],
    7. rows: 10,
    8. page: 1,
    9. total: 0,
    10. title: '新增窗体',
    11. dialogFormVisible: false,
    12. formLabelWidth: '100px',
    13. types: [],
    14. book: {
    15. id: '',
    16. bookname: '',
    17. price: '',
    18. booktype: ''
    19. },
    20. rules: {
    21. bookname: [{
    22. required: true,
    23. message: '请输入书籍名称',
    24. trigger: 'blur'
    25. },
    26. {
    27. min: 2,
    28. max: 7,
    29. message: '长度在 2 到 7 个字符',
    30. trigger: 'blur'
    31. }
    32. ],
    33. price: [{
    34. required: true,
    35. message: '请输入书籍价格',
    36. trigger: 'blur'
    37. }],
    38. booktype: [{
    39. required: true,
    40. message: '请输入书籍类别',
    41. trigger: 'blur'
    42. }]
    43. }
    44. }
    45. },
    46. methods: {
    47. del(idx, row) {
    48. this.$confirm('此操作将永久删除id为' + row.id + '的数据,是否继续?', '提示', {
    49. confirmButtonText: '确定',
    50. cancelButtonText: '取消',
    51. type: 'warning'
    52. }).then(() => {
    53. let url = this.axios.urls.Book_DEL;
    54. this.axios.post(url, {
    55. id: row.id
    56. }).then(r => {
    57. this.clear();
    58. this.query({})
    59. this.$message({
    60. type: 'success',
    61. message: '删除成功!'
    62. });
    63. this.query({});
    64. }).catch(e => {
    65. })
    66. }).catch(() => {
    67. this.$message({
    68. type: 'info',
    69. message: '已取消删除'
    70. });
    71. });
    72. },
    73. dosub() {
    74. this.$refs['book'].validate((valid) => {
    75. if (valid) {
    76. let url = this.axios.urls.Book_ADD;
    77. if (this.title == '编辑窗体') {
    78. url = this.axios.urls.Book_UPD;
    79. }
    80. let params = {
    81. id: this.book.id,
    82. bookname: this.book.bookname,
    83. price: this.book.price,
    84. booktype: this.book.booktype
    85. };
    86. console.log(params);
    87. this.axios.post(url, params).then(r => {
    88. this.clear();
    89. this.query({})
    90. }).catch(e => {
    91. })
    92. } else {
    93. console.log('error submit!!');
    94. return false;
    95. }
    96. });
    97. },
    98. //初始化对话框,重置对话框
    99. clear() {
    100. this.dialogFormVisible = false;
    101. this.title = '新增窗体';
    102. this.book = {
    103. id: '',
    104. bookname: '',
    105. price: '',
    106. booktype: ''
    107. }
    108. },
    109. open(idx, row) {
    110. //打开对话框
    111. this.dialogFormVisible = true;
    112. if (row) {
    113. this.title = '编辑窗体';
    114. this.book.id = row.id;
    115. this.book.bookname = row.bookname;
    116. this.book.price = row.price;
    117. this.book.booktype = row.booktype;
    118. }
    119. },
    120. query(params) {
    121. let url = this.axios.urls.Book_LIST;
    122. this.axios.get(url, {
    123. params: params
    124. }).then(r => {
    125. console.log(r);
    126. this.tableData = r.data.rows;
    127. this.total = r.data.total;
    128. }).catch(e => {})
    129. },
    130. onSubmit() {
    131. let params = {
    132. bookname: this.bookname
    133. }
    134. this.query(params);
    135. },
    136. //当页大小发生变化
    137. handleSizeChange(r) {
    138. let params = {
    139. bookname: this.bookname,
    140. rows: r,
    141. page: this.page
    142. }
    143. this.query(params)
    144. },
    145. //当前页码发生变化
    146. handleCurrentChange(p) {
    147. let params = {
    148. bookname: this.bookname,
    149. rows: this.rows,
    150. page: p
    151. }
    152. this.query(params);
    153. }
    154. },
    155. created() {
    156. this.query({});
    157. this.types = [{
    158. id: 1,
    159. name: '恐怖'
    160. }, {
    161. id: 2,
    162. name: '惊悚'
    163. }, {
    164. id: 3,
    165. name: '动画片'
    166. }, {
    167. id: 4,
    168. name: '爱情'
    169. }];
    170. }
    171. }
    172. script>
    173. <style>
    174. style>

    2.5 效果

  • 相关阅读:
    在选购腾讯云服务器时需要注意哪些参数?
    【学习笔记】子集和问题
    LGBM 模型结果 图形展示
    RK3588平台开发系列讲解(项目篇)视频监控之RTMP推流
    贪心算法(算法竞赛、蓝桥杯)--修理牛棚
    遍历堆 PAT甲级 1155 堆路径
    【无标题】
    渲染路径RenderingPath
    技巧分享:wps文件怎么转换成word格式?
    计算机网络第3章(数据链路层)-----总结1
  • 原文地址:https://blog.csdn.net/m0_73192864/article/details/133343700