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>
目录
相关文章
|
16天前
|
存储 JavaScript 前端开发
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
【10月更文挑战第21天】 vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
|
13天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
30 7
|
14天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
36 3
|
13天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
34 1
|
13天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
34 1
|
15天前
|
前端开发 JavaScript
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
|
16天前
Vue3 项目的 setup 函数
【10月更文挑战第23天】setup` 函数是 Vue3 中非常重要的一个概念,掌握它的使用方法对于开发高效、灵活的 Vue3 组件至关重要。通过不断的实践和探索,你将能够更好地利用 `setup` 函数来构建优秀的 Vue3 项目。
|
19天前
|
JavaScript API
vue3知识点:ref函数
vue3知识点:ref函数
29 2
|
19天前
|
API
vue3知识点:reactive函数
vue3知识点:reactive函数
24 1
|
19天前
|
JavaScript 前端开发 API
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
23 0