图书管理系统前端—项目分析(二)

1.理解分页渲染

分析功能的实现: 1、总计条目以及每页条目数的动态传值 2、点击页码跳转 3、输入指定页码跳转

image-20230314224537682

1.1 分页组件(pagination)

<el-pagination background
               @size-change="自定义事件"
               @current-change="自定义事件"
               :page-size="10"
               layout="prev, pager, next, jumper, ->, total" 
               :total="500" >
</el-pagination>

常见属性

属性名称说明
small是否使用小型分页样式boolean(默认false)
background是否为分页按钮添加背景色boolean(默认false)
page-size每页显示条目个数,支持 .sync 修饰符number(默认10)
page-sizes每页显示个数选择器的选项设置number[] (默认[10, 20, 30, 40, 50, 100])
page-count总页数,total 和 page-count 设置任意一个就可以达到显示页码的功能;如果要支持 page-sizes 的更改,则需要使用 total 属性number
pager-count页码按钮的数量,当总页数超过该值时会折叠number(大于等于 5 且小于等于 21 的奇数,默认7)
current-page当前页数,支持 .sync 修饰符number(默认1)
layout组件布局,子组件名用逗号分隔String
total总条目数number
prev-text替代图标显示的上一页文字string
next-text替代图标显示的下一页文字string
disabled是否禁用boolean(默认false)
hide-on-single-page只有一页时是否隐藏boolean

layout属性值说明:

sizes, prev, pager, next, jumper, ->, total, slot(默认值 “prev, pager, next, jumper, ->, total”)

prev表示上一页,next为下一页,pager表示页码列表,->后的元素会靠右显示,jumper表示跳页元素,total表示总条目数,sizes用于设置每页显示的页码数量。

image-20230314222117697

常见事件

事件名称说明回调参数
size-changepageSize 改变时会触发每页条数
current-changecurrentPage 改变时会触发当前页
prev-click用户点击上一页按钮改变当前页后触发当前页
next-click用户点击下一页按钮改变当前页后触发当前页

◼ 学习更多:Pagination

1.2 使用分页组件

src > views > bookinfo > index.vue

<!--分页条(182~192行)-->
<el-pagination
        background
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page.sync="queryParam.page"
        :page-sizes="[5, 10, 20, 50]"
        :page-size="queryParam.limit"
        layout="total, sizes, prev, pager, next, jumper"
        :total="recordTotal"
        style="margin-top: 15px">
</el-pagination>

◼ 分析说明

  • background:设置分页组件背景颜色。
  • @size-change:在页面大小改变时触发的事件,将调用 handleSizeChange 函数来处理。
  • @current-change:在当前页面更改时触发的事件,将调用 handleCurrentChange 函数来处理。
  • :current-page.sync:用于绑定当前页码,同时允许双向数据绑定(特殊属性 sync 来实现双向绑定),即当页面数据发生更改时,该变量的值也会随之更改。
  • :page-sizes:指定分页组件可供选择的每页数据量选项,这里提供了 [5, 10, 20, 50] 四个选项。
  • :page-size:用于绑定当前每页显示的数据量。
  • layout:用于指定分页组件的布局方式,该属性值为一个字符串,其中不同部分之间用逗号分隔,可用的布局有:total(总条数),sizes(每页数据量选择器),prev(上一页按钮),pager(页码按钮),next(下一页按钮)和jumper(跳转输入框)。image-20230314222117697
  • :total:用于绑定总条数。
// methods
// 分页大小改变监听(237~245行)
handleSizeChange(curSize) {
    const params = this.queryParam
    params.limit = curSize  //修改分页记录的条数
    //向后台发起请求并获取响应对象res,调用 api>bookinfo 中的 queryBookInfosByPage 函数
    queryBookInfosByPage(params).then(res => {
        console.log('分页数据获取成功',res)
        this.tableData = res.data
        this.recordTotal = res.count
    })
},

// 点击分页监听方法(248~256行)
handleCurrentChange(curPage) {
    const params = this.queryParam
    params.page = curPage  //修改当前分页的序号
    //向后台发起请求并获取响应对象res,调用 api>bookinfo 中的 queryBookInfosByPage 函数
    queryBookInfosByPage(params).then(res => {
        console.log('分页数据获取成功',res)
        this.tableData = res.data
        this.recordTotal = res.count
    })
}

