VUE&Element,能够进行简单的 Element 页面修改, 能够完成查询所有功能, 能够完成添加功能(下)

简介: VUE&Element,能够进行简单的 Element 页面修改, 能够完成查询所有功能, 能够完成添加功能

3,综合案例


3.1 功能介绍

以上是我们在综合案例要实现的功能。对数据的除了对数据的增删改查功能外,还有一些复杂的功能,如 批量删除、分页查询、条件查询 等功能


批量删除 功能:每条数据前都有复选框,当我选中多条数据并点击 批量删除 按钮后,会发送请求到后端并删除数据库中指定的多条数据。

分页查询 功能:当数据库中有很多数据时,我们不可能将所有的数据展示在一页里,这个时候就需要分页展示数据。

条件查询 功能:数据库量大的时候,我们就需要精确的查询一些想看到的数据,这个时候就需要通过条件查询。

这里的 修改品牌 和 删除品牌 功能在课程上不做讲解,留作同学来下的练习。


3.2 环境准备

环境准备我们主要完成以下两件事即可


将资料的 brand-case 模块导入到 idea中

执行资料中提供的 tb_brand.sql脚本

3.2.1 工程准备

将 04-资料\01-初始工程 中的 brand-case 工程导入到我们自己的 idea 中。工程结构如下:


3.2.2 创建表

下面是创建表的语句



--删除tb_brand表droptableifexiststb_brand;
--创建tb_brand表createtabletb_brand (
--id主键idintprimarykeyauto_increment,
--品牌名称brand_namevarchar(20),
--企业名称company_namevarchar(20),
--排序字段orderedint,
--描述信息descriptionvarchar(100),
--状态:0:禁用1:启用statusint);
--添加数据insertintotb_brand (brand_name, company_name, ordered, description, status)
values       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '万物互联', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1),
       ('格力', '格力电器股份有限公司', 30, '让世界爱上中国造', 1),
       ('阿里巴巴', '阿里巴巴集团控股有限公司', 10, '买买买', 1),
       ('腾讯', '腾讯计算机系统有限公司', 50, '玩玩玩', 0),
       ('百度', '百度在线网络技术公司', 5, '搜搜搜', 0),
       ('京东', '北京京东世纪贸易有限公司', 40, '就是快', 1);



3.3 查询所有功能

如上图所示是查询所有品牌数据在页面展示的效果。要实现这个功能,要先搞明白如下问题:


什么时候发送异步请求?


页面加载完毕后就需要在页面上看到所有的品牌数据。所以在 mounted() 这个构造函数中写发送异步请求的代码。


请求需要携带参数吗?


查询所有功能不需要携带什么参数。


响应的数据格式是什么样?


后端是需要将 List<Brand> 对象转换为 JSON 格式的数据并响应回给浏览器。响应数据格式如下:


我们先实现后端程序,然后再实现前端程序。


3.3.1 后端实现

3.3.1.1 dao方法实现

在 com.itheima.mapper.BrandMapper 接口中定义抽象方法,并使用 @Select 注解编写 sql 语句


/*** 查询所有* @return*/@Select("select * from tb_brand")
List<Brand>selectAll();


由于表中有些字段名和实体类中的属性名没有对应,所以需要在 com/itheima/mapper/BrandMapper.xml 映射配置文件中定义结果映射 ,使用resultMap 标签。映射配置文件内容如下:


<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="com.itheima.mapper.BrandMapper"><resultMapid="brandResultMap"type="brand"><resultproperty="brandName"column="brand_name"/><resultproperty="companyName"column="company_name"/></resultMap></mapper>


定义完结果映射关系后,在接口 selectAll() 方法上引用该结构映射。使用 @ResultMap("brandResultMap") 注解


完整接口的 selectAll() 方法如下:


/*** 查询所有* @return*/@Select("select * from tb_brand")
@ResultMap("brandResultMap")
List<Brand>selectAll();


3.3.1.2 service方法实现

在 com.itheima.service 包下创建 BrandService 接口,在该接口中定义查询所有的抽象方法


publicinterfaceBrandService {
/*** 查询所有* @return*/List<Brand>selectAll();
}


并在 com.itheima.service 下再创建 impl 包;impl 表示是放 service 层接口的实现类的包。 在该包下创建名为 BrandServiceImpl 类


publicclassBrandServiceImplimplementsBrandService {
@OverridepublicList<Brand>selectAll() {
    }
}


此处为什么要给 service 定义接口呢?因为service定义了接口后,在 servlet 中就可以使用多态的形式创建Service实现类的对象


