基于后端MybatisPlus分页的vue前端页面代码实现

目录

后端相关代码

前端相关代码

效果


后端相关代码

Controller层

    @PostMapping
    public AjaxResult selectProduct(@RequestParam(defaultValue = "1")int pageNum, @RequestParam(defaultValue = "5")int pageSize, @RequestBody(required = false)ProductDTO productDTO){

        return AjaxResult.success(productService.selectProduct(pageNum,pageSize,productDTO));

    }

Service层

    @Override
    public IPage<Product> selectProduct(int pageNum, int pageSize, @Param("productDTO")ProductDTO productDTO) {
        Page<Product> page = new Page<>(pageNum, pageSize);
        // 非空判断
        if (productDTO == null) {
            productDTO = new ProductDTO();
        }
        page.setCurrent(pageNum);
        return productMapper.selectProduct(page,productDTO);
    }

Mapper层

@Mapper
public interface ProductMapper extends BaseMapper<Product> {
    IPage<Product> selectProduct(IPage<Product> page, @Param("productDTO")ProductDTO productDTO);
}

Mapper.xml

  <select id="selectProduct" resultType="com.zhan.springboot.springbootmybatis.pojo.Product">
      select *
      from springboot.product
      <where>
        <if test="productDTO.pid != null and productDTO.pid != ''">pid=#{productDTO.pid}</if>
        <if test="productDTO.pname != null and productDTO.pname != ''">And pname=#{productDTO.pname}</if>
        <if test="productDTO.price != null and productDTO.price != ''">And price=#{productDTO.price}</if>
      </where>
  </select>

Product

@AllArgsConstructor
@NoArgsConstructor
public class Product implements Serializable {


    private Integer pid;

    private String pname;

    private Double price;

    @TableField(value = "category_id")
    private String categoryId;

    private static final long serialVersionUID = 1L;

    public Integer getPid() {
        return pid;
    }

    public void setPid(Integer pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname == null ? null : pname.trim();
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(String categoryId) {
        this.categoryId = categoryId == null ? null : categoryId.trim();
    }
}

以上要求有相关数据库,sql语句如下:

-- auto-generated definition
create table product
(
    pid         int auto_increment
        primary key,
    pname       varchar(20) not null,
    price       double      null,
    category_id varchar(20) null
);

前端相关代码

基于Element-ui和axios

<template>
  <div>
    <el-table :data="productList" border>
      <el-table-column prop="pid" label="Product ID"></el-table-column>
      <el-table-column prop="pname" label="Product Name"></el-table-column>
      <el-table-column prop="price" label="Price"></el-table-column>
      <el-table-column prop="categoryId" label="Category ID"></el-table-column>
    </el-table>

    <el-pagination @size-change="handleSizeChange" 
                          @current-change="handleCurrentChange" 
                          :current-page-sync="currentPage" 
                          :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" 
                          :total="total">
    </el-pagination> 
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      productList: [],
      pageNum: 1,
			pageSize: 10,
      total: null
    };
  },
  created() {
    this.fetchProductList();
  },
  methods: {
    fetchProductList() {
      const params = {
        pageNum: this.pageNum,
        pageSize: this.pageSize
      };
      axios.post(`http://localhost:8080/product?pageNum=${params.pageNum}&pageSize=${params.pageSize}`)
        .then(response => {
          this.productList = response.data.records; 

          this.total = response.data.total;
        })
        .catch(error => {
          console.error('Error fetching product list:', error);
        });
    },
    // 分页处理方法

		handleSizeChange(val) {
			this.pageSize = val;
			this.fetchProductList();
			console.log(`每页 ${val} 条`);
		},
        //改变当前下标页的时触发,再调一遍接口
		handleCurrentChange(val) {
      this.pageNum = val;
			this.fetchProductList();
			console.log(`当前页: ${val}`);
			//主要 axios
		}

  }
};
</script>

注意这边要在main.js添加响应拦截:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import 'element-ui/lib/theme-chalk/index.css';
import ElementUI from "element-ui";
import axios from "axios";
 
Vue.config.productionTip = false;
Vue.prototype.$axios = axios;
 
Vue.use(ElementUI);
 
//------------------请求拦截-------------------//
axios.interceptors.request.use(config => {
  //例:若存在token则带token
  const token = store.state.token;
  if (token) {
      config.headers.Authorization = token
  }
  return config;
}, err => {
  console.log("请求拦截=>", err);
  return err;
})
 
//------------------响应拦截-------------------//
//-------------对响应数据做点什么-------------//
axios.interceptors.response.use(res => {
  console.log("响应拦截=>", res.data);
  //例:后端数据处理错误,并返回错误原因;前端获取错误原因并展示
  if (res.data.success == false) {
      Message({
          message: res.data.data.message + ',请重试!',
          type: 'warning'
      });
  }
  console.log("响应拦截=>", res);
  return res ? res.data : res;
}, err => {
  console.log(err);
  //打印完整的错误信息
  console.log("响应拦截错误完整信息=>",err.response)
  //也可以在这里对不同的错误码做不同的展示处理
  throw err;
})
 
 
new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

上面我没有作条件查询,因此没有传ProductDTO进去,相当于无条件查询,会列出所有的数据列表:

关键的请求代码是:

axios.post(`http://localhost:8080/product?pageNum=${params.pageNum}&pageSize=${params.pageSize}`)

params是请求体参数,如下定义:

      const params = {
        pageNum: this.pageNum,
        pageSize: this.pageSize
      };

当然加上条件查询的话,你还得加上一个VTO:

const productDTO = {
    // 根据需要设置其他的查询条件
};

这边要注意一个地方:设置请求头: 在发送请求时,确保设置适当的请求头,特别是Content-Type头,以指示后端请求体的格式。对于JSON格式的请求体,通常使用Content-Type: application/json

当然 如果每次请求都声明header未免太过麻烦,我们可以在main.js中设置,即作请求拦截器,整个代码示例如下:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import 'element-ui/lib/theme-chalk/index.css';
import ElementUI from "element-ui";
import axios from "axios";
 
Vue.config.productionTip = false;
Vue.prototype.$axios = axios;
 
Vue.use(ElementUI);
 
//------------------请求拦截-------------------//
axios.interceptors.request.use(config => {
  //例:若存在token则带token
  const token = store.state.token;
  config.headers['Content-Type'] = 'application/json';//这边声明了请求头类型
  if (token) {
      config.headers.Authorization = token
  }
  return config;
}, err => {
  console.log("请求拦截=>", err);
  return err;
})
 
//------------------响应拦截-------------------//
//-------------对响应数据做点什么-------------//
axios.interceptors.response.use(res => {
  console.log("响应拦截=>", res.data);
  //例:后端数据处理错误,并返回错误原因;前端获取错误原因并展示
  if (res.data.success == false) {
      Message({
          message: res.data.data.message + ',请重试!',
          type: 'warning'
      });
  }
  console.log("响应拦截=>", res);
  return res ? res.data : res;
}, err => {
  console.log(err);
  //打印完整的错误信息
  console.log("响应拦截错误完整信息=>",err.response)
  //也可以在这里对不同的错误码做不同的展示处理
  throw err;
})
 
 
new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

效果

前端设置了选择pagesize大小的功能:

 至此,一个最简单的前后端对接的例子完成,后续根据自己的需求拓展,例如文件上传、登录校验功能或增加条件查询的功能等

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜗牛变涡流

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值