Maynor手把手教你完成一个SpringBoot+Vue+Element实现的SPA商品管理系统(增删改查)

前言

完整代码 三连后私信我获取~
撸了一上午完成的SPA商品管理系统,求三连!

B站演示视频

Maynor手把手教你完成一个SpringBoot+Vue+Element演示视频(最后出现了点小bug)_哔哩哔哩_bilibili

项目需求

商品管理系统

1、商品列表

多条件查询包括模糊查询,区间查询,类别选择和品牌选择、列表分页、类别和品类下拉列表选择

2、添加商品

3、修改商品

4、批量删除

5、单个商品删除

项目搭建:

SpringBoot项目的搭建(你的第一个SpringBoot项目)_A Coder-CSDN博客_springboot 项目

项目结构

后端结构

配置文件

pom.xml

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.5</version><relativePath/> <!-- lookup parent from repository --></parent><!-- 统一版本维护 --><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><mybatis.starter.version>1.3.2</mybatis.starter.version><mapper.starter.version>2.0.2</mapper.starter.version><mysql.version>5.1.32</mysql.version><pageHelper.starter.version>1.2.5</pageHelper.starter.version><durid.starter.version>1.1.10</durid.starter.version><lombok.version>1.18.16</lombok.version></properties><dependencies><!-- SpringBoot整合SpringMVC的启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- SpringBoot整合jdbc和事务的启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- mybatis启动器 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.starter.version}</version></dependency><!-- 通用Mapper启动器 --><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>${mapper.starter.version}</version></dependency><!-- 分页助手启动器 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pageHelper.starter.version}</version></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- Druid连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${durid.starter.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

application.properties

#Tomcat
server.port=8090
#DB configuration
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test3?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
#druid
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.initial-size=1
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=20
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.stat-view-servlet.allow=true
logging.level.com.czxy=debug

封装类

BaseResult

package com.czxy.common;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.ResponseEntity;@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseResult {/*** 10000 成功* 10001 失败*/private Integer code;/*** 成功或者失败的消息提醒*/private String msg;/*** 数据*/private Object data;private Integer total;public BaseResult(Integer code, String msg, Object data) {this.code = code;this.msg = msg;this.data = data;}public static ResponseEntity<BaseResult> success(Object data){return ResponseEntity.ok(new BaseResult(10000,"成功",data));}public static ResponseEntity<BaseResult> fail(){return ResponseEntity.ok(new BaseResult(10001,"失败",null));}public static ResponseEntity<BaseResult> success(Object data,Integer total){return ResponseEntity.ok(new BaseResult(10000,"成功",data,total));}}

GlobalCorsConfig

package com.czxy.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;/**  全局跨域配置类*/
@Configuration
public class GlobalCorsConfig {@Beanpublic CorsFilter corsFilter() {//1.添加CORS配置信息CorsConfiguration config = new CorsConfiguration();//放行哪些原始域config.addAllowedOrigin("*");//是否发送Cookie信息config.setAllowCredentials(false);//放行哪些原始域(请求方式)config.addAllowedMethod("OPTIONS");config.addAllowedMethod("HEAD");config.addAllowedMethod("GET");     //getconfig.addAllowedMethod("PUT");     //putconfig.addAllowedMethod("POST");    //postconfig.addAllowedMethod("DELETE");  //deleteconfig.addAllowedMethod("PATCH");config.addAllowedHeader("*");//2.添加映射路径UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();configSource.registerCorsConfiguration("/**", config);//3.返回新的CorsFilter.return new CorsFilter(configSource);}}

数据库

-- MySQL dump 10.13  Distrib 5.5.15, for Win64 (x86)
--
-- Host: 127.0.0.1    Database: test3
-- ------------------------------------------------------
-- Server version   5.5.15/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;--
-- Table structure for table `brand`
--DROP TABLE IF EXISTS `brand`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `brand` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
/*!40101 SET character_set_client = @saved_cs_client */;--
-- Dumping data for table `brand`
--LOCK TABLES `brand` WRITE;
/*!40000 ALTER TABLE `brand` DISABLE KEYS */;
INSERT INTO `brand` VALUES (1,'花花公子'),(2,'唐狮'),(4,'太平鸟'),(5,'森马'),(6,'大嘴猴'),(7,'adidas'),(8,'耐克'),(9,'苹果'),(10,'华为'),(11,'小米'),(12,'格力');
/*!40000 ALTER TABLE `brand` ENABLE KEYS */;
UNLOCK TABLES;--
-- Table structure for table `category`
--DROP TABLE IF EXISTS `category`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `category` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
/*!40101 SET character_set_client = @saved_cs_client */;--
-- Dumping data for table `category`
--LOCK TABLES `category` WRITE;
/*!40000 ALTER TABLE `category` DISABLE KEYS */;
INSERT INTO `category` VALUES (1,'女装'),(2,'男装'),(3,'内衣'),(4,'家电'),(5,'吸尘器'),(6,'取暖器'),(7,'手机'),(8,'家纺');
/*!40000 ALTER TABLE `category` ENABLE KEYS */;
UNLOCK TABLES;--
-- Table structure for table `goods`
--DROP TABLE IF EXISTS `goods`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `goods` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) DEFAULT NULL,`brand_id` int(11) DEFAULT NULL,`category_id` int(11) DEFAULT NULL,`introduction` varchar(50) DEFAULT NULL,`store_num` int(11) DEFAULT NULL,`price` double DEFAULT NULL,`create_time` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
/*!40101 SET character_set_client = @saved_cs_client */;--
-- Dumping data for table `goods`
--LOCK TABLES `goods` WRITE;
/*!40000 ALTER TABLE `goods` DISABLE KEYS */;
INSERT INTO `goods` VALUES (2,'华为Mate30',10,7,'华为MATE30 金色1T',200,9999,'2021-10-22'),(8,'运动鞋',8,1,'百搭潮休闲鞋子',6000,999,'2021-11-02'),(9,'夹克',4,2,'新款迷彩休闲连帽上衣',8888,789,'2021-11-01'),(10,'demo',NULL,NULL,'xxxx',1,999,'2021-11-03'),(11,'1',NULL,NULL,'1',111,11,NULL),(12,'2',NULL,NULL,NULL,222,22,'2021-11-25T16:00:00.000Z'),(13,'123',NULL,NULL,'123',12,123,'2021-11-09');
/*!40000 ALTER TABLE `goods` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;-- Dump completed on 2021-11-05  9:27:52

后端代码部分

主要完成 entity/dao/service/controller/vo的开发,由于代码重复仅贴出Goods的完整代码

entity层:

@Table(name = "goods")
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class TTeacher implements Serializable {//id
//  name
//          brand_id
//  category_id
//          introduction
//  store_num
//          price
//  create_time@Idprivate Integer id;private String name;private Integer brand_id;private Integer category_id;private String introduction;private Integer store_num;private Double price;private String create_time;// 在java的日期类型只要符合2012-02-02private TSchool school;private TType type;}

dao层:

@org.apache.ibatis.annotations.Mapper
public interface TeacherMapper extends Mapper<TTeacher> {}

service层:

public interface TeacherService {ResponseEntity<BaseResult> findByCondition(TeacherSearchVO teacherSearchVO);boolean add(TTeacher tea);TTeacher findById(Integer id);boolean update(TTeacher tea);boolean deleteById(Integer id);List<TTeacher> selectAll();
}

impl 实现类

@Service
@Transactional
public class TeacherServiceImpl implements TeacherService {@Autowiredprivate TeacherMapper teacherMapper;@Autowiredprivate SchoolMapper schoolMapper;@Autowiredprivate TypeMapper typeMapper;@Overridepublic ResponseEntity<BaseResult> findByCondition(TeacherSearchVO teacherSearchVO) {// List<TTeacher> teaList = new ArrayList<>();//最终要返回到前端的数据//拼接条件String teacherName = teacherSearchVO.getTeacherName();Integer schoolId = teacherSearchVO.getSchoolId();Integer typeId = teacherSearchVO.getTypeId();String typeName = teacherSearchVO.getTypeName();Integer minSalary = teacherSearchVO.getMinSalary();Integer maxSalary = teacherSearchVO.getMaxSalary();Integer page = teacherSearchVO.getPage();Integer rows = teacherSearchVO.getRows();Example example = new Example(TTeacher.class);Example.Criteria criteria = example.createCriteria();//1 名字模糊if (StringUtils.isNotBlank(teacherName)){criteria.andLike("name","%"+teacherName+"%");}//2 id精确匹配if (schoolId!=null&&StringUtils.isNotBlank(schoolId.toString())){criteria.andEqualTo("brand_id",schoolId);}if (typeId!=null&&StringUtils.isNotBlank(typeId.toString())){criteria.andEqualTo("category_id",typeId);}if (minSalary!=null&&StringUtils.isNotBlank(minSalary.toString())){criteria.andGreaterThanOrEqualTo("price",minSalary);}//4if (maxSalary!=null&&StringUtils.isNotBlank(maxSalary.toString())){criteria.andLessThanOrEqualTo("price",maxSalary);}//查找总条数,供分页使用int total = teacherMapper.selectByExample(example).size();//7 后端分页PageHelper.startPage(page,rows);//8 查出结果List<TTeacher> teacherList = teacherMapper.selectByExample(example);//后端关联id显示名字for (TTeacher tea:teacherList){tea.setType(typeMapper.selectByPrimaryKey(tea.getCategory_id()));tea.setSchool(schoolMapper.selectByPrimaryKey(tea.getBrand_id()));}if (teacherList.size()==0&&teacherSearchVO.getPage()!=1){page = total%rows==0?total/rows:(total/rows+1);teacherSearchVO.setPage(page);findByCondition(teacherSearchVO);}return BaseResult.success(teacherList,total);}@Overridepublic boolean add(TTeacher tea) {return teacherMapper.insert(tea)==1;}@Overridepublic TTeacher findById(Integer id) {return teacherMapper.selectByPrimaryKey(id);}@Overridepublic boolean update(TTeacher tea) {return teacherMapper.updateByPrimaryKey(tea)==1;}@Overridepublic boolean deleteById(Integer id) {return teacherMapper.deleteByPrimaryKey(id)==1;}@Overridepublic List<TTeacher> selectAll() {return teacherMapper.selectAll();}
}

VO类:

@Data
public class TeacherSearchVO {private String teacherName;private String typeName;private Integer schoolId;private Integer typeId;private Integer minSalary;private Integer maxSalary;private Integer page;//页码private Integer rows;//行数}

controller层:

@RestController
@RequestMapping("/teacher")
public class TeacherController {@Autowiredprivate TeacherServiceImpl teacherService;@GetMapping("/condition")public ResponseEntity<BaseResult> findByCondition(TeacherSearchVO teacherSearchVO){ResponseEntity<BaseResult> rbr = teacherService.findByCondition(teacherSearchVO);return rbr;}@GetMapping("/all")public List<TTeacher> selectAll( ){List<TTeacher>  rbr = teacherService.selectAll();return rbr;}@PostMappingpublic ResponseEntity<BaseResult> add(@RequestBody TTeacher tea){boolean flag = teacherService.add(tea);if (flag){return BaseResult.success("新增成功");}else{return BaseResult.fail();}}@GetMapping("/{id}")public ResponseEntity<BaseResult> findById(@PathVariable("id") Integer id){TTeacher tea = teacherService.findById(id);return BaseResult.success(tea);}@PutMappingpublic ResponseEntity<BaseResult> update(@RequestBody TTeacher tea){boolean flag = teacherService.update(tea);if (flag){return BaseResult.success("修改成功");}else{return BaseResult.fail();}}@DeleteMapping("/{id}")public ResponseEntity<BaseResult> deleteById(@PathVariable Integer id){boolean flag= teacherService.deleteById(id);if (flag){return BaseResult.success("删除成功");}else{return BaseResult.fail();}}@DeleteMapping("/batchDelete/{ids}")public ResponseEntity<BaseResult> bachDelete(@PathVariable String ids){String[] splitIds = ids.split(",");for (String id:splitIds){teacherService.deleteById(Integer.parseInt(id));}return BaseResult.success("删除成功");}}

Maynor小声bb:后端完成,接下来我们转战前端页面的实现!

前端代码部分:

vue创建命令:

npm create xxxcd xxxnpm run serve

vue安装命令:

npm install

elementui 安装

npm i element-ui -S

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import axios from 'axios'
axios.defaults.baseURL = "http://localhost:8090"
Vue.prototype.$http = axiosVue.use(ElementUI)Vue.config.productionTip = falsenew Vue({router,render: h => h(App)
}).$mount('#app')

App.vue

<template><div id="app"><div id="nav"><!-- <router-link to="/schoolList">品牌列表</router-link> | --><router-link to="/teacherList">商品管理</router-link></div><router-view/></div>
</template>

index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'Vue.use(VueRouter)const routes = [{path: '/',name: 'Home',component: Home},{path: '/schoolList',name: 'SchoolList',component: () => import('@/views/SchoolList.vue')},{path: '/teacherList',name: 'TeacherList',component: () => import('@/views/TeacherList.vue')},{path: '/addTeacher',name: 'AddTeacher',component: () => import('@/views/AddTeacher.vue')},{path: '/updateTeacher/:id(\\d+)',name: 'UpdateTeacher',component: () => import('@/views/UpdateTeacher.vue')},
]const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
})export default router

前端增删改查

页面显示

 <div><hr><router-link to="/addTeacher">新增商品</router-link>   <br><input type="button" value="搜索" @click="initTeaList()"> <br><input type="button" value="批量删除" @click="batchDelete()"><br>品牌:<select v-model="teacherSearchVo.schoolId"><option value="">--请选择品牌--</option><option v-for="(s,index) in schoolList" :key="index" :value="s.id">{{s.name}}</option></select>类别:<select v-model="teacherSearchVo.typeId"><option value="">--请选择分类--</option><option v-for="(s,index) in categoryList" :key="index" :value="s.id">{{s.name}}</option></select>商品名称:<input type="text" v-model="teacherSearchVo.teacherName">商品价格:<input type="text" v-model="teacherSearchVo.minSalary">-<input type="text" v-model="teacherSearchVo.maxSalary">
<br><table border="1"><tr><th><input type="checkbox" v-model="selectAll" @change="change()">全选</th><th>商品ID</th><th>商品名称</th><th>商品品牌</th><th>商品类别</th><th>商品价格</th><th>商品库存</th><th>发布时间</th><th>商品介绍</th><th>操作</th></tr><tr v-for="(tea,index) in teaList" :key="index"><td><input type="checkbox" v-model="dels" :value="tea.id"></td><td>{{tea.id}}</td><td>{{tea.name}}</td><td>{{tea.school.name}}</td><td>{{tea.type.name}}</td><td>{{tea.price}}</td><td>{{tea.store_num}}</td><td>{{tea.create_time}}</td><td>{{tea.introduction}}</td><td><router-link :to="'/updateTeacher/'+tea.id">修改</router-link>   <a href="#" @click="deleteById(tea.id)">删除</a> </td></tr></table>

js

export default {data() {return {id:[],teacherSearchVo:{page:1,rows:3,schoolId:"",typeId:""},teaList:[],//商品列表schoolList:[],//所有的学校集合categoryList:[],//所有的类别集合total:0,//总条数dels:[],//批量删除的id集合selectAll:false,//true全选  false全不选}},methods: {async initTeaList(){let res = await this.$http.get("/teacher/condition",{params:this.teacherSearchVo})console.log(res)this.teaList = res.data.datathis.total = res.data.total}, async initSchoolList(){let res = await this.$http.get("/school/all")this.schoolList = res.data.data},async initCategoryList(){let res = await this.$http.get("/type/all")this.categoryList = res.data.dataconsole.log(this.categoryList)},handleSizeChange(val) {console.log(`每页 ${val} 条`);this.teacherSearchVo.rows = valthis.initTeaList()},handleCurrentChange(val) {console.log(`当前页: ${val}`);this.teacherSearchVo.page = valthis.initTeaList()},async deleteById(id){console.log(id)let res = await this.$http.delete("/teacher/"+id)if(res.data.code==10000){alert("删除成功")this.initTeaList()}else{alert("删除失败")}},async batchDelete(){// 组装idlet delIds = "";for(let i=0;i<this.dels.length;i++){delIds += this.dels[i] + ","}delIds = delIds.substring(0,delIds.length-1)// 调用ajaxlet res = await this.$http.delete("/teacher/batchDelete/"+delIds)alert("删除成功")this.initTeaList()},change(){console.log(this.selectAll)if(this.selectAll==true){//全选for(let i=0;i<this.teaList.length;i++){this.dels.push(this.teaList[i].id)}}else{this.dels = []}}},created() {this.initTeaList()this.initSchoolList()this.initCategoryList()},watch:{'dels':function(){if(this.dels.length==this.teaList.length){this.selectAll = true}else{this.selectAll = false}},'teaList':function(){}}
}

添加功能

<router-link to="/addTeacher">新增商品</router-link>

通过点击添加按钮跳转到添加的页面

<template><div><h1>新增商品</h1>商品名字:<input type="text" v-model="teacher.name"><br>  商品品牌:<select v-model="teacherSearchVo.schoolId"><option value="">--请选择品牌--</option><option v-for="(s,index) in schoolList" :key="index" :value="s.id">{{s.name}}</option></select><br>  商品类别:<select v-model="teacherSearchVo.typeId"><option value="">--请选择分类--</option><option v-for="(s,index) in typeList" :key="index" :value="s.id">{{s.name}}</option></select><br>商品介绍: <input type="text" v-model="teacher.introduction"><br>商品价格: <input type="text" v-model="teacher.price"><br>商品库存: <input type="text" v-model="teacher.store_num"><br>发布时间:<input type="date" v-model="teacher.create_time"><br>     <input type="button" value="新增" @click="add()"></div>
</template><script>
export default {data() {return {teacherSearchVo:{page:1,rows:3,schoolId:"",typeId:""},teacher:{sex:"",typeId:"",//默认:--请选择--},//商品是一个对象typeList:[],//商品类型数组schoolList:[],//所有的学校集合}},methods: {async add(){let res = await this.$http.post("/teacher",this.teacher)console.log(res)if(res.data.code==10000){alert("新增成功")this.$router.push("/teacherList")}else{alert("新增失败");}},//初始化商品类型的方法async initTypeList(){let res = await this.$http.get("/type/all")this.typeList = res.data.data},async initSchoolList(){let res = await this.$http.get("/school/all")this.schoolList = res.data.data},},created() {this.initTypeList()this.initSchoolList()},
}
</script><style></style>

修改功能

<router-link :to="'/updateTeacher/'+tea.id">修改</router-link>

与添加页面类似,仅需修改js即可

export default {data() {return {teacherSearchVo:{page:1,rows:3,schoolId:"",typeId:""},teacher:{sex:"",typeId:"",//默认:--请选择--},//商品是一个对象typeList:[],//商品类型数组schoolList:[],//所有的学校集合}},methods: {async initTeacher(){let res = await this.$http.get("/teacher/"+this.id)// debuggerthis.teacher = res.data.data},//初始化商品类型的方法async initTypeList(){let res = await this.$http.get("/type/all")this.typeList = res.data.data},async update(){let res = await this.$http.put("/teacher",this.teacher)if(res.data.code==10000){alert("修改成功")this.$router.push("/teacherList")}else{alert("修改失败")}},async initSchoolList(){let res = await this.$http.get("/school/all")this.schoolList = res.data.data},},  created() {this.id = this.$route.params.idthis.initTeacher()this.initTypeList()this.initSchoolList()},
}

删除功能

<a href="#" @click="deleteById(tea.id)">删除</a>
 async deleteById(id){console.log(id)let res = await this.$http.delete("/teacher/"+id)if(res.data.code==10000){alert("删除成功")this.initTeaList()}else{alert("删除失败")}},

目前功能基本实现了!我们再来完善一下

批量删除

功能分析:

实现批量删除的办法其实有很多,我这里是把批量传入的id放进数组里,然后后端用for循环遍历删除。

<input type="checkbox" v-model="dels" :value="tea.id">

js

async batchDelete(){// 组装idlet delIds = "";for(let i=0;i<this.dels.length;i++){delIds += this.dels[i] + ","}delIds = delIds.substring(0,delIds.length-1)// 调用ajaxlet res = await this.$http.delete("/teacher/batchDelete/"+delIds)alert("删除成功")this.initTeaList()},change(){console.log(this.selectAll)if(this.selectAll==true){//全选for(let i=0;i<this.teaList.length;i++){this.dels.push(this.teaList[i].id)}}else{this.dels = []}},watch:{'dels':function(){if(this.dels.length==this.teaList.length){this.selectAll = true}else{this.selectAll = false}},'teaList':function(){}}

模糊查询 多条件查询

思考一下该怎么写,代码在上面已贴出

Elementui 实现分页查询

使用npm 安装完ui插件后,改下官网模板

<el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="teacherSearchVo.page":page-sizes="[1,2,3,4,50,1000]":page-size="teacherSearchVo.rows"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination>

参数解释:

​ @size-change:每页条数通过下拉列表框发生改变

​ @current-change:当前页码发生改变

​ current-page:当前是第几页 2

​ page-sizes:下拉列表框,设置每页显示条数

​ page-size:每页显示条数 3

​ total:该数据在数据库里的总条数 16,作用:计算总页数

js

handleSizeChange(val) {console.log(`每页 ${val} 条`);this.teacherSearchVo.rows = valthis.initTeaList()},handleCurrentChange(val) {console.log(`当前页: ${val}`);this.teacherSearchVo.page = valthis.initTeaList()},

后记

Maynor手把手教你完成一个SpringBoot+Vue+Element实现的SPA商品管理系统(增删改查)相关推荐

  1. vue+element实现树状表格的增删改查;使用el-table树形数据与懒加载实现树状表格增删改查

    以下代码可以直接复制使用 一.情景: 列表是一个树状表格,可以无限添加下级,以及对列表的某一行进行增删改查(目前查没有写). 原博链接 二.本篇是在原博主的代码基础上添加了部分功能. 功能1: 给树状 ...

  2. springboot整合mybatis实现简单的单表增删改查(完整代码可下载)

    搭建项目 项目简单效果,前端效果丑的一批,主要是后端功能实现: springboot增删改查 csdn完整代码下载链接: springboot+mybatis Gitee下载地址: Gitee下载地址 ...

  3. 基于springboot+thymeleaf+mybatis的员工管理系统 —— 增删改查

    员工管理系统 - 增删改查 entity 查询所有功能 查询所有的页面 emplist.html 保存员工 保存员工的页面 addEmp.html 删除员工 修改员工 根据id查询员工 修改员工信息 ...

  4. Springboot整合JDBC和DBUtils,实现简单的增删改查.

    Springboot整合JDBC和DBUtils,实现简单的增删改查. 一.pom.xml文件 <?xml version="1.0" encoding="UTF- ...

  5. Android 中编写一个简易购物车,商品包括商品名称,单价,数量,可以对商品进行增删改查功能。(ArrayList,SQLite)

    Android 中编写一个简易购物车,商品包括商品名称,单价,数量,可以对商品进行增删改查功能.(ArrayList,SQLite) 布局(activity_main.xml): <?xml v ...

  6. springboot/vue前后端分离后台管理系统增删改查

    1.需求分析 一个音乐管理系统包括: 1.用户信息管理:该模块主要由管理员进行操作,将所有用户的用户名.密码.邮箱.创建时间以及用户状态列在一张表,管理员可以进行增加.删除(批量删除).修改以及查询用 ...

  7. springBoot加layui和mybatis后台管理系统增删改查分页登录注销修改密码功能

    超市订单管理系统 1 登录页面 1.1 登录 点击提交按钮提交form表单使用post请求把(String name, String password)数据传到后台loginController 路径 ...

  8. 【SpringBoot实战】员工部门管理页面,增删改查,含源码

    简介 基于SpringBoot,整合MyBatis, Hibernate, JPA, Druid, bootstrap, thymeleaf等,进行增删改查操作的Demo bootstrap-curd ...

  9. Springboot 整合微信小程序实现登录与增删改查

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:我的大学到研究生自学 Java 之路,过程艰辛,不放弃,保持热情,最终发现我是这样拿到大厂 offer 的! 作 ...

最新文章

  1. vs2012常用快捷键
  2. 哔哩哔哩软测三面,面试题复盘
  3. 3D图形学的线性代数的通俗解释。
  4. XML文档类型定义DTD
  5. Android 编译系统分析(二)
  6. 解决eclipse + pydev 编译过程中有中文的问题
  7. python 读文件写数据库_python读文件写数据库
  8. org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved
  9. for循环与each遍历的跳出循环方式
  10. 华为Mate X2再曝光:全新向内折叠方案 有望彻底消除折痕
  11. KVM Virtio: An I/O virtualization framework for Linux(Linux虚拟IO框架)
  12. DOM操作style样式——link、style、p style=''的区别
  13. linux如何卸载金山安全终端,卸载和释放-文档中心-金山云
  14. 关于win8的各种版本的区别
  15. HDU 1374 求三角形外接圆的半径
  16. 【原创】联通网络无法使用FTP,无法使用21端口连接的解决方法
  17. 【科研小工具】输入任意坐标即可显示相应脑区详细解剖信息
  18. 计算机网络路由器的配置连接不上,为什么路由器连接不上_我的电脑换了一个路由器怎么就连接不上网络呢...
  19. 【AI教程】AI基础学习笔记(第3天)
  20. SWUSTOJ#616排序查找

热门文章

  1. 基于浏览器调用ARKit与ARCore
  2. RenderControl获取控件输出的HTML
  3. 【Linux】 Jetbot、Dofbot机器人如何创建、执行python脚本+Linux基础操作
  4. “忠诚僚机”不应该“忠诚”
  5. 英雄联盟召唤师名封号查询
  6. props写法_Vue中props的用法知识点
  7. python爬取王者_python爬取王者荣耀APP英雄皮肤-Go语言中文社区
  8. php循环volist,ThinkPHP中循环遍历的两种方法(volist和foreach标签)
  9. 使用Direct3D渲染2D图素
  10. 使用PHP获取优酷网视频缩略图