Vue3 分页

简介: Vue3 分页

组件


<template>
  <div :class="{ hidden: hidden }" class="pagination-container">
    <el-pagination
      :background="background"
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :page-sizes="pageSizes"
      :pager-count="5"
      :layout="layout"
      :total="total"
      v-bind="$attrs"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    >
      <span v-if="selected >= 0" class="text"> 已选择 {{ selected }} 条 </span>
    </el-pagination>
  </div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { scrollTo } from '@/utils/libs/scroll-to'
const props = defineProps({
  total: { type: Number, required: true },
  page: { type: Number, default: 1 },
  limit: { type: Number, default: 20 },
  pageSizes: { type: Array as PropType<Array<number>>, default: () => [10, 20, 30, 40, 50] },
  layout: { type: String, default: 'total , slot , -> ,  sizes, prev, pager, next, jumper ' },
  background: { type: Boolean, default: true },
  autoScroll: { type: Boolean, default: true },
  hidden: { type: Boolean, default: false },
  selected: { type: Number, default: 0 }
})
const childEmit = defineEmits(['update:page', 'update:limit', 'pagination'])
const currentPage = computed({
  get: () => props.page,
  set: (val) => {
    childEmit('update:page', val)
  }
})
const pageSize = computed({
  get: () => props.limit,
  set: (val) => {
    childEmit('update:limit', val)
  }
})
const handleSizeChange = (val) => {
  childEmit('pagination', { pageNum: currentPage, pageSize: val })
  if (props.autoScroll) scrollTo(0, 800)
}
const handleCurrentChange = (val) => {
  childEmit('pagination', { pageNum: val, pageSize: props.limit })
  if (props.autoScroll) scrollTo(0, 800)
}
</script>
<style lang="scss"></style>


hook


import { ref, reactive, nextTick } from 'vue'
export default function (
  ajaxRequest, // 请求接口
  multipleTable, // table ref
  paging, // 分页大小
  parameter, // 搜索参数
  multipleTableKey = '',
  isMultipleTable = false
) {
  const mixinsLoading = ref<boolean>(false)
  const tableData = ref([])
  const selectCodes = ref([]) // 选中的数据
  const originalData = ref(null) // 原始数据
  /* 集中处理筛选数据 */
  function filterFrom() {
    const para = JSON.parse(JSON.stringify(parameter.value))
    for (const key in para) {
      if (para[key] === '' || para[key] === null) delete para[key] // 如果属性为空 删除掉
    }
    parameter.value = para
    getList()
  }
  // 重新搜索
  function reload(parameters = {}) {
    paging.pageNum = 1
    parameter.value = parameters // 保证响应式
    filterFrom()
  }
  function handleCurrentChange(paging) {
    Object.assign(paging, paging)
    getList()
  }
  async function getList() {
    mixinsLoading.value = true
    parameter.value = Object.assign(parameter.value, paging)
    parameter.value.page = parameter.value.pageNum
    parameter.value.page_size = parameter.value.pageSize
    delete parameter.value.totalCount
    delete parameter.value.pageNum
    delete parameter.value.pageSize
    try {
      const { data } = await ajaxRequest(parameter.value)
      // const body = []
      originalData.value = data // 保持响应式
      tableData.value.length = 0
      for (const iterator of data?.datalist) {
        tableData.value.push(iterator)
      }
      paging.totalCount = +data?.total || 0
      if (isMultipleTable) {
        tableSelect()
      } else {
        mixinsLoading.value = false
      }
    } catch (err) {
      // console.log('err:', error)
      tableData.value.length = 0
      mixinsLoading.value = false
    }
  }
  /* 重置 */
  function reset(paramete = {}) {
    paging = reactive({ pageNum: 1, pageSize: 20, totalCount: 0 })
    for (const item in paramete) paramete[item] = ''
    parameter.value = paramete // 本地赋值
    filterFrom()
    selectCodes.value = []
  }
  // 表格勾选
  function tableSelect() {
    if (!tableData.value && !tableData.value.length) {
      mixinsLoading.value = false
      return
    }
    tableData.value.forEach((element) => {
      if (selectCodes.value.join().includes(element[multipleTableKey])) {
        nextTick(() => {
          multipleTable.value.toggleRowSelection(element, true)
        })
      }
    })
    mixinsLoading.value = false
  }
  return {
    mixinsLoading,
    selectCodes,
    originalData,
    tableData,
    handleCurrentChange,
    reload,
    reset
  }
}


param


import { ref, reactive } from 'vue'
export default function (
  tableRefVal,
  parameterVal,
  pagingVal = {
    pageNum: 1,
    pageSize: 20,
    totalCount: 0
  },
  paginationLayoutVal = 'total , slot , -> ,  sizes, prev, pager, next, jumper '
) {
  const tableRef = ref(tableRefVal) // table DOM
  const paging = reactive(pagingVal) // 分页大小
  const parameter = ref(parameterVal) // 查询参数
  const paginationLayout = paginationLayoutVal // 页码设置
  return { tableRef, paging, parameter, paginationLayout }
}


