当前位置: 首页 > news >正文

前后端分离-小项目-3前后端交互

第一步编写前端页面,第二步搭建后端环境,现在开始第三步,继续完善前端功能


完善“添加”按钮功能

  1. Ajax异步请求安装

  • 在前端项目安装ajax。在Terminal输入:npm i axios -S

  1. 点击“添加”按钮,弹出Dialog对话框

  1. 设置对话框里面的内容——表单

  • 对话框选用Dialog

  • 嵌入表单menu,二者一起构成了新增对话框

  • 注意v-model,:model,变量,方法的设置及格式

    <!--添加对话框--><el-dialog text v-model="dialogVisible" width="30%" title="提示"><!--添加表单--><el-form :model="furn" label-width="120px" style="width:80%"><el-form-item label="商品名"><el-input v-model="furn.name" /></el-form-item><el-form-item label="制造商"><el-input v-model="furn.maker" /></el-form-item><el-form-item label="价格"><el-input v-model="furn.price" /></el-form-item><el-form-item label="销量"><el-input v-model="furn.sales" /></el-form-item><el-form-item label="库存"><el-input v-model="furn.stock" /></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="dialogVisible = false">确定</el-button></span></template></el-dialog>
  1. 创建axios request

  • 命名成了myRequest,便于区别request

// 引入axios
import axios from 'axios';
// 通过axios创建对象-request,用于发送请求到后端
const myRequest=axios.create({timeout: 5000
})
// request拦截器处理
myRequest.interceptors.request.use(config=>{config.headers['Content-Type']='application/json;charset=utf-8'return config
},error => {return Promise.reject(error)
})
export default myRequest
  1. 跨域异常:AxiosError/跨源

  • 修改vue.config.js