// data(478行)
tableData: [], // 表格数据
recordTotal: 0, // 记录总数
queryParam: { // 查询参数
    page: 1,   //当前分页的序号
    limit: 10,  //每个分页记录的条数
    bookname: null,
    bookauthor: null,
    booktypeid: null
}

src > api > bookinfo.js

// 向后端发起请求的API
// 分页查询图书信息(20~26行)
export function queryBookInfosByPage(params) {
    return request({
        url: '/bookInfo/queryBookInfosByPage', 
        method: 'get',
        params
    })
}

2.查询功能实现

模糊查询和查询全部的列表渲染

image-20230314224915349

src > views > bookinfo > index.vue

<div class="filter-container" style="margin-bottom: 15px">
    <!-- 书名输入 -->
    <el-input v-model="queryParam.bookname" placeholder="书名" style="width: 200px;" 
              class="filter-item" @keyup.enter.native="handleFilter" />
    <!-- 作者输入 -->
    <el-input v-model="queryParam.bookauthor" placeholder="作者" style="width: 200px;" 
              class="filter-item" @keyup.enter.native="handleFilter" />
    <!-- 类型选择 -->
    <el-select v-model="queryParam.booktypeid" filterable placeholder="类型" 
               clearable class="filter-item" style="width: 200px">
        <el-option v-for="item in typeData" :key="item.booktypeid" :label="item.booktypename" :value="item.booktypeid" />
    </el-select>
    <!-- 一些按钮 -->
    <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
        搜索
    </el-button>
    <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleShowAll">
        显示全部
    </el-button>
</div>
  • v-model:数据双向绑定

  • v-waves:自定义指令,该指令会在元素被点击时产生波纹效果。(src > directive > waveswaves.js=>实现波动效果;index.js=>注册到Vue中,并导出;waves.css=>提供样式)

  • 学习更多自定义指令

  • keyup.enter.native:表示监听回车键的keyup事件,.native表示监听原生的 DOM 事件而非 Vue 的封装事件。

// methods
// 搜索图书(259~267行)
handleFilter() {
    this.queryParam.page = 1
    //将发生改变的queryParam作为参数向后台请求并获取响应对象res
    queryBookInfosByPage(this.queryParam).then(res => {
        if(res.code = = = 0) {  //查询是否成功
            this.tableData = res.data
            this.recordTotal = res.count
        }
    })
},

// 显示全部(270~281行)
handleShowAll() {
    this.queryParam.page = 1
    //将queryParam中的书名、作者、类型设为null,实现查询全部
    this.queryParam.bookname = null
    this.queryParam.bookauthor = null
    this.queryParam.booktypeid = null
    //将初始化的queryParam作为参数向后台请求并获取响应对象res
    queryBookInfosByPage(this.queryParam).then(res => {
        if(res.code = = = 0) {  //查询是否成功
            this.tableData = res.data
            this.recordTotal = res.count
        }
    })
}

// data(478行)
tableData: [], // 表格数据
typeData: [], // 图书类型数据
recordTotal: 0, // 记录总数
queryParam: { // 查询参数
    page: 1,   //当前分页的序号
    limit: 10,  //每个分页记录的条数
    bookname: null,
    bookauthor: null,
    booktypeid: null
}

◼ 关于后端返回给前端的响应对象res

image-20230315111306091

◼ 关于data函数中tableData、recordTotal、typeData初始化:(216~228行)

◼ 使用created生命周期方法,在创建完成后执行。

image-20230315112516936

src > api > bookinfo.js

// 向后端发起请求的API
// 分页查询图书信息(20~26行)
export function queryBookInfosByPage(params) {
    return request({
        url: '/bookInfo/queryBookInfosByPage', 
        method: 'get',
        params
    })
}

3.Axios网络请求

1、Axios引入方式 2、请求封装 3、使用

3.1 axios自定义配置

◼ 可以使用自定义配置新建一个 axios 实例

import axios from 'axios'

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',   //基本URL,这样在发起请求时就不必重复指定相同的URL部分
  timeout: 1000,   //请求超时时间,如果请求在指定时间内没有得到响应,就会被取消
  headers: {'X-Custom-Header': 'foobar'}  //自定义的请求头
});

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
});

◼ 实例的方法