使用


<template>
  <div class="index-table pr-20px pl-20px">
    <list-pagination
      class="mt-20px"
      :total="paging.totalCount"
      v-model:page="paging.pageNum"
      v-model:limit="paging.pageSize"
      :layout="paginationLayoutVal"
      @pagination="handleCurrentChange"
    />
  </div>
</template>
<script setup lang="ts">
import ListPagination from '@/components/ListPagination/index.vue'
import useListPagination from '@/hooks/list-pagination/useListPagination'
import { onMounted } from 'vue'
import usePagParam from '@/hooks/list-pagination/usePagParam'
import { scanList } from '@/api/home'
import { TABLE_BORDER_RADIUS } from '@/config/style'
import tableHeightHook from '@/hooks/table-height/tableHeight'
const handleSelectionChange = () => {}
const { tableRef, paging, parameter } = usePagParam(null, {})
const paginationLayoutVal = 'total , -> ,  sizes, prev, pager, next, jumper '
let { mixinsLoading, tableData, handleCurrentChange, reload } = useListPagination(
  scanList,
  tableRef,
  paging,
  parameter
)
const topHeightValCom = tableHeightHook(tableRef) // 获取 table 的高度
onMounted(() => {
  reload() // 初始化数据
})
defineExpose({ reload }) // 共父组件使用
</script>
<style lang="scss" scoped>
.index-table {
  margin-top: 0;
  &__content {
    width: 100%;
    height: 200px;
  }
}
@mixin state-modify {
  height: 5px;
  width: 5px;
  border-radius: 50%;
  margin-right: 10px;
}
.modify-orange {
  @include state-modify;
  background: orange;
}
.modify-green {
  @include state-modify;
  background: green;
}
</style>
目录
相关文章
|
6天前
|
缓存 监控 UED
升级 Vue3 时,如何减少打包体积的增加?
升级 Vue3 时,如何减少打包体积的增加?
85 59
|
5天前
|
JavaScript
在vue3中(vite)引入unocss,安装配置unocss
在vue3中(vite)引入unocss,安装配置unocss
|
6天前
|
缓存 JavaScript 前端开发
「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系
该文章全面覆盖了Vue.js从基础知识到进阶原理的48个核心知识点,包括Vue CLI项目结构、组件生命周期、响应式原理、Composition API的使用等内容,并针对Vue 2与Vue 3的不同特性进行了详细对比与讲解。
「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系
|
6天前
|
API UED
如何实现Vue2项目升级Vue3?
如何实现Vue2项目升级Vue3?
13 1
|
8天前
|
JavaScript 前端开发 API
vue3的传送门teleport究竟有多神奇?suspense发起异步请求有多简约?
该文章介绍了Vue3中新特性Teleport和Suspense的使用方法,演示了如何使用Teleport进行DOM节点的非父子关系传送,以及Suspense在处理异步组件加载时的优雅展示和错误处理技巧。
|
8天前
|
JavaScript
particles 粒子背景插件在vue3中的使用
本文介绍了如何在Vue 3项目中使用`particles.vue3`库来创建粒子背景特效。文章提供了粒子背景插件的概述、安装步骤、配置参数说明,并展示了粒子特效的实现效果。同时,提供了在main.js中进行全局配置、在Vue组件中使用粒子背景组件的示例代码,以及完整代码的下载链接。
|
6天前
|
API UED
升级 Vue3 后,项目的打包体积会有什么变化?
升级 Vue3 后,项目的打包体积会有什么变化?
92 57
|
7天前
|
JavaScript API
再不学vue3就没有人要你了!速来围观vue3
这篇技术文章介绍了作者从最初对学习 Vue3 抵触到最终决定投入学习的心路历程,展示了 Vue3 相较于 Vue2 的诸多改进和新特性,如更优的性能、更小的代码体积及更佳的 TypeScript 支持。文章重点阐述了 Vue3 中 createApp 的使用变化、emits 机制、多事件处理、Fragment 的引入等重要功能升级。此外,还深入探讨了 Composition API 和 Options API 的区别,强调 Composition API 在代码组织和逻辑复用方面的优势,并给出了在不同项目规模中选择合适 API 的建议。
19 0
|
8天前
|
JavaScript 前端开发 UED
组件库实战 | 用vue3+ts实现全局Header和列表数据渲染ColumnList
该文章详细介绍了如何使用Vue3结合TypeScript来开发全局Header组件和列表数据渲染组件ColumnList,并提供了从设计到实现的完整步骤指导。
|
8天前
|
JavaScript API
模块化妙用!用vue3实现一个鼠标追踪器和异步加载组件
该文章展示了如何使用Vue3的Composition API实现鼠标追踪器功能,并介绍了创建异步加载组件的方法,利用TS泛型增强了组件的灵活性与可维护性。
下一篇
无影云桌面