module.exports = {devServer: {port: 10000,proxy:{ //设置代理,必填"/api":{    //设置拦截器,格式:/+名字target:"http://localhost:8080" ,//目标地址,就是'/api'要替换的地址changeOrigin:true,              //设置是否同源,设为是。实现跨域pathRewrite:{                   //路径重写'/api':''                   //选择忽略拦截器里面的单词}}}}
}
  • HomeView.vue修改ajax的访问url:"localhost:8080/save"改为。前后端即可通信

myRequest.post("/api/save",this.furn).then(

显示所有家居信息

思路分析

  1. 完成后台代码从mapper->service->controller,并使用Postman对代码进行测试

  • 因为使用搭建的环境,mybatis-plus已经完成了mapper\service层,直接完成controller即可

    @RequestMapping("/list")public Result listFurns(){List<Furn> furns = furnService.list();return Result.success(furns);}
  1. 完成前台代码,使用axios发送http请求,返回所有家居数据,将数据绑定显示

  methods:{list(){myRequest.get("/api/list").then(res=>{console.log("res=",res);this.tableData=res.data.data;})},
  1. 调用显示数据的方法。VUE生命周期

  created(){this.list()},
  1. 增加 处理响应后的结果

  • 主要是练习这种处理方式。这儿的用处不大

  • 实际产生的作用就是把response.data的数据层级拿出来了一层,达成下面这个效果

  • this.tableData=res.data.data=>this.tableData=res.data;前端HomeView.vue

// response拦截器,返回结果处理
myRequest.interceptors.response.use(response=>{let res=response.dataif(response.config.responseType==='blob'){return res;}if(typeof res==='string'){res=res? JSON.parse(res):res}return res;
})
  1. 在save()方法增加list(),完成刷新

  • 之前在list()方法里面加入了list(),导致循环,致使view页面不能显示

  • list()方法加在res=>{}括号里面,在页面能立马看到更新效果。原因是Ajax的异步机制

  • Ajax有通讯,运行慢,=>{}而括号外的代码在本机执行快,就导致list更新在新数据到来之前就执行了,导致看不到更新效果。

    save(){...this.list() //新增},

回显家具信息,并完成修改

思路分析

  1. 完成后台代码从mapper->service->controller,并对代码进行测试

  • 破案了。updateById()这个方法来自于接口IService,它是谁实现的呢?它自己!接口的默认实现

    @PutMapping("/update")public Result updateFurn(@RequestBody Furn furn){log.info("待修改的furn="+furn);furnService.updateById(furn);return Result.success();}
  1. 完成前台代码,回显家居信息[方式1:直接将点击的表格当前行的数据进行回显,方式2(先思考,尝试完成):根据当前行的id(家居id),到db查询对应的数据,进行回显],再使用axios发送http请求,更新数据,将数据绑定显示

  • 获取当前行数据的方法,就是在该行@Click=handleEdit(scope.row),在方法区,使用该方法,带入参数(row)即可获取。插槽机制

  • row对象转换成JSON格式的过程

  • JSON.parse(JS0N.stringify(row))就是对行数据进行深拷贝

  • 这样点击的表格当前行的数据和弹出框的数据是独立的

    handleEdit(row){// 输出原始rowconsole.log("row1=",row)// 字符串化rowconsole.log("row2=",JSON.stringify(row))// JSON格式rowconsole.log("row3=",JSON.parse(JSON.stringify(row)))},
  • 回显当前行数据。方式1:

  methods:{handleEdit(row){this.form= JSON.parse(JSON.stringify(row))    //获取当前行数据。并放到表单this.dialogVisible=true         //显示表单},
  • 从后端拿到数据再回显。方式2:

  • 修改当前行数据,以及成功状态返回。同样也存在Ajax异步,更新list()要放在then()里面

save(){if(this.form.id){//此时执行更新myRequest.put("/api/update",this.form).then(res=>{if(res.code==="200"){//更新成功this.$message({type: "success",message: res.msg})}else{//更新失败this.$message({type:"error",message:"更新数据失败"})}this.dialogVisible = falsethis.list()})}else{//此时执行添加myRequest.post("/api/save",this.form).then(res=>{// res就是后端输出给前端的结果console.log("res",res)this.dialogVisible = falsethis.list()})}},

删除家居项

思路分析

  1. 完成后台代码从mapper->service->controller,并对代码进行测试

    @DeleteMapping("/del/{id}")public Result deleteFurn(@PathVariable Integer id){furnService.removeById(id);return Result.success();}
  1. 完成前台代码,使用axios发送http请求,删除数据,将数据绑定显示

  • 注意删除的方法是用@confirm在<el-popconfirm>绑定的,而不是在<el-button>用@click。

        <template #default="scope"><el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button><el-popconfirm title="确定删除这条记录?" @confirm="handleDel(scope.row)"><template #reference><el-button link type="primary" size="small">删除</el-button></template></el-popconfirm></template>
  • handleDel()方法的具体实现

  • 完成后用list()进行刷新。同样注意位置,避免ajax异步导致刷新异常。

    handleDel(row){myRequest.delete("/api/del/"+row.id).then(res=>{if(res.code==="200"){this.$message({type:"success",message:res.msg})}else{this.$message({type:"error",message:res.msg})}this.list()})}

分页功能

需求分析

1.显示共多少记录

2.可以设置每项显示几条

3.点击第几页,显示对应数据

思路分析

1.后台使用MyBatis-plus分页插件完成查询

2.修改FurnController,增加处理分页显示代码

3.完成前台代码,加入分页导航,并将分页请求和后台接口结合


  1. 创建config/MybatisplusConfig.java配置类。配置分页插件


@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){//需要注入的对象MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();//添加分页插件//设置数据库类型interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}
  1. 增加分页插件的调用处理

  • application.yml配置输出日志。便于调试

mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • 完成后端分页功能

    @RequestMapping("/page")public Result page(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "5") Integer pageSize){Page<Furn> furnPage = furnService.page(new Page<>(pageNum, pageSize));return Result.success(furnPage);}
  1. 增加前端分页控件,并在数据池完善参数。

    <div><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":page-sizes="[5, 10]"layout="total, sizes, prev, pager, next, jumper":total="totalCount"@size-change="handleSizeChange"@current-change="handleCurrentChange"/></div>
  1. 完成控件功能

  • 完善分页长度,显示指定页码内容的方法。注意方法参数名是自定义的,由控件传入

  methods:{handleSizeChange(pageSize){this.pageSize=pageSizethis.list()},handleCurrentChange(currentPage){this.currentPage=currentPagethis.list()},
  • 采用分页方法显示,重写显示列表

  • 注意url添加参数的格式。而且参数名需要和后端接收参数名一致。

  • 注意返回接收数据时,表数据和总条数分别来自于records和total。记不得可以利用console的输出,自己手动查询变量名称后完善。

list(){// 采用分页方式更新数据列表myRequest.get("/api/page",{params:{pageNum:this.currentPage,pageSize:this.pageSize}}).then(res=>{console.log("res=",res)this.tableData=res.data.recordsthis.totalCount=res.data.total})},

切换数据源为DruidDataSource

  • 检查在pom.xml是否已经配置

        <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.17</version></dependency>
  • 创建配置类,完成注入

@Configuration
@Slf4j
public class DruidDataSourceConfig {@Bean@ConfigurationProperties("spring.datasource")public DataSource dataSource(){DruidDataSource druidDataSource = new DruidDataSource();log.info("数据源={}",druidDataSource.getClass());return druidDataSource;}
}
  • 注意@ConfigurationProperties("spring.datasource")是已经配置在application.yml的

spring:datasource:url: jdbc:mysql://localhost:3306/furn_ssm?useSSL=true&useUnicode=true&charactorEncoding=utf-8password: rootusername: rootdriver-class-name: com.mysql.cj.jdbc.Driver

带条件检索的分页显示

思路分析

  1. 完成后台代码从mapper->service->controller,并对代码进行测试

  • 构造用的是Wrappers的静态方法,而不是new ...

  • 带条件的分页查找。page(分页,条件queryWrapper)

    @RequestMapping("/search")public Result pageBySearch(@RequestParam(defaultValue = "1")Integer pageNum,@RequestParam(defaultValue = "5")Integer pageSize,@RequestParam(defaultValue = "")String search){QueryWrapper<Furn> queryWrapper = Wrappers.query();if(StringUtils.hasText(search)){queryWrapper.like("name",search);}Page<Furn> furnPage =furnService.page(new Page<>(pageNum, pageSize), queryWrapper);return Result.success(furnPage);}
  1. 完成前台代码,使用axios发送http请求,完成带条件查询分页显示

  • 前端按键添加响应方法

<el-button  @click="list">查询</el-button>
  • 注意参数的增加

    list(){//改用带条件的分页查询myRequest.get("/api/search",{params:{pageNum:this.currentPage,pageSize:this.pageSize,search:this.search}}).then(res=>{...

相关文章:

前后端分离-小项目-3前后端交互

第一步编写前端页面&#xff0c;第二步搭建后端环境&#xff0c;现在开始第三步&#xff0c;继续完善前端功能完善“添加”按钮功能Ajax异步请求安装在前端项目安装ajax。在Terminal输入&#xff1a;npm i axios -S点击“添加”按钮&#xff0c;弹出Dialog对话框设置对话框里面…...

Spring如何整合MyBatis框架?使用XML及java类的配置方式

前言 Spring文章链接: 从头到尾Spring概念&#xff0c;家族&#xff0c;核心技术使用&#xff0c;事务这一篇就够了&#xff01;&#xff01;&#xff01;_千小半的博客-CSDN博客_spring最新技术 mybatis文章链接: MyBatis框架入门(含实例)_mybatis sqlsession创建和关闭_千小…...

第七届蓝桥杯省赛——8冰雹数(递归)

题目&#xff1a;任意给定一个正整数N&#xff0c;如果是偶数&#xff0c;执行&#xff1a; N / 2如果是奇数&#xff0c;执行&#xff1a; N * 3 1生成的新的数字再执行同样的动作&#xff0c;循环往复。通过观察发现&#xff0c;这个数字会一会儿上升到很高&#xff0c;一会…...

Android 10.0 设置静态ip重启后获取不到ip的修复

1.概述 在定制化开发中,对于设置静态ip以后可以正常使用,但是遇到一个新问题 就是开机以后,获取不到ip 地址,这就有点不正常了,获取不到ip 就自然连不上网了,所以要分析问题所在解决问题 2.设置静态ip重启后获取不到ip的修复的核心代码 frameworks/opt/net/ethernet/java…...

mysql笔记

基础 概念 数据库体系结构的三级模式为&#xff1a;外模式、概念模式和内模式。 内模式&#xff1a;存储模式&#xff0c;对数据的物理结构和存储方式的描述。提供数据定义语言定义的。如顺序还是索引存储&#xff08;将概念模式定义的数据进行组织存储&#xff0c;达到较好…...

华为OD机试 - 最多等和不相交连续子序列(Python)| 真题+思路+考点+代码+岗位

最多等和不相交连续子序列 题目 给定一个数组,我们称其中连续的元素为连续子序列,称这些元素的和为连续子序列的和。 数组中可能存在几组连续子序列,组内的连续子序列互不相交且有相同的和。 求一组连续子序列,组内子序列的数目最多。输出这个数目。 输入 第一行输入为…...

第四届宁波网安市赛训练题

Crypto 散乱的密文 8fd4a4c94gf15{50}l72d3提示了2 1 6 5 3 4&#xff0c;我们直接横向排列 2165348fd4a4c94gf15{50}l72d3 按顺序竖着抄下来fc1l84f}a45dg034{2d957,然后栅栏解密&#xff0c;注意这里是W型栅栏解密&#xff0c;行数6 flag:flag{52048c453d794df1} 综合解密…...

Windows中MySQL 8.x版本忘记密码如何重设

Windows中MySQL 8.x版本忘记密码如何重置 文章目录Windows中MySQL 8.x版本忘记密码如何重置一、前言二、重置密码操作1、停止MySQL服务2、以安全模式启动MySQL服务3、无密码登录mysql4、重置登录密码5、验证密码是否重置成功三、最后我想说一、前言 好久之前在电脑下载的MySQL…...

【信管12.1】信息文档管理与配置管理

信息文档管理与配置管理对于项目管理来说&#xff0c;文档非常重要&#xff0c;如果是传统的工程行业项目的话&#xff0c;仅仅标书就是几百上千页的。相对来说&#xff0c;其实信息系统开发项目已经好很多了。另外就是配置项&#xff0c;它是比文档更大的一个概念&#xff0c;…...

一文搞懂Linux的标准输出/错误重定向

前言 今天在写一个脚本时&#xff0c;需要将shell命令和可执行程序的输出重定向在某一个log文件中&#xff0c;但是遇到了点小问题&#xff0c;索性就研究下输出重定向到底怎么回事。 Linux系统&#xff0c;有一个非常重要概念&#xff0c;就是一切皆文件。在使用shell脚本时&a…...

【OJ】计数的梦

&#x1f4da;Description: Bessie 处于半梦半醒的状态。过了一会儿&#xff0c;她意识到她好像在数羊&#xff0c;不能入睡。Bessie的大脑反应灵敏&#xff0c;仿佛真实地看到了她数过的一个又一个数。她开始注意每一个数码&#xff1a;每一个数码在计数的过程中出现过多少次…...

【项目实战】MySQL使用CONCAT字符串拼接函数实现与特殊字符的拼接

一、需求说明 因为有新功能需要上生产环境&#xff0c;总有一些乱七八糟的兼容历史数据的活要去做&#xff0c;比如以下。 需要批量的更新数据库中某个字段&#xff08;如id列中原来是ABCDEFG&#xff0c;需要改成[“ABCDEFG”]&#xff09;&#xff0c; 没错&#xff0c;就是…...

OpenCV实战(11)——形态学变换详解

OpenCV实战&#xff08;11&#xff09;——形态学变换详解0. 前言1. 腐蚀和膨胀运算1.1 腐蚀和膨胀基础1.2 使用形态学滤波器执行图像腐蚀和膨胀运算2. 开运算和闭运算2.1 使用形态学滤波器执行图像开运算和闭运算3. 形态学变换应用3.1 使用形态学滤波器检测边缘3.2 使用形态学…...

SPI协议详解(Standard SPI、Dual SPI和Queued SPI)

1、标准SPI 1.1、SPI接口的引脚 (1)SCLK&#xff1a;时钟线&#xff1b; (2)MOSI(master output slave input)&#xff1a;主设备输出&#xff0c;从设备输入&#xff0c;单向传输&#xff1b; (3)MISO(master input slave output)&#xff1a;主设备输入&#xff0c;从设备输…...

【代码随想录二刷】Day15-二叉树-C++

代码随想录二刷Day15 今日任务 层序遍历 226.翻转二叉树 101.对称二叉树 语言&#xff1a;C 层序遍历 102.二叉树的层序遍历 class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> res;if(root NULL) …...

C++为什么能重夺年度语言?

目录一、爷青回1、年初依旧很多大新闻&#xff0c;其中一条就是TIOBE把年度编程语言颁给了C。2、这是什么概念&#xff1f;那一年Java的流行指数是14%。二、C为什么衰落三、C为什么重新流行1、C为什么重新流行起来了呢&#xff1f;2、C究竟做对了什么呢&#xff1f;3、根本原因…...

视频监控实时接入——以海康威视为例(2023.2.16)

海康威视实时视频监控接入学习 2023.2.16引言1、视频协议简介1.1 RTSP——Real Time Streaming Protocol&#xff08;实时流传输协议&#xff09;1.2 RTMP——Real Time Messaging Protocol&#xff08;实时消息传输协议&#xff09;1.3 HLS——HTTP Live Streaming&#xff08…...

推荐系统[一]:超详细知识介绍,一份完整的入门指南,解答推荐系统是什么。

1. 推荐算法的初步理解 如果说互联网的目标就是连接一切,那么推荐系统的作用就是建立更加有效率的连接,推荐系统可以更有效率的连接用户与内容和服务,节约了大量的时间和成本。 1.1 推荐系统主要解决问题 任务一:挖掘长尾:帮助用户找到想要的物品(音乐、商品、新闻),…...

新手小白入门必看!如何批量注册Twitter账号?

Twitter是目前海外比较流行的社媒营销平台&#xff0c;所以很多从事跨境电商行业的朋友都需要利用多个Twitter账号来推广营销&#xff0c;但是注册和管理多个Twitter账号其实并不是简单的事情。龙哥将会在这里详细讲讲该如何批量注册并且让这些账号不会因为关联被封号&#xff…...

虚拟环境的创建以及labelme的使用教程

本来打算是将这两部分分开的&#xff0c;但写完虚拟环境的创建似乎字数太少了&#xff0c;不过二者有关联&#xff0c;所以就放一起了。简单介绍一下&#xff0c;虚拟环境的创建有win11系统已经Ubuntu系统&#xff0c;labelme教程包括了下载及其使用的全部流程&#xff0c;以及…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究

摘要&#xff1a;在消费市场竞争日益激烈的当下&#xff0c;传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序&#xff0c;探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式&#xff0c;分析沉浸式体验的优势与价值…...

SQL注入篇-sqlmap的配置和使用

在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap&#xff0c;但是由于很多朋友看不了解命令行格式&#xff0c;所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习&#xff0c;链接&#xff1a;https://wwhc.lanzoue.com/ifJY32ybh6vc…...

ubuntu中安装conda的后遗症

缘由: 在编译rk3588的sdk时&#xff0c;遇到编译buildroot失败&#xff0c;提示如下&#xff1a; 提示缺失expect&#xff0c;但是实测相关工具是在的&#xff0c;如下显示&#xff1a; 然后查找借助各个ai工具&#xff0c;重新安装相关的工具&#xff0c;依然无解。 解决&am…...