非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 2

  七、创建前端项目

  你下载了nodejs吗?从cn官网下载:http://nodejs.cn/download/,或者从一个国外org网站下载,选择自己想要的版本https://nodejs.org/download/release/,双击下载好的安装文件,选择安装路径安装好即可。安装完成后,输入命令查看版本,mac首次安装都无需配置环境变量。


根据以上命令查看配置信息,先在设置路径目录下新建两个文件夹(eg:node_global和node_cache),设置新的文件夹

PS D: \nodejs> npm config set prefix "D: \nodejs\node_global" 
PS D: \nodejs> npm config set cache "D: \nodejs\node_cache" 
PS D: \nodejs> npm get registry 
https: //registry.npmjs.org/
PS D: \nodejs> npm config set registry https://mirrors.cloud.tencent.com/npm/ 

 下载vue脚手架,理论上你应该下载过了

npm install -g @vue/cli

在cmd中创建vue项目  vue create vuedemo1 ,powershell中参见下方网页

“vue : 无法加载文件 D:\nodejs\node_global\vue.ps1,因为在此系统上禁止运行脚本”的解决方法-CSDN博客

 用上下方向键移动,然后回车,我选择Vue2,等待创建完成

执行启动项目命令(注意要先进入项目目录)

cd vuedemo1
npm run serve 

 现在cd在desktop,vue create wms-web,选择vue2,Take A While......

 cd进入,npm run serve成功启动vue脚手架,localhost:8080

八、前端项目导到idea中运行

把wms-web复制到springboot_vue_wms中,在idea打开项目,你要是足够nb用webstrom去吧
为了节约时间,不用cmd一条慢慢输入命令,可以选择小绿三角的''编译配置''

停止服务直接CTRL + C 即可

 记得把前端的git删除

tmd,后面vue服务器频频报错,找了我一个半小时,问题解决了,我的idea不知道为什么对node_modules文件进行了排除(变成黄色的),右键该文件后将目录标记为不排除就能解决element提示的问题,记得更新对应的本地的vue服务器

九、导入Element-ui

Element - 网站快速成型工具 饿了么 nb

注意了,这个安装方式和引用方式只适用于vue2,vue3用这个会报错,就算强行安装上,最后运行的时候页面只会是空白的。

npm i element-ui -S
报错可能是版本不匹配, 试试npm install element-plus --save
npm install --legacy-peer-deps element-ui --save也行

打开对应的文件管理器,发现安装成功

 好了,现在是VUE时间!

记得把main.js必要的修改

import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({render: h => h(App),
}).$mount('#app')

App.vue如下

<template><div id="app"><el-button type="primary">BUTTON</el-button></div>
</template><script>export default {name: 'App',components: {}
}
</script><style></style>

 

十、搭建页面布局

 难道不用router吗

