ElementUI--数据表格增删改查与表单验证

简介: ElementUI--数据表格增删改查与表单验证

一、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 新增示例

b68e7a8db7964784af418be41c5c5b94.gif


1.4.2 修改示例

650ed6426f7d4bada9d87e897ecfb19d.gif


1.4.3 删除示例

1d65f352aa6b4eeea9fe9d6b4311d1ff.gif


二、表单验证


2.1 设置表单验证属性

  Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。校验规则参见 async-validator

413b69896927406cb851d98fd5c0b8c8.png

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;
          }
        });
      },


2.4 效果演示

e776cf477fd04645824d753bc2a5ca04.gif

目录
相关文章
|
2月前
|
存储 JSON 关系型数据库
【干货满满】解密 API 数据解析:从 JSON 到数据库存储的完整流程
本文详解电商API开发中JSON数据解析与数据库存储的全流程,涵盖数据提取、清洗、转换及优化策略,结合Python实战代码与主流数据库方案,助开发者构建高效、可靠的数据处理管道。
|
29天前
|
存储 数据管理 数据库
数据字典是什么?和数据库、数据仓库有什么关系?
在数据处理中,你是否常困惑于字段含义、指标计算或数据来源?数据字典正是解答这些问题的关键工具,它清晰定义数据的名称、类型、来源、计算方式等,服务于开发者、分析师和数据管理者。本文详解数据字典的定义、组成及其与数据库、数据仓库的关系,助你夯实数据基础。
数据字典是什么?和数据库、数据仓库有什么关系?
|
1月前
|
存储 关系型数据库 数据库
【赵渝强老师】PostgreSQL数据库的WAL日志与数据写入的过程
PostgreSQL中的WAL(预写日志)是保证数据完整性的关键技术。在数据修改前,系统会先将日志写入WAL,确保宕机时可通过日志恢复数据。它减少了磁盘I/O,提升了性能,并支持手动切换日志文件。WAL文件默认存储在pg_wal目录下,采用16进制命名规则。此外,PostgreSQL提供pg_waldump工具解析日志内容。
133 0
|
4月前
|
SQL 数据库 开发者
Python中使用Flask-SQLAlchemy对数据库的增删改查简明示例
这样我们就对Flask-SQLAlchemy进行了一次简明扼要的旅程,阐述了如何定义模型,如何创建表,以及如何进行基本的数据库操作。希望你在阅读后能对Flask-SQLAlchemy有更深入的理解,这将为你在Python世界中从事数据库相关工作提供极大的便利。
486 77
|
3月前
|
存储 SQL Java
数据存储使用文件还是数据库,哪个更合适?
数据库和文件系统各有优劣:数据库读写性能较低、结构 rigid,但具备计算能力和数据一致性保障;文件系统灵活易管理、读写高效,但缺乏计算能力且无法保证一致性。针对仅需高效存储与灵活管理的场景,文件系统更优,但其计算短板可通过开源工具 SPL(Structured Process Language)弥补。SPL 提供独立计算语法及高性能文件格式(如集文件、组表),支持复杂计算与多源混合查询,甚至可替代数据仓库。此外,SPL 易集成、支持热切换,大幅提升开发运维效率,是后数据库时代文件存储的理想补充方案。
|
4月前
|
XML 数据库 Android开发
Android数据库的使用(增删改查)
本文介绍了一个简单的数据库操作Demo,包含创建数据库、增删改查功能。通过5个按钮分别实现创建数据库、插入数据、删除数据、更新数据和查询数据的操作。代码结构清晰,适合初学者学习Android SQLite数据库基础操作。
122 5
|
4月前
|
数据库 Android开发 开发者
Android常用的room增删改查语句(外部数据库)
本文分享了将一个原生数据库驱动的单词APP重构为使用Room库的过程及遇到的问题,重点解决了Room中增删改查的常用语句实现。文章通过具体示例(以“forget”表为例),详细展示了如何定义实体类、Dao接口、Database类以及Repository和ViewModel的设计与实现。同时,提供了插入、删除、更新和查询数据的代码示例,包括模糊查询、分页加载等功能。此外,针对外部数据库导入问题,作者建议可通过公众号“计蒙不吃鱼”获取更多支持。此内容适合有一定Room基础的开发者深入学习。
158 0
Android常用的room增删改查语句(外部数据库)
|
5月前
|
人工智能 关系型数据库 分布式数据库
让数据与AI贴得更近,阿里云瑶池数据库系列产品焕新升级
4月9日阿里云AI势能大会上,阿里云瑶池数据库发布重磅新品及一系列产品能力升级。「推理加速服务」Tair KVCache全新上线,实现KVCache动态分层存储,显著提高内存资源利用率,为大模型推理降本提速。
|
3月前
|
人工智能 运维 关系型数据库
数据库运维:mysql 数据库迁移方法-mysqldump
本文介绍了MySQL数据库迁移的方法与技巧,重点探讨了数据量大小对迁移方式的影响。对于10GB以下的小型数据库,推荐使用mysqldump进行逻辑导出和source导入;10GB以上可考虑mydumper与myloader工具;100GB以上则建议物理迁移。文中还提供了统计数据库及表空间大小的SQL语句,并讲解了如何使用mysqldump导出存储过程、函数和数据结构。通过结合实际应用场景选择合适的工具与方法,可实现高效的数据迁移。
665 1
|
4月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!

热门文章

最新文章