方法说明
request(config)允许发起自定义配置的任何类型的请求,它接受一个包含请求配置的对象(config)作为参数,并返回一个Promise
get(url[, config])用于发起HTTP GET请求,它接受一个URL字符串和一个可选的配置对象作为参数,并返回一个Promise
delete(url[, config])用于发起HTTP DELETE请求,它接受一个URL字符串和一个可选的配置对象作为参数,并返回一个Promise
head(url[, config])用于发起HTTP HEAD请求,它接受一个URL字符串和一个可选的配置对象作为参数,并返回一个Promise
post(url[, data[, config]])用于发起HTTP POST请求,它接受一个URL字符串、一个可选的请求数据对象和一个可选的配置对象作为参数,并返回一个Promise
put(url[, data[, config]])用于发起HTTP PUT请求,它接受一个URL字符串、一个可选的请求数据对象和一个可选的配置对象作为参数,并返回一个Promise
patch(url[, data[, config]])用于发起HTTP PATCH请求,它接受一个URL字符串、一个可选的请求数据对象和一个可选的配置对象作为参数,并返回一个Promise

◼ Promise将在请求完成时解析为响应

◼ axios请求的响应包含以下信息:

{
  // data 由服务器提供的响应
  data: {},

  // status HTTP 状态码
  status: 200,

  // statusText 来自服务器响应的 HTTP 状态信息
  statusText: "OK",

  // `headers 服务器响应的头
  headers: {},

  // config 是为请求提供的配置信息
  config: {}
}

◼ 关于配置对象config的属性介绍

属性说明
method请求的 HTTP 方法,例如 GET、POST 等。
url请求的 URL 地址。
headers请求头,可以自定义添加请求头信息。
params用于在 URL 中传递参数的对象,会被转换成查询字符串。
data用于在请求体中发送数据的对象或字符串。
timeout设置请求超时时间,单位为毫秒。
withCredentials是否携带跨域请求的凭证,默认为 false。

◼ 使用实例方法

import request from '@/utils/request'

function foo() {
    return request({
        url: 'request url',
        method: 'request mothod'
        ...
    })
}

◼ 学习更多:Axios

3.2 图数管理系统 —— Axios的导入&&请求的封装

src > utils > request.js

import axios from 'axios'   // 导入 Axios 库
import { Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// 创建axios实例
const service = axios.create({
  baseURL: 'http://localhost:8092/BookManager/', // url = base url + request url
  timeout: 5000 // request timeout
})

// 请求拦截器
service.interceptors.request.use(
    config => {
        // 在发送请求之前做一些操作
        if (store.getters.token) {
            //让每个请求携带令牌token
            //['X-Token']是自定义标头键
            //请根据实际情况修改
            config.headers['X-Token'] = getToken()
        }
        return config
    },
    error => {
        // 处理请求错误
        console.log(error) // for debug
        return Promise.reject(error)
    }
)

// 响应拦截器
service.interceptors.response.use(
    response => {
        // 对响应数据做一些操作
        const res = response.data
        return res
    },
    error => {
        // 处理响应错误
        console.log('err' + error) // for debug
        Message({
            message: error.message,
            type: 'error',
            duration: 5 * 1000
        })
        return Promise.reject(error)
    }
)

export default service
  • **import 语句:**用于导入需要的模块和函数。这里分别导入了 Axios 库、element-ui 中的 Message 组件、一个自定义的 store 对象以及一个名为 getToken 的自定义函数。
  • **axios.create() 方法:**用于创建一个 Axios 实例,其中的配置选项将应用于该实例的所有请求。在这个例子中,baseURL 设置为 http://localhost:8092/BookManager/,这意味着所有请求的 URL 都将以这个字符串为前缀。timeout 设置为 5000,表示如果请求超过 5 秒未返回,则请求将被中断。
  • **service.interceptors.request.use() 方法:**用于注册一个请求拦截器函数。这个函数将在每个请求发送之前被调用,用于检查是否存在 token 并将其添加到请求头中,以便在服务器端验证身份。如果请求发送时出现错误,请求拦截器将使用 Promise.reject() 将错误传递给响应拦截器。
  • **service.interceptors.response.use() 方法:**用于注册一个响应拦截器函数。这个函数将在每个响应被接收时被调用,用于检查响应数据中的状态码,如果存在错误,则会使用 Message 组件将错误信息显示在界面上。如果没有错误,则响应拦截器将解析响应并将其返回。
  • **export default service语句 :**将创建的 Axios 实例导出,以便在其他文件中使用该实例发送 HTTP 请求。
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值