新建IndexPage.vue文件,(后面你会命名为index,这里index报错是因为规范是组件名应该是多个单词组成的,而不是单个单词。可以考虑IndexPage或者其他的多词命名.  实在说太多不好弄的 , 导入之后报错的在vue.config中配置lintOnSave: false(胡说八道) //@8 版本中新增了要求组件名称以驼峰格式命名

<template><el-container style="height: 500px; border: 1px solid #eee"><el-aside width="200px" style="background-color: rgb(238, 241, 246)"><el-menu :default-openeds="['1', '3']"><el-submenu index="1"><template slot="title"><i class="el-icon-message"></i>导航一</template><el-menu-item-group><template slot="title">分组一</template><el-menu-item index="1-1">选项1</el-menu-item><el-menu-item index="1-2">选项2</el-menu-item></el-menu-item-group><el-menu-item-group title="分组2"><el-menu-item index="1-3">选项3</el-menu-item></el-menu-item-group><el-submenu index="1-4"><template slot="title">选项4</template><el-menu-item index="1-4-1">选项4-1</el-menu-item></el-submenu></el-submenu><el-submenu index="2"><template slot="title"><i class="el-icon-menu"></i>导航二</template><el-menu-item-group><template slot="title">分组一</template><el-menu-item index="2-1">选项1</el-menu-item><el-menu-item index="2-2">选项2</el-menu-item></el-menu-item-group><el-menu-item-group title="分组2"><el-menu-item index="2-3">选项3</el-menu-item></el-menu-item-group><el-submenu index="2-4"><template slot="title">选项4</template><el-menu-item index="2-4-1">选项4-1</el-menu-item></el-submenu></el-submenu><el-submenu index="3"><template slot="title"><i class="el-icon-setting"></i>导航三</template><el-menu-item-group><template slot="title">分组一</template><el-menu-item index="3-1">选项1</el-menu-item><el-menu-item index="3-2">选项2</el-menu-item></el-menu-item-group><el-menu-item-group title="分组2"><el-menu-item index="3-3">选项3</el-menu-item></el-menu-item-group><el-submenu index="3-4"><template slot="title">选项4</template><el-menu-item index="3-4-1">选项4-1</el-menu-item></el-submenu></el-submenu></el-menu></el-aside><el-container><el-header style="text-align: right; font-size: 12px"><el-dropdown><i class="el-icon-setting" style="margin-right: 15px"></i><el-dropdown-menu slot="dropdown"><el-dropdown-item>查看</el-dropdown-item><el-dropdown-item>新增</el-dropdown-item><el-dropdown-item>删除</el-dropdown-item></el-dropdown-menu></el-dropdown><span>王小虎</span></el-header><el-main><el-table :data="tableData"><el-table-column prop="date" label="日期" width="140"></el-table-column><el-table-column prop="name" label="姓名" width="120"></el-table-column><el-table-column prop="address" label="地址"></el-table-column></el-table></el-main></el-container></el-container></template><style scoped>
.el-header {background-color: #B3C0D1;color: #333;line-height: 60px;
}.el-aside {color: #333;
}
</style><script>
export default {name:"IndexPage",data() {const item = {date: '2016-05-02',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'};return {tableData: Array(20).fill(item)}}
};
</script>

App.vue相应的添加

<template><div id="app"><IndexPage></IndexPage></div>
</template><script>import IndexPage from "@/components/IndexPage.vue";export default {name: 'App',components: {IndexPage}
}
</script><style>
/*font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;*/
</style>
  1.  白屏是因为外层需要template

根据你的需求微修一下,我对部分部件进行了height:100%的代码修改

在assets下新建一个global.css文件,在main.js中导入   import './assets/global.css'

*{margin:0;padding: 0;
}

在IndexPage中style添加 

.el-main{padding:5px;
}

十一、页面布局的拆分

 原页面太长了,在components中新建几个界面AppAside.vue,AppHeader.vue,IndexPage.vue,AppMain.vue

AppAside是将menu部分剪切到template中;将dropdown中,给到AppHeader;table复制到Appmain( 其实是想改成MainComponent的                     下面是IndexPage.vue

<template><el-container style="height: 100%; border: 1px solid #eee"><el-aside width="200px" style="background-color: rgb(238, 241, 246);height: 100%"><AppAside></AppAside></el-aside><el-container style="height: 100%"><el-header style="text-align: right; font-size: 12px ;"><AppHeader></AppHeader><span>王小虎</span></el-header><el-main style="height: 100%"><AppMain></AppMain></el-main></el-container></el-container></template><style scoped>
.el-header {background-color: #B3C0D1;color: #333;line-height: 60px;
}
.el-main{padding:5px;
}
.el-aside {color: #333;
}
</style><script>
import AppAside from "@/components/AppAside.vue";
import AppHeader from "@/components/AppHeader.vue";
import AppMain from "@/components/AppMain.vue";export default {name:"IndexPage",components: {AppMain, AppHeader, AppAside},
};
</script>

如果有包版本的冲突,npm install --legacy-peer-deps 

十二、编写Header头页面

1.dropdown下拉

@click和@click.native有什么区别,如何阻止第三方组件内部的冒泡一.@click和@click.nati - 掘金

这是一篇文章在vue3的部分同学们,可能对native的选择有帮助

 AppHeader.vue

<template><div style="display:flex;line-height:60px;"><div><i class="el-icon-s-fold" style="font-size:20px;vertical-align: middle;"></i></div><div style="flex:1;text-align:center;font-size:27px;"><span>欢迎来到仓库管理系统</span></div><span>王小虎</span><el-dropdown trigger="click"><i class="el-icon-arrow-down" style="margin-left:5px;"></i><el-dropdown-menu slot="dropdown"><!--直接给图标加line-height:60px就居中了;加上height和line-height,让他们相等就可以让文本垂直居中;加垂直vertical-align: middle;应该就好了--><el-dropdown-item @click.native="toUser">个人中心</el-dropdown-item><el-dropdown-item @click.native="logout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></div>
</template><style scoped></style>
<script>export default{name:"AppHeader",methods:{toUser() {console.log('to_user')},logout(){console.log('logout')},}}
</script>

 IndexPage.vue部分

<el-container style="height: 100%; border: 1px solid #eee"><el-aside width="200px" style="background-color: rgb(238, 241, 246);height: 100%"><AppAside></AppAside></el-aside>

2.菜单伸缩图标

原先的太多了,不符合项目的要求,

这里是因为设置了1px的border

3.欢迎字样

4.去除背景,加入下边框

十三、菜单导航页面编写

一级菜单,AppHeader.vue

<template><div style="display:flex;line-height:60px;"><div><i class="el-icon-s-fold" style="font-size:20px;vertical-align: middle;"></i></div><div style="flex:1;text-align:center;font-size:27px;"><span>欢迎来到仓库管理系统</span></div><span>王小虎</span><el-dropdown trigger="click"><i class="el-icon-arrow-down" style="margin-left:5px;"></i><el-dropdown-menu slot="dropdown"><!--直接给图标加line-height:60px就居中了;加上height和line-height,让他们相等就可以让文本垂直居中;加垂直vertical-align: middle;应该就好了--><el-dropdown-item @click.native="toUser">个人中心</el-dropdown-item><el-dropdown-item @click.native="logout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></div>
</template><style scoped></style>
<script>export default{name:"AppHeader",methods:{toUser() {console.log('to_user')},logout(){console.log('logout')},}}
</script>

十四、菜单导航页面伸缩

伸缩的思路:图标和文字,收起和展开是有变量的,根据element的官方文档,对aside修改

两相对比,发现动画不太流畅影响观感 。

 并且header的选项,把信号跨组件给到aside,可以回去看看vue的多种跨组件方法吗?Vue跨组件通信8种方式汇总
 可以直接使用全局事件总线快很多,这里提供一个不太好的方法(很卡):header点击图标---提交--->父组件--改变-->aside子组件(collapse)

IndexPage.vue

<template><el-container style="height: 100%; border: 1px solid #eee"><el-aside :width="aside_width" style="background-color: rgb(238, 241, 246);height: 100% ;margin-left:-1px"><AppAside :isCollapse="isCollapse"></AppAside></el-aside><el-container style="height: 100%"><el-header style="text-align: right; font-size: 12px ;height:100%;border-bottom: rgba(168,168,168,0.3) 1px solid"><AppHeader @doCollapse="doCollapse" :icon="icon"></AppHeader></el-header><el-main style="height: 100%"><AppMain></AppMain></el-main></el-container></el-container></template><style scoped>
.el-header {/*background-color:#B3C0D1;*/color: #333;line-height: 60px;
}
.el-main{padding:5px;
}
.el-aside {color: #333;
}
</style><script>
import AppAside from "@/components/AppAside.vue";
import AppHeader from "@/components/AppHeader.vue";
import AppMain from "@/components/AppMain.vue";
import appAside from "@/components/AppAside.vue";export default {name:"IndexPage",computed: {appAside() {return appAside}},components: {AppMain, AppHeader, AppAside},data(){return {isCollapse:false,aside_width:'200px',icon:'el-icon-s-fold'}},methods:{doCollapse(){console.log(11111)this.isCollapse =!this.isCollapseif(!this.isCollapse){//默认展开,你想写三目也行 this.isCollapse ===true?this.changeWidth="64px":this.changeWidth="200px"this.aside_width='200px'this.icon='el-icon-s-fold'}else{this.aside_width='62px'this.icon='el-icon-s-unfold'}}}
};
</script>

AppHeader.vue

<template><div style="display:flex;line-height:60px;"><div  style="cursor:pointer;"><i :class="icon" style="font-size:20px;vertical-align: middle;" @click="collapse"></i></div><div style="flex:1;text-align:center;font-size:27px;"><span>欢迎来到仓库管理系统</span></div><span>王小虎</span><el-dropdown trigger="click"><i class="el-icon-arrow-down" style="margin-left:5px;"></i><el-dropdown-menu slot="dropdown"><!--直接给图标加line-height:60px就居中了;加上height和line-height,让他们相等就可以让文本垂直居中;加垂直vertical-align: middle;应该就好了--><el-dropdown-item @click.native="toUser">个人中心</el-dropdown-item><el-dropdown-item @click.native="logout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></div>
</template><style scoped></style>
<script>export default{name:"AppHeader",props:{icon:String},methods:{toUser() {console.log('to_user')},logout(){console.log('logout')},collapse(){this.$emit('doCollapse')}}}
</script>

AppAside.vue

<template><el-menubackground-color="#545c64"text-color="#fff"active-text-color="#ffd04b"style="height:100vh;"default-active="/Home":collapse="isCollapse":collapse-transition="false"><el-menu-item index="/One"><i class="el-icon-s-home"></i><span slot="title">首页</span></el-menu-item><el-menu-item index="/Two"><i class="el-icon-s-flag"></i><span slot="title">导航一</span></el-menu-item><el-menu-item index="/Home"><i class="el-icon-s-opportunity"></i><span slot="title">导航二</span></el-menu-item></el-menu>
</template><style scoped></style>
<script>export default{name:"AppAside",data(){return{// isCollapse:false}},props:{isCollapse:Boolean}}
</script>

十五、axios的安装和处理跨域

 1.安装axios
npm install axios --save

在main.js全局引入axios

import axios from "axios";
Vue.prototype.$axios =axios;

跨域:解决SpringBoot跨域问题8种方法,含网关、-CSDN博客SpringBoot解决跨域的5种方式_springboot跨域-CSDN博客

package com.wms.common;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CorsConfig implements WebMvcConfigurer{@overridepublic void addCorsMappings(CorsRegistry registry){registry.addMapping("/**")//是否发送Cookie.allowCredentials(true)//放行哪些原始域.aliowedOriginPatterns("*").allowedMethods(new String[]{"GET","POST","PUT","DELETE"}).allowedHeaders("*").exposedHeaders("*");}
}

get使用        这个get前端写法已经过时了

this.$axios.get('http://localhost:8090/1ist').then(res=>{console.log(res)})

post使用

this.$axios.post('http://localhost:8091/user/1istP',()).then(res=>{
console.log(res)
})

将地址设置为全局,记得开mysql!!!!!!!!!!!!啊啊啊啊啊啊

实际上,跨域可以一个@CrossOrigin解决(@CrossOrigin使用场景要求(jdk1.8+,Spring4.2+)

 但是请在wms/src/main/java/com.wms/common新建CorConfig.java

package com.wms.common;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;// 案例 一
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")//是否发送Cookie.allowCredentials(true)//放行哪些原始域.allowedOriginPatterns("*").allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"}).allowedHeaders("*").exposedHeaders("*");}
}

 AppMain中

methods:{loadGet(){this.$axios.get('http://localhost:8090/user/list').then(res=>res.data).then(res=>{console.log(res)})}
},

 这个sql显示要在yml文件里加配置,可以搜mybatis控制台打印sql配置

请在pom中添加

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version> <!-- 请使用最新的版本号 --></dependency>

你可以将 StringUtil.isNotBlack(user.getName()) 替换为 StringUtils.isNotBlank(user.getName())。这样就可以正确地判断 user.getName() 是否既非 null 又不是空白字符串了。

 在main.js中添加,从而全局地址

Vue.prototype.$httpUrl='http://localhost:8090'

 this.$axios.get(this.$httpUrl+'/user/list').then(res=>res.data).then(res=>{可以把$httpUrl去掉,去用去拦截:这里就不这么搞了。

request.js可供选择使用,我就不用了Vue项目搭建常用的配置文件,request.js和vue.config.js_vue项目搭建常用的配置文件,request.js和vue.config.js-CSDN博客

// 1.引入axios
// 2.axios.create方法创建实例
// 3.使用实例对象创建请求拦截器
// 4.使用实例创建响应拦截器
// 5.export抛出实例对象
// 6.main.js中引入request文件对象
import axios from 'axios'
import store from '@/store/index'
const Server =axios.create({baseURL:'',timeout:3000
})
//使用Server创建请求拦截器
Server.interceptors.request.use(function(config){store.commit('setLoading',true) //设置loading效果return config;
},function(error){return Promise.reject(error)
})
//使用Server创建响应拦截器
Server.interceptors.response.use(function(response){console.log(response);//判断接口返回的数据成功,直接返回数据中data数据if(response.status == 200){setTimeout(() => {store.commit('setLoading',false) //设置loading效果}, 1000);return response.data;}return response;
},function(error){return Promise.reject(error);
});
export default Server

 UserController.java部分

//查询(模糊、匹配)@PostMapping("/listP")public List<User> listP(@RequestBody User user) {LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper();if(StringUtils.isNotBlank(user.getName())){lambdaQueryWrapper.like(User::getName, user.getName());}//lambdaQueryWrapper.like(User::getName, user.getName());//lambdaQueryWrapper.eq(User::getName, user.getName());//eq就是完全匹配return userService.list(lambdaQueryWrapper);}

Appmain.vue部分

<script>export default{name:"AppMain",/*其实是想改成MainComponent的*/data() {return {tableData: Array(10).fill(item)}},methods:{loadGet(){this.$axios.get(this.$httpUrl+'/user/list').then(res=>res.data).then(res=>{console.log(res)})},loadPost(){this.$axios.post(this.$httpUrl+'/user/listP',{}).then(res=>res.data).then(res=>{console.log(res)})}},beforeMount() {this.loadGet()}}
</script>

十六、列表展示

1.列表数据
2.用tag转换列
3.header-cell-style设置表头样式
4.加上边框
5.按钮(编辑、删除)
6.后端返回结果封装(Result)

 AppMain.vue的需修改

<template><el-table :data="tableData"><el-table-column prop="id" label="ID" width="60"></el-table-column><el-table-column prop="no" label="账号" width="120"></el-table-column><el-table-column prop="name" label="姓名" width="80"></el-table-column><el-table-column prop="age" label="年龄" width="80"></el-table-column><el-table-column prop="sex" label="性别" width="80"></el-table-column><el-table-column prop="roleId" label="角色" width="80"></el-table-column><el-table-column prop="phone" label="电话" width="120"></el-table-column><el-table-column prop="operate" label="操作"></el-table-column></el-table>
</template><style scoped></style><script>export default{name:"AppMain",/*其实是想改成MainComponent的*/data() {return {tableData:[]}},methods:{loadGet(){this.$axios.get(this.$httpUrl+'/user/list').then(res=>res.data).then(res=>{console.log(res)})},loadPost(){this.$axios.post(this.$httpUrl+'/user/listP',{}).then(res=>res.data).then(res=>{console.log(res)this.tableData=res})}},beforeMount() {this.loadPost()}}
</script>

这里我还报错了,改了loadPost才正确,这是tyqw的建议

从你的代码来看,问题可能出在以下几个方面:

1. **API 调用方式**:你在 `loadGet` 方法中使用了 GET 请求来获取用户列表,但在 `loadPost` 方法中使用了 POST 请求。如果你的后端 API 需要通过 POST 请求来获取用户列表,那么你应该只保留一个方法,并确保它正确地调用了后端接口。

2. **响应处理**:你需要将后端返回的数据赋值给 `tableData` 数组,以便在 Vue 组件中显示这些数据。目前,你只是打印了返回的数据,但没有将其赋值给 `tableData`。

3. **组件生命周期钩子**:你可以在 `mounted` 生命周期钩子中调用加载数据的方法,而不是在 `beforeMount` 中。这样可以确保 DOM 已经渲染完毕后再进行数据请求和更新。

4. **错误处理**:建议添加错误处理逻辑,以防止网络或服务器出现问题时导致应用崩溃。

以下是修改后的代码示例 

<template><el-table :data="tableData"><!-- ... --></el-table>
</template><script>
export default {name: "AppMain",data() {return {tableData: []};},mounted() {this.loadData();},methods: {loadData() {// 确保使用正确的 HTTP 方法(GET 或 POST)const method = 'POST'; // 根据实际需求选择 GET 或 POSTif (method === 'GET') {this.$axios.get(this.$httpUrl + '/user/list').then(response => {this.tableData = response.data;}).catch(error => {console.error('Error fetching data:', error);});} else if (method === 'POST') {this.$axios.post(this.$httpUrl + '/user/listP', {}).then(response => {this.tableData = response.data;}).catch(error => {console.error('Error fetching data:', error);});}}}
};
</script>

请注意以下几点:
- 将 `beforeMount` 改为 `mounted`。
- 在 `loadData` 方法中根据实际情况选择 GET 或 POST 请求。
- 将后端返回的数据直接赋值给 `tableData`。
- 添加错误处理逻辑。

这样应该可以帮助你解决“暂无数据”的问题。如果问题仍然存在,请检查后端 API 的 URL 是否正确以及返回的数据格式是否符合预期。

 2.用tag转换列

<template><el-table :data="tableData"><el-table-column prop="id" label="ID" width="60"></el-table-column><el-table-column prop="no" label="账号" width="120"></el-table-column><el-table-column prop="name" label="姓名" width="80"></el-table-column><el-table-column prop="age" label="年龄" width="80"></el-table-column><el-table-column prop="sex" label="性别" width="80"><template slot-scope="scope"><el-tag:type="scope.row.sex === 1 ?'primary':'success'"disable-transitions>{{scope.row.sex=== 1 ?'男':'女'}}</el-tag></template></el-table-column><el-table-column prop="roleId" label="角色" width="120"><template slot-scope="scope"><el-tag:type="scope.row.roleId === 0 ?'danger':(scope.row.roleId === 1 ?'primary':'success')"disable-transitions>{{scope.row.roleId === 0 ?'超级管理员':(scope.row.roleId === 1 ?'管理员':'用户')}}</el-tag></template></el-table-column><el-table-column prop="phone" label="电话" width="120"></el-table-column><el-table-column prop="operate" label="操作"></el-table-column></el-table>
</template>

可能会报错,idea又抽风了,进一步修改

<el-table-column prop="operate" label="操作"><el-button size="small" type="success">编辑</el-button><el-button size="small" type="danger">删除</el-button>
</el-table-column>

修改对应的Usercontroller.java,因为你是一个列表,查出来的数据就放进去就好

//查询(模糊、匹配)@PostMapping("/listP")public Result listP(@RequestBody User user) {LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper();if(StringUtils.isNotBlank(user.getName())){lambdaQueryWrapper.like(User::getName, user.getName());}//lambdaQueryWrapper.like(User::getName, user.getName());//lambdaQueryWrapper.eq(User::getName, user.getName());//eq就是完全匹配return Result.success(userService.list(lambdaQueryWrapper));}

重启后端服务WmsApplication,这时前端刷新后什么都没有是正常的,因为数据经过了一层封装,在AppMain中修改loadPost如下,对200进行判定,

loadPost(){this.$axios.post(this.$httpUrl+'/user/listP',{}).then(res=>res.data).then(res=>{console.log(res)if(res.code===200){this.tableData=res.data}else{alert('获取数据失败!请刷新页面')}})}

十七、分页查询 

1.页面加上分页代码
2.修改查询方法和参数
3.处理翻页、设置条数逻辑(注意一个问题)

部分AppMain.vue

.......................<el-table-column prop="operate" label="操作"><el-button size="small" type="success">编辑</el-button><el-button size="small" type="danger">删除</el-button></el-table-column></el-table><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage4":page-sizes="[2, 5, 10, 20, 50]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></div>
</template><style scoped></style><script>export default{name:"AppMain",/*其实是想改成MainComponent的*/data() {return {tableData:[],pageSize:10,pageNum:1,total:0}},methods:{loadGet(){this.$axios.get(this.$httpUrl+'/user/list').then(res=>res.data).then(res=>{console.log(res)})},loadPost(){this.$axios.post(this.$httpUrl+'/user/listPageC1',{pageSize:this.pageSize,pageNum:this.pageNum}).then(res=>res.data).then(res=>{console.log(res)if(res.code===200){this.tableData=res.datathis.total=res.total}else{alert('获取数据失败!请刷新页面')}})},handleSizeChange(val) {console.log(`每页 ${val} 条`);this.pageNum=1//这个错误是先翻到第二页在调页面条数,显示无数据this.pageSize=valthis.loadPost()},handleCurrentChange(val) {console.log(`当前页: ${val}`);this.pageNum=valthis.loadPost()}},beforeMount() {this.loadPost()}}
</script>

 QueryPageParam.java

private HashMap parma = new HashMap();

 UserController.vue

@PostMapping("/listPageC1")//public List<User>listPage(@RequestBody HashMap map){public Result listPageC1(@RequestBody QueryPageParam query) {HashMap param = query.getParam();String name = (String) param.get("name");System.out.println("name===" + (String) param.get("name"));Page<User> page = new Page();page.setCurrent(query.getPageNum());page.setSize(query.getPageSize());LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper();if(StringUtils.isNotBlank(name)&&!"null".equals(name)) {lambdaQueryWrapper.like(User::getName, name);}//IPage result=userService.pageC(page);IPage result=userService.pageCC(page,lambdaQueryWrapper);System.out.println("total=="+result.getTotal());return Result.success(result.getRecords(),result.getTotal());//提醒,listPageC1的return记得改}

十八、查询处理

1.查询的布局(包含查询、重置按钮)
2.输入框,在appmain.vue中如此

<template><div><div style="margin-left:5px"><el-input v-model="name" placeholder="请输入名字:" suffix-icon="el-icon-search" style="width:200px;"></el-input><el-button type ="primary" style="margin-left:5px" @click="loadPost">查询</el-button><el-button type="success">重置</el-button></div><el-table :data="tableData":header-cell-style="{background:'#e0ecf4',color:'#555'}"border>

main.js中如此

//Vue.use(ElementUI)
Vue.use(ElementUI,{size:'small'})

 查询要把数据传到后端去啊,loadpost需要传一个name过去啊,param是代表需要传的参数啊 。就是那个querypageparam一起封装的啊hashmap param想传什么传什么,

3下拉框
4.回车事件(查询)@keyup.enter.native
5.重置处理:新增

<el-input v-model="name" placeholder="请输入名字:" suffix-icon="el-icon-search" style="width:200px;"@keyup.enter.native="loadPost"></el-input><!--Vue3输入框回车事件用@change="loadPostPage",重置只需加 clearable属性--><el-select v-model="sex" filterableplacehoLder="请选择性别"><el-optionv-for="item in sexs":key="item.value":label="item.label":value="item.value"></el-option></el-select>
..................
..................
..................
export default{name:"AppMain",/*其实是想改成MainComponent的*/data() {return {tableData:[],pageSize:10,pageNum:1,total:0,name:'',sex:'',sexs:[{value:'1',label:'男'},{value:'0',label:'女'}],}},

可以优化,获取当前触发事件的dom的参数,再去执行axios请求,不然每次都要给后端发送一大堆数据 ,usercontroller部分如下

@PostMapping("/listPageC1")//public List<User>listPage(@RequestBody HashMap map){public Result listPageC1(@RequestBody QueryPageParam query) {HashMap param = query.getParam();String name = (String) param.get("name");//System.out.println("name===" + (String) param.get("name"));String sex = (String) param.get("sex");Page<User> page = new Page();page.setCurrent(query.getPageNum());page.setSize(query.getPageSize());LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper();if(StringUtils.isNotBlank(name)&&!"null".equals(name)) {lambdaQueryWrapper.like(User::getName, name);}if(StringUtils.isNotBlank(sex)) {lambdaQueryWrapper.eq(User::getSex, sex);}//IPage result=userService.pageC(page);IPage result=userService.pageCC(page,lambdaQueryWrapper);System.out.println("total=="+result.getTotal());return Result.success(result.getRecords(),result.getTotal());//提醒,listPageC1的return记得改}

 Appmain.vue

 <div style="margin-left:5px"><el-input v-model="name" placeholder="请输入名字:" suffix-icon="el-icon-search" style="width:200px;"@keyup.enter.native="loadPost"></el-input><!--Vue3输入框回车事件用@change="loadPostPage",重置只需加 clearable属性--><el-select v-model="sex" filterableplacehoLder="请选择性别" style="margin-left:5px"><el-optionv-for="item in sexs":key="item.value":label="item.label":value="item.value"></el-option></el-select><el-button type ="primary" style="margin-left:5px" @click="loadPost">查询</el-button><el-button type="success" @click="resetParam">重置</el-button><!--重置好像在input里面添加个clearable可以实现名字的清空;直接重置接post如何?--></div>
........................
..........................
..........................
.....................methods中添加这个
resetParam(){this.name=''this.sex=''},

你的代码已经相当不错了,但确实有一些地方可以优化。特别是关于减少不必要的数据传输,可以通过优化前端逻辑来实现。下面是几个建议:

1. **动态构建请求参数**:
   可以通过一个方法来动态构建要发送给后端的数据对象,这样可以确保只有用户实际更改过的字段才会包含在请求中。

2. **使用计算属性**:
   对于那些依赖于其他数据变化而变化的数据,可以考虑使用计算属性(computed properties),这可以帮助减少不必要的数据处理。

3. **事件委托**:
   虽然在这个例子中并不适用,但在某些情况下,使用事件委托可以减少DOM监听器的数量,提高性能。

4. **优化按钮操作**:
   你可以将`loadPost`方法的调用封装在一个新的方法中,以便更好地控制何时以及如何发送请求。

以下是根据上述建议对你的代码进行的一些优化: 

<template><div><div style="margin-left:5px"><el-input v-model="searchParams.name" placeholder="请输入名字:" suffix-icon="el-icon-search" style="width:200px;" @keyup.enter.native="fetchData"></el-input><el-select v-model="searchParams.sex" filterable placeholder="请选择性别" style="margin-left:5px"><el-optionv-for="item in sexs":key="item.value":label="item.label":value="item.value"></el-option></el-select><el-button type="primary" style="margin-left:5px" @click="fetchData">查询</el-button><el-button type="success" @click="resetParams">重置</el-button></div><el-table :data="tableData" :header-cell-style="{background:'#e0ecf4',color:'#555'}" border><!-- 表格列定义保持不变 --></el-table><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-sizes="[2, 5, 10, 20, 50]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></div>
</template><script>
export default {name: "MainComponent",data() {return {tableData: [],pageSize: 10,pageNum: 1,total: 0,searchParams: {name: '',sex: ''},sexs: [{ value: '1', label: '男' },{ value: '0', label: '女' }]};},methods: {fetchData() {const params = {pageSize: this.pageSize,pageNum: this.pageNum,...this.searchParams // 展开搜索参数对象};// 过滤掉值为空的参数,避免向后端发送多余的数据const filteredParams = Object.fromEntries(Object.entries(params).filter(([_, v]) => v !== '' && v !== null));this.$axios.post(this.$httpUrl + '/user/listPageC1', filteredParams).then(res => res.data).then(res => {if (res.code === 200) {this.tableData = res.data;this.total = res.total;} else {alert('获取数据失败!请刷新页面');}});},resetParams() {this.searchParams.name = '';this.searchParams.sex = '';},handleSizeChange(val) {this.pageSize = val;this.pageNum = 1; // 切换每页数量时重置页码为第一页this.fetchData();},handleCurrentChange(val) {this.pageNum = val;this.fetchData();}},beforeMount() {this.fetchData();}
};
</script>

主要改动点:

  • - 将查询条件集中管理到 `searchParams` 对象中,便于管理和传递。
  • - 在 `fetchData` 方法中,通过解构赋值和过滤,只发送非空的查询参数给后端。
  • - 使用 `fetchData` 方法统一处理数据加载,简化了代码逻辑。
  • - 修改组件名为 `MainComponent`,符合你的需求。

这些改动应该能帮助你减少不必要的数据传输,并使代码更加简洁高效。

十九、新增

1.新增按钮

2.弹出窗口,添加对centerDialogVisible的判定,以及弹窗

 <el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage4":page-sizes="[2, 5, 10, 20, 50]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination><el-dialogtitle="提示":visible.sync="centerDialogVisible"width="30%"center><span>需要注意的是内容是默认不居中的</span><span slot="footer" class="dialog-footer"><el-button @click="centerDialogVisible=false">取消</el-button><el-button type="primary" @click="centerDialogVisible=false">确定</el-button></span></el-dialog></div>
</template>.................
..................
..................
sexs: [{value: '1',label: '男'}, {value: '0',label: '女'}],centerDialogVisible: false}},methods: {add() {this.centerDialogVisible = true},

3.编写表单vue项目表单中使用resetFields()报错或未生效-CSDN博客

4.提交数据(提示信息、列表刷新)

5.数据的检查

哎呦wc,一定一定一定要注意啊,from和form由于键盘手快打错了,找了我2hours的bug,cnm

AppMain.vue 

<template><div><div style="margin-left:5px"><el-input v-model="name" placeholder="请输入名字:" suffix-icon="el-icon-search" style="width:200px;"@keyup.enter.native="loadPost"></el-input><!--Vue3输入框回车事件用@change="loadPostPage",重置只需加 clearable属性--><el-select v-model="sex" filterable placehoLder="请选择性别" style="margin-left:5px"><el-optionv-for="item in sexs":key="item.value":label="item.label":value="item.value"></el-option></el-select><el-button type="primary" style="margin-left:5px" @click="loadPost">查询</el-button><el-button type="success" @click="resetParam">重置</el-button><!--重置好像在input里面添加个clearable可以实现名字的清空;直接重置接post如何?--><el-button type="primary" style="margin-left:5px" @click="add">新增</el-button></div><el-table :data="tableData":header-cell-style="{background:'#e0ecf4',color:'#555'}"border><el-table-column prop="id" label="ID" width="60"></el-table-column><el-table-column prop="no" label="账号" width="120"></el-table-column><el-table-column prop="name" label="姓名" width="80"></el-table-column><el-table-column prop="age" label="年龄" width="80"></el-table-column><el-table-column prop="sex" label="性别" width="80"><template slot-scope="scope"><el-tag:type="scope.row.sex === 1 ?'primary':'success'"disable-transitions>{{ scope.row.sex === 1 ? '男' : '女' }}</el-tag></template></el-table-column><el-table-column prop="roleId" label="角色" width="120"><template slot-scope="scope"><el-tag:type="scope.row.roleId === 0 ?'danger':(scope.row.roleId === 1 ?'primary':'success')"disable-transitions>{{ scope.row.roleId === 0 ? '超级管理员' : (scope.row.roleId === 1 ? '管理员' : '用户') }}</el-tag></template></el-table-column><el-table-column prop="phone" label="电话" width="120"></el-table-column><el-table-column prop="operate" label="操作"><el-button size="small" type="success">编辑</el-button><el-button size="small" type="danger">删除</el-button></el-table-column></el-table><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage4":page-sizes="[2, 5, 10, 20, 50]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination><el-dialogtitle="提示":visible.sync="centerDialogVisible"width="30%"center><el-form ref="form" :rules="rules" :model="form" label-width="80px"><el-form-item label="账号" prop="no"><el-col :span="20"><el-input v-model="form.no"></el-input></el-col></el-form-item><el-form-item label="密码" prop="password"><el-col :span="20"><el-input v-model="form.password"></el-input></el-col></el-form-item><el-form-item label="名字" prop="name"><el-col :span="20"><el-input v-model="form.name"></el-input></el-col></el-form-item><el-form-item label="年龄" prop="age"><el-col :span="20"><el-input v-model="form.age"></el-input></el-col></el-form-item><el-form-item label="性别"><el-radio-group v-model="form.sex"><el-radio label="1">男</el-radio><el-radio label="0">女</el-radio></el-radio-group></el-form-item><el-form-item label="电话" prop="phone"><el-col :span="20"><el-input v-model="form.phone"></el-input></el-col></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="centerDialogVisible=false">取消</el-button><el-button type="primary" @click="save">确定</el-button></span></el-dialog></div>
</template><style scoped></style><script>
export default {name: "AppMain",/*其实是想改成MainComponent的*/data() {let checkAge = (rule, value, callback) => {if (value > 150) {callback(new Error('年龄太大!lbd再来我让你飞起来!'));} else {callback();}};let checkDuplicate = (rule, value, callback) => {if (this.form.id) {return callback();}this.$axios.get(this.$httpUrl+"/user/findByNo?no=" + this.form.no).then(res=>res.data).then(res => {if (res.code!== 200) {//es6解构也可以callback();} else {callback(new Error('账号已经存在'));}});};return {tableData: [],pageSize: 10,pageNum: 1,currentPage4: 1, // 新增这一行来初始化 currentPage4 的值total: 0,name: '',sex: '',sexs: [{value: '1',label: '男'}, {value: '0',label: '女'}],centerDialogVisible: false,form: {name: '',no: '',age: '',password: '',phone: '',sex: '0',roleId: '2'},rules: {no: [{required: true, message: '请输入账号', trigger: 'blur'},{min: 3, max: 8, message: '长度在3-8个字符', trigger: 'blur'},{validator: checkDuplicate, trigger: 'blur'}],name: [{required: true, message: '请输入名字', trigger: 'blur'},],password: [{required: true, message: '请输入密码', trigger: 'blur'},{min: 4, max: 10, message: '长度在4-10个字符之间', trigger: 'blur'}],age: [{required: true, message: '请输入年龄', trigger: 'blur'},{min: 1, max: 3, message: '长度在1到3个位', trigger: 'blur'},{pattern: /^([1-9][0-9]*){1,3}$/, message: '年龄必须为正整数字', trigger: "blur"},{validator: checkAge, trigger: 'blur'}],phone: [{required: true, message: "手机号不能为空", trigger: "blur"},{pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur"}]}}},methods: {resetForm() {this.$refs.form.resetFields();},add() {this.centerDialogVisible = truethis.$nextTick(()=>{this.resetForm()})},save() {this.$refs.form.validate((valid) => {if (valid) {this.$axios.post(this.$httpUrl + '/user/save', this.form).then(res => res.data).then(res => {console.log(res)if (res.code === 200) {this.$message({message: '操作成功!',type: 'success'});this.centerDialogVisible = falsethis.loadPost();this.resetForm()} else {this.$message({message: '操作失败!请返回重新操作...',type: 'error'});}});} else {console.log('error submit!!');return false;}});},loadGet() {this.$axios.get(this.$httpUrl + '/user/list').then(res => res.data).then(res => {console.log(res)})},loadPost() {this.$axios.post(this.$httpUrl + '/user/listPageC1', {pageSize: this.pageSize,pageNum: this.pageNum,param: {name: this.name,sex: this.sex,}}).then(res => res.data).then(res => {console.log(res)if (res.code === 200) {this.tableData = res.datathis.total = res.total} else {alert('获取数据失败!请刷新页面')}})},resetParam() {this.name = ''this.sex = ''},handleSizeChange(val) {console.log(`每页 ${val} 条`);this.pageNum = 1//这个错误是先翻到第二页在调页面条数,显示无数据this.pageSize = val;this.loadPost();},handleCurrentChange(val) {console.log(`当前页: ${val}`);this.pageNum = valthis.loadPost();}},beforeMount() {this.loadPost()}
}
</script>

UserController.java部分 

 @GetMapping("/findByNo")public Result findByNo(@RequestParam String no) {List list=userService.lambdaQuery().eq(User::getNo, no).list();return list.size()>0?Result.success(list):Result.fail();}

编辑

<template><div><div style="margin-left:5px"><el-input v-model="name" placeholder="请输入名字:" suffix-icon="el-icon-search" style="width:200px;"@keyup.enter.native="loadPost"></el-input><!--Vue3输入框回车事件用@change="loadPostPage",重置只需加 clearable属性--><el-select v-model="sex" filterable placehoLder="请选择性别" style="margin-left:5px"><el-optionv-for="item in sexs":key="item.value":label="item.label":value="item.value"></el-option></el-select><el-button type="primary" style="margin-left:5px" @click="loadPost">查询</el-button><el-button type="success" @click="resetParam">重置</el-button><!--重置好像在input里面添加个clearable可以实现名字的清空;直接重置接post如何?--><el-button type="primary" style="margin-left:5px" @click="add">新增</el-button></div><el-table :data="tableData":header-cell-style="{background:'#e0ecf4',color:'#555'}"border><el-table-column prop="id" label="ID" width="60"></el-table-column><el-table-column prop="no" label="账号" width="120"></el-table-column><el-table-column prop="name" label="姓名" width="80"></el-table-column><el-table-column prop="age" label="年龄" width="80"></el-table-column><el-table-column prop="sex" label="性别" width="80"><template slot-scope="scope"><el-tag:type="scope.row.sex === 1 ?'primary':'success'"disable-transitions>{{ scope.row.sex === 1 ? '男' : '女' }}</el-tag></template></el-table-column><el-table-column prop="roleId" label="角色" width="120"><template slot-scope="scope"><el-tag:type="scope.row.roleId === 0 ?'danger':(scope.row.roleId === 1 ?'primary':'success')"disable-transitions>{{ scope.row.roleId === 0 ? '超级管理员' : (scope.row.roleId === 1 ? '管理员' : '用户') }}</el-tag></template></el-table-column><el-table-column prop="phone" label="电话" width="120"></el-table-column><el-table-column prop="operate" label="操作"><template slot-scope="scope"><el-button size="small" type="success" @click="mod(scope.row)">编辑</el-button><el-button size="small" type="danger" @click="del">删除</el-button></template></el-table-column></el-table><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage4":page-sizes="[2, 5, 10, 20, 50]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination><el-dialogtitle="提示":visible.sync="centerDialogVisible"width="30%"center><el-form ref="form" :rules="rules" :model="form" label-width="80px"><el-form-item label="账号" prop="no"><el-col :span="20"><el-input v-model="form.no"></el-input></el-col></el-form-item><el-form-item label="密码" prop="password"><el-col :span="20"><el-input v-model="form.password"></el-input></el-col></el-form-item><el-form-item label="名字" prop="name"><el-col :span="20"><el-input v-model="form.name"></el-input></el-col></el-form-item><el-form-item label="年龄" prop="age"><el-col :span="20"><el-input v-model="form.age"></el-input></el-col></el-form-item><el-form-item label="性别"><el-radio-group v-model="form.sex"><el-radio label="1">男</el-radio><el-radio label="0">女</el-radio></el-radio-group></el-form-item><el-form-item label="电话" prop="phone"><el-col :span="20"><el-input v-model="form.phone"></el-input></el-col></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="centerDialogVisible=false">取消</el-button><el-button type="primary" @click="save">确定</el-button></span></el-dialog></div>
</template><style scoped></style><script>
export default {name: "AppMain",/*其实是想改成MainComponent的*/data() {let checkAge = (rule, value, callback) => {if (value > 150) {callback(new Error('年龄太大!lbd再来我让你飞起来!'));} else {callback();}};let checkDuplicate = (rule, value, callback) => {if (this.form.id) {return callback();}this.$axios.get(this.$httpUrl+"/user/findByNo?no=" + this.form.no).then(res=>res.data).then(res => {if (res.code!== 200) {//es6解构也可以callback();} else {callback(new Error('账号已经存在'));}});};return {tableData: [],pageSize: 10,pageNum: 1,currentPage4: 1, // 新增这一行来初始化 currentPage4 的值total: 0,name: '',sex: '',sexs: [{value: '1',label: '男'}, {value: '0',label: '女'}],centerDialogVisible: false,form: {id:'',name: '',no: '',age: '',password: '',phone: '',sex: '0',roleId: '2'},rules: {no: [{required: true, message: '请输入账号', trigger: 'blur'},{min: 3, max: 8, message: '长度在3-8个字符', trigger: 'blur'},{validator: checkDuplicate, trigger: 'blur'}],name: [{required: true, message: '请输入名字', trigger: 'blur'},],password: [{required: true, message: '请输入密码', trigger: 'blur'},{min: 4, max: 10, message: '长度在4-10个字符之间', trigger: 'blur'}],age: [{required: true, message: '请输入年龄', trigger: 'blur'},{min: 1, max: 3, message: '长度在1到3个位', trigger: 'blur'},{pattern: /^([1-9][0-9]*){1,3}$/, message: '年龄必须为正整数字', trigger: "blur"},{validator: checkAge, trigger: 'blur'}],phone: [{required: true, message: "手机号不能为空", trigger: "blur"},{pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur"}]}}},methods: {resetForm() {this.$refs.form.resetFields();},del(){},mod(row){//this.form=row就可以了this.centerDialogVisible = truethis.$nextTick(()=>{this.form.id=row.id;this.form.no=row.no;this.form.name=row.name;this.form.sex=row.sex+'';this.form.age=row.age+'';//转化成字符串类型this.form.phone=row.phone;this.form.password='';this.form.roleId=row.roleId;})//修改User的时候要确保账号不能修改,否则有可能会数据库存在账号相同的情况!!!!给账号的input里加个v-bind:disabled="isDisabled“,如果是修改就把isDisabled设置为true,添加就false},add() {this.centerDialogVisible = truethis.$nextTick(()=>{this.resetForm()})},doSave(){this.$axios.post(this.$httpUrl + '/user/save', this.form).then(res => res.data).then(res => {console.log(res)if (res.code === 200) {this.$message({message: '操作成功!',type: 'success'});this.centerDialogVisible = falsethis.loadPost();this.resetForm()} else {this.$message({message: '操作失败!请返回重新操作...',type: 'error'});}});},doMod(){this.$axios.post(this.$httpUrl + '/user/update', this.form).then(res => res.data).then(res => {console.log(res);if (res.code == 200) {this.$message({message: '操作成功!',type: 'success'});this.centerDialogVisible = false;this.loadPost();this.resetForm();} else {this.$message({message: '操作失败!',type: 'error'});}});},save() {this.$refs.form.validate((valid) => {if (valid) {if(this.form.id){this.doMod();}else{this.doSave()}} else {console.log('error submit!!');return false;}});},loadGet() {this.$axios.get(this.$httpUrl + '/user/list').then(res => res.data).then(res => {console.log(res)})},loadPost() {this.$axios.post(this.$httpUrl + '/user/listPageC1', {pageSize: this.pageSize,pageNum: this.pageNum,param: {name: this.name,sex: this.sex,}}).then(res => res.data).then(res => {console.log(res)if (res.code === 200) {this.tableData = res.datathis.total = res.total} else {alert('获取数据失败!请刷新页面')}})},resetParam() {this.name = ''this.sex = ''},handleSizeChange(val) {console.log(`每页 ${val} 条`);this.pageNum = 1//这个错误是先翻到第二页在调页面条数,显示无数据this.pageSize = val;this.loadPost();},handleCurrentChange(val) {console.log(`当前页: ${val}`);this.pageNum = valthis.loadPost();}},beforeMount() {this.loadPost()}
}
</script>

UserController.java部分内容 

//新增@PostMapping("/save")public Result save(@RequestBody User user) {return userService.save(user)?Result.success():Result.fail();}//更新@PostMapping("/update")public Result update(@RequestBody User user) {return userService.updateById(user)?Result.success():Result.fail();}//修改User的时候要确保账号不能修改,否则有可能会数据库存在账号相同的情况!!!!给账号的input里加个v-bind:disabled="isDisabled“,如果是修改就把isDisabled设置为true,添加就false//修改@PostMapping("/mod")public boolean mod(@RequestBody User user) {return userService.updateById(user);}//新增或修改@PostMapping("/saveOrMod")public boolean saveOrMod(@RequestBody User user) {return userService.saveOrUpdate(user);}

删除

<el-table-column prop="operate" label="操作"><template slot-scope="scope"><el-button size="small" type="success" @click="mod(scope.row)">编辑</el-button><el-popconfirmtitle="确定删除吗?"@confirm="del(scope.row.id)"style="margin-left:8px;"><el-button slot="reference" size="small" type="danger">删除</el-button></el-popconfirm></template></el-table-column></el-table>
..............................
..............................
..............................
methods: {resetForm() {this.$refs.form.resetFields();},del(id){this.$axios.get(this.$httpUrl + '/user/del?id='+id).then(res => res.data).then(res => {console.log(res)if (res.code === 200) {this.$message({message: '操作成功!',type: 'success'});this.loadPost();} else {this.$message({message: '操作失败!请返回重新操作...',type: 'error'});}});},mod(row){//this.form=row就可以了this.centerDialogVisible = truethis.$nextTick(()=>{this.form.id=row.id;this.form.no=row.no;this.form.name=row.name;this.form.sex=row.sex+'';this.form.age=row.age+'';//转化成字符串类型this.form.phone=row.phone;this.form.password='';this.form.roleId=row.roleId;})//修改User的时候要确保账号不能修改,否则有可能会数据库存在账号相同的情况!!!!给账号的input里加个v-bind:disabled="isDisabled“,如果是修改就把isDisabled设置为true,添加就false},
 //删除@GetMapping("/del")public Result del(@RequestParam String id) {return userService.removeById(id)?Result.success():Result.fail();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/477992.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows 软件之 FFmpeg

文章目录 前言1 FFmpeg 视频处理1.1 编解码1.2 其它视频编辑命令1.3 视频抽帧 2 FFmpeg 音频处理3 FFmpeg 图片处理3.1 编解码3.2 拼接图片3.3 图片合成视频 附录1&#xff1a;mediainfo.ps1 前言 FFmpeg 是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的…

Docker1:认识docker、在Linux中安装docker

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

MATLAB的addpath和rmpath函数增加或删除路径

在进行MBD建模开发时&#xff0c;模型生成代码时常需要加载一些其他的文件&#xff0c;例如代码生成模版文件cgt文件、模型所涉及的头文件&#xff0c;这个时候可以在模型的回调函数中使用addpath和rmpath函数加载和删除路径&#xff0c;例如设置模型的加载之前的回调函数在模型…

【FPGA开发】Vivado自定义封装IP核,绑定总线

支持单个文件的封装、整个工程的封装&#xff0c;这里用单个文件举例。 在文件工程目录下&#xff0c;自建一个文件夹&#xff0c;里面放上需要封装的verilog文件。 选择第三个&#xff0c;指定路径封装&#xff0c;找到文件所在目录 取个名&#xff0c;选择封装IP的路径 会…

前端速通(CSS)

1.CSS介绍 1.什么是CSS? CSS&#xff08;Cascading Style Sheets&#xff0c;层叠样式表&#xff09;是一种用于控制网页的外观和布局的样式表语言。它与HTML&#xff08;超文本标记语言&#xff09;紧密配合&#xff0c;负责页面元素的样式定义&#xff0c;如字体、颜色、尺…

Android 13 编译Android Studio版本的Launcher3

Android 13 Aosp源码 源码版本 Android Studio版本 Launcher3QuickStepLib (主要代码) Launcher3ResLib(主要资源) Launcher3IconLoaderLib(图片加载&#xff0c;冲突资源单独新建) 需要值得注意的是&#xff1a; SystemUISharedLib.jar 有kotlin和java下的&#xff0c;在 Lau…

idea添加版权信息

1、添加Copyright Profiles 打开Settings -> Editor -> Copyright -> Copyright Profiles -> 新增 Copyright (c) 【你的版权信息】 【开始年份】-${today.year}. All rights reserved.如&#xff1a; Copyright (c) by cwp 2024-${today.year}. All rights rese…

【计算机网络】多路转接之poll

poll也是一种linux中的多路转接方案(poll也是只负责IO过程中的"等") 解决&#xff1a;1.select的fd有上限的问题&#xff1b;2.每次调用都要重新设置关心的fd 一、poll的使用 int poll(struct pollfd *fds, nfds_t nfds, int timeout); ① struct pollfd *fds&…

【C语言】深入剖析 C 语言中数组与指针的紧密联系及高效应用

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;例一&#xff1a;指针偏移遍历数组1.1 代码回顾1.2 代码分析1.3 理论扩展&#xff1a;数组与指针的关系1.4 数组与指针的应用场景 &#x1f4af;例二&#xff1a;自定义…

基于SpringBoot的数据结构系统设计与实现(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

算法训练-双指针

双指针 leetcode392. 判断子序列 法一&#xff1a;动态规划 法二&#xff1a;双指针 leetcode876. 链表的中间结点 法一&#xff1a;链表数组 法二&#xff1a;快慢指针 leetcode160. 相交链表 法一&#xff1a;双指针 leetcode167. 两数之和 II - 输入有序数组 法一&…

零基础学指针(上)

系列文章目录 &#x1f388; &#x1f388; 我的CSDN主页:OTWOL的主页&#xff0c;欢迎&#xff01;&#xff01;&#xff01;&#x1f44b;&#x1f3fc;&#x1f44b;&#x1f3fc; &#x1f389;&#x1f389;我的C语言初阶合集&#xff1a;C语言初阶合集&#xff0c;希望能…

shell编程之sed

sed 是一种流编辑器&#xff0c;它是文本处理中非常有用的工具&#xff0c;能够完美的配合正则表达式使用&#xff0c;处理时&#xff0c;把当前处理的行存储在临时缓冲区中&#xff0c;称为模式空间&#xff0c;接着用sed 命令处理缓冲区中的内容&#xff0c;处理完成 后&…

一文学习开源框架OkHttp

OkHttp 是一个开源项目。它由 Square 开发并维护&#xff0c;是一个现代化、功能强大的网络请求库&#xff0c;主要用于与 RESTful API 交互或执行网络通信操作。它是 Android 和 Java 开发中非常流行的 HTTP 客户端&#xff0c;具有高效、可靠、可扩展的特点。 核心特点 高效…

多目标优化算法:多目标极光优化算法(MOPLO)求解ZDT1、ZDT2、ZDT3、ZDT4、ZDT6,提供完整MATLAB代码

一、极光优化算法 极光优化算法&#xff08;Polar Lights Optimization, PLO&#xff09;是2024年提出的一种新型的元启发式优化算法&#xff0c;它从极光这一自然现象中汲取灵感。极光是由太阳风中的带电粒子在地球磁场的作用下&#xff0c;与地球大气层中的气体分子碰撞而产…

【贪心算法第二弹——2208.将数组和减半的最小操作数】

1.题目解析 题目来源 2208.将数组和减半的最小操作数——力扣 测试用例 2.算法原理(贪心策略) 3.实战代码 class Solution { public:int halveArray(vector<int>& nums) {priority_queue<double> hash;double sum 0.0;for(auto e : nums){hash.push(e);sum …

2024最新python使用yt-dlp

2024最新python使用yt-dlp下载YT视频 1.获取yt的cookie1&#xff09;google浏览器下载Get cookies.txt LOCALLY插件2&#xff09;导出cookie 2.yt-dlp下载[yt-dlp的GitHub地址](https://github.com/yt-dlp/yt-dlp?tabreadme-ov-file)1&#xff09;使用Pycharm(2024.3)进行代码…

深入理解下oracle 11g block组成

深层次说&#xff0c;oracle数据库的最少组成单位应该是块&#xff0c;一般默认情况下&#xff0c;oracle数据库的块大小是8kb&#xff0c;其中存储着我们平常所需的数据。我们在使用过程中&#xff0c;难免会疑问道&#xff1a;“oracle数据块中到底是怎样组成的&#xff0c;平…

2024年12月Gesp七级备考知识点拾遗第一期(图的定义及遍历)

目录 总序言 知识点拾遗​编辑 度数 环 二叉树 图的遍历 深度优先 广度优先 连通与强连通 有什么不同 构成分别至少需要几条边&#xff08;易错题&#xff09;&#xff1f; 无向连通图 有向强连通图 完全图 什么是完全图 无向完全图最少边数 有向完全图最少边…

家庭智慧工程师:如何通过科技提升家居生活质量

在今天的数字化时代&#xff0c;家居生活已经不再只是简单的“住”的地方。随着物联网&#xff08;IoT&#xff09;、人工智能&#xff08;AI&#xff09;以及自动化技术的快速发展&#xff0c;越来越多的家庭开始拥抱智慧家居技术&#xff0c;将他们的家变得更加智能化、便捷和…