这里使用多态是因为方便我们后期解除 Servlet 和 service 的耦合。从上面的代码我们可以看到 SelectAllServlet 类和 BrandServiceImpl 类之间是耦合在一起的,如果后期 BrandService 有其它更好的实现类(例如叫 BrandServiceImpl),那就需要修改 SelectAllServlet 类中的代码。后面我们学习了 Spring 框架后就可以解除 SelectAllServlet 类和红色框括起来的代码耦合。而现在咱们还做不到解除耦合,在这里只需要理解为什么定义接口即可。


BrandServiceImpl 类代码如下:


publicclassBrandServiceImplimplementsBrandService {
//1. 创建SqlSessionFactory 工厂对象SqlSessionFactoryfactory=SqlSessionFactoryUtils.getSqlSessionFactory();
@OverridepublicList<Brand>selectAll() {
//2. 获取SqlSession对象SqlSessionsqlSession=factory.openSession();
//3. 获取BrandMapperBrandMappermapper=sqlSession.getMapper(BrandMapper.class);
//4. 调用方法List<Brand>brands=mapper.selectAll();
//5. 释放资源sqlSession.close();
returnbrands;
    }
}



3.3.1.3 servlet实现

在 com.itheima.web.servlet 包下定义名为 SelectAllServlet 的查询所有的 servlet。该 servlet 逻辑如下:


调用service的 selectAll() 方法查询所有的品牌数据,并接口返回结果

将返回的结果转换为 json 数据

响应 json 数据

代码如下:


@WebServlet("/selectAllServlet")
publicclassSelectAllServletextendsHttpServlet {
privateBrandServicebrandService=newBrandServiceImpl();
@OverrideprotectedvoiddoGet(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
//1. 调用service查询List<Brand>brands=brandService.selectAll();
//2. 转为JSONStringjsonString=JSON.toJSONString(brands);
//3. 写数据response.setContentType("text/json;charset=utf-8"); //告知浏览器响应的数据是什么, 告知浏览器使用什么字符集进行解码response.getWriter().write(jsonString);
    }
@OverrideprotectedvoiddoPost(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
this.doGet(request, response);
    }
}



3.3.1.4 测试后端程序

在浏览器输入访问 servlet 的资源路径 http://localhost:8080/brand-case/selectAllServlet ,如果没有报错,并能看到如下信息表明后端程序没有问题


3.3.2 前端实现

前端需要在页面加载完毕后发送 ajax 请求,所以发送请求的逻辑应该放在 mounted() 钩子函数中。而响应回来的数据需要赋值给表格绑定的数据模型,从下图可以看出表格绑定的数据模型是 tableData


前端代码如下:



mounted(){
//当页面加载完成后,发送异步请求,获取数据var_this=this;
axios({
method:"get",
url:"http://localhost:8080/brand-case/selectAllServlet"     }).then(function (resp) {
_this.tableData=resp.data;
     })
 }


3.4 添加功能

上图是添加数据的对话框,当点击 提交 按钮后就需要将数据提交到后端,并将数据保存到数据库中。


页面发送请求时,需要将输入框输入的内容提交给后端程序,而这里是以 json 格式进行传递的。


注意:由于是添加数据,所以上述json数据中id是没有值的。


3.4.1 后端实现

3.4.1.1 dao方法实现

在 BrandMapper 接口中定义 add() 添加方法,并使用 @Insert 注解编写sql语句


