• 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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    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
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    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 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用

    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
  • 相关阅读:
    零宽空格引发的问题
    prosemirror 学习记录(四)decoration
    第5章 C语言高级的库函数
    最新 Kubernetes 集群部署 + Contranerd容器运行时 + flannel 网络插件(保姆级教程,最新 K8S 1.28.2 版本)
    Flink K8s Operator 如何提交flink SQL
    几个强力的nodejs库
    Mac虚拟机Parallels Desktop和VirtualBox哪个更适合?
    看完 2022 雷军年度演讲,我总结了我的故事
    TensorFlow 的基本概念和使用场景
    stl中vecter和pair组合达到字典的效果
  • 原文地址:https://blog.csdn.net/weixin_40639095/article/details/126409349