/*** 添加数据* @param brand*/@Insert("insert into tb_brand values(null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
voidadd(Brandbrand);


3.4.1.2 service方法实现

在 BrandService 接口中定义 add() 添加数据的业务逻辑方法


/*** 添加数据* @param brand*/voidadd(Brandbrand);


在 BrandServiceImpl 类中重写 add() 方法,并进行业务逻辑实现


@Overridepublicvoidadd(Brandbrand) {
//2. 获取SqlSession对象SqlSessionsqlSession=factory.openSession();
//3. 获取BrandMapperBrandMappermapper=sqlSession.getMapper(BrandMapper.class);
//4. 调用方法mapper.add(brand);
sqlSession.commit();//提交事务//5. 释放资源sqlSession.close();
}


注意:增删改操作一定要提交事务。


3.4.1.3 servlet实现

在 com.itheima.web.servlet 包写定义名为 AddServlet 的 Servlet。该 Servlet 的逻辑如下:


接收页面提交的数据。页面到时候提交的数据是 json 格式的数据,所以此处需要使用输入流读取数据

将接收到的数据转换为 Brand 对象

调用 service 的 add() 方法进行添加的业务逻辑处理

给浏览器响应添加成功的标识,这里直接给浏览器响应 success 字符串表示成功

servlet 代码实现如下:


@WebServlet("/addServlet")
publicclassAddServletextendsHttpServlet {
privateBrandServicebrandService=newBrandServiceImpl();
@OverrideprotectedvoiddoGet(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
//1. 接收品牌数据BufferedReaderbr=request.getReader();
Stringparams=br.readLine();//json字符串//转为Brand对象Brandbrand=JSON.parseObject(params, Brand.class);
//2. 调用service添加brandService.add(brand);
//3. 响应成功的标识response.getWriter().write("success");
    }
@OverrideprotectedvoiddoPost(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
this.doGet(request, response);
    }
}



3.4.2 前端实现

上图左边是页面效果,里面的 提交 按钮可以通过上图右边看出绑定了一个 单击事件,而该事件绑定的是 addBrand 函数,所以添加数据功能的逻辑代码应该写在 addBrand() 函数中。在此方法中需要发送异步请求并将表单中输入的数据作为参数进行传递。如下


// 添加数据addBrand() {
var_this=this;
// 发送ajax请求,添加数据axios({
method:"post",
url:"http://localhost:8080/brand-case/addServlet",
data:_this.brand    }).then(function (resp) {
//响应数据的处理逻辑    })
}


在 then 函数中的匿名函数是成功后的回调函数,而 resp.data 就可以获取到响应回来的数据,如果值是 success 表示数据添加成功。成功后我们需要做一下逻辑处理:


关闭新增对话框窗口


如下图所示是添加数据的对话框代码,从代码中可以看到此对话框绑定了 dialogVisible 数据模型,只需要将该数据模型的值设置为 false,就可以关闭新增对话框窗口了。


重新查询数据


数据添加成功与否,用户只要能在页面上查看到数据说明添加成功。而此处需要重新发送异步请求获取所有的品牌数据,而这段代码在 查询所有 功能中已经实现,所以我们可以将此功能代码进行抽取,抽取到一个 selectAll() 函数中


// 查询所有数据selectAll(){
var_this=this;
axios({
method:"get",
url:"http://localhost:8080/brand-case/selectAllServlet"    }).then(function (resp) {
_this.tableData=resp.data;
    })
}


那么就需要将 mounted() 钩子函数中代码改进为


mounted(){
//当页面加载完成后,发送异步请求,获取数据this.selectAll();
}


同时在新增响应的回调中调用 selectAll() 进行数据的重新查询。


弹出消息给用户提示添加成功


上图左边就是 elementUI 官网提供的成功提示代码,而上图右边是具体的效果。


注意:上面的this需要的是表示 VUE 对象的this。


综上所述,前端代码如下:


// 添加数据addBrand() {
var_this=this;
// 发送ajax请求,添加数据axios({
method:"post",
url:"http://localhost:8080/brand-case/addServlet",
data:_this.brand    }).then(function (resp) {
if(resp.data=="success"){
//添加成功//关闭窗口_this.dialogVisible=false;
// 重新查询数据_this.selectAll();
// 弹出消息提示_this.$message({
message: '恭喜你,添加成功',
type: 'success'            });
        }
    })
}


相关文章
|
1月前
|
JavaScript 前端开发 API
|
1月前
|
JavaScript API UED
vue.js怎么实现全屏显示功能
【10月更文挑战第7天】
16 1
|
1月前
|
资源调度 JavaScript UED
如何使用Vue.js实现单页应用的路由功能
【10月更文挑战第1天】如何使用Vue.js实现单页应用的路由功能
|
17天前
|
JavaScript UED
"Vue实战技巧大揭秘:一招解决路由跳转页面不回顶部难题,让你的单页面应用用户体验飙升!"
【10月更文挑战第23天】在Vue单页面应用中,点击路由跳转时,默认情况下页面不会自动滚动到顶部,这可能影响用户体验。本文通过一个新闻网站的案例,介绍了如何使用Vue-router的全局前置守卫和`scrollBehavior`方法,实现路由跳转时页面自动滚动到顶部的功能,提升用户浏览体验。
52 0
|
1月前
|
JavaScript 前端开发 API
vue尚品汇商城项目-day04【28.详情页面Detail】
vue尚品汇商城项目-day04【28.详情页面Detail】
17 1
|
29天前
|
JavaScript 前端开发 安全
如何在 Vue 页面中禁止选择、右键、复制及 F12 开发者工具
【10月更文挑战第3天】 在前端开发中,保护页面内容不被随意复制或查看是一个常见需求。本文介绍了如何在 Vue 应用中实现禁止文本选择、右键菜单、复制操作以及 F12 开发者工具的方法。通过结合 CSS 和 JavaScript 事件监听,我们可以增加用户查看和复制内容的难度,尽管无法完全阻止高级用户。适当的防护措施可以为内容提供一层额外的保护,帮助开发者提升页面安全性。
320 0
|
3天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
3天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
3天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
3天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。