CrudTable.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <template>
  2. <div class="tab-container">
  3. <div class="tab-toolbar">
  4. <div class="tool-group">
  5. <el-button-group>
  6. <slot name="toolGroup"></slot>
  7. </el-button-group>
  8. </div>
  9. <slot name="toolMid"></slot>
  10. <div style="flex:1"></div>
  11. <el-icon class="is-loading" v-show="isLoading"><loading/></el-icon>
  12. <el-pagination
  13. v-model:current-page="pagination.currentPage"
  14. v-model:page-size="pagination.pageSize"
  15. :page-sizes="pageSizeOpts"
  16. :small="false"
  17. :disabled="false"
  18. :background="false"
  19. :layout="pageInfoOpts"
  20. :total="pagination.totalRows"
  21. />
  22. </div>
  23. <div class="tab-main">
  24. <el-table :data="tableDatas" style="width: 100%;height:100%;" border stripe highlight-current-row v-bind="$attrs">
  25. <slot name="tabColumns" :index-generate="indexGenerate"></slot>
  26. </el-table>
  27. </div>
  28. </div>
  29. </template>
  30. <script setup>
  31. import {reactive,ref,onMounted,toRaw,watch} from 'vue'
  32. import request from '../../utils/request'
  33. import { ElMessage } from "element-plus"
  34. const props=defineProps({
  35. pageSize:Number,
  36. pageSizeOpts:{
  37. type:Array,
  38. default:[10,20,50,100]
  39. },
  40. pageInfoOpts:String,
  41. url:String,
  42. datas:Array,
  43. initWhere:Object,
  44. autoLoad:{
  45. type:Boolean,
  46. default:true
  47. }
  48. })
  49. const pagination=reactive({
  50. currentPage:1,
  51. pageSize:props.pageSize||5,
  52. totalRows:0,
  53. pageCount:1,
  54. watchReload:true //通过监听器重载
  55. })
  56. const isLoading=ref(false)
  57. const tableDatas=ref([])
  58. onMounted(()=>{
  59. if(props.url&&props.autoLoad){
  60. query()
  61. }
  62. else{
  63. tableDatas.value=props.datas
  64. }
  65. })
  66. let _queryParam={}
  67. //只监听翻页、页size更改
  68. watch([
  69. ()=>pagination.currentPage,
  70. ()=>pagination.pageSize,
  71. ],
  72. ([newcp,newpz],[oldcp,oldpz])=>{
  73. if(pagination.watchReload){
  74. load(_queryParam)
  75. }
  76. })
  77. let getReqParam=(queryParams)=>{
  78. return Object.assign({},props.initWhere,toRaw(pagination),queryParams)
  79. }
  80. const getPageInfo=()=>{
  81. return toRaw(pagination)
  82. }
  83. const query=(queryParams)=>{
  84. pagination.watchReload=false
  85. pagination.currentPage=1 //新的查询页码重置为1,禁止通过监听自动查询,手动查询,便于外部接收查询状态
  86. return load(queryParams)
  87. }
  88. const load=async (queryParams)=>{
  89. //console.log('query...')
  90. isLoading.value=true
  91. try{
  92. let resp=await request({url: props.url,method: 'post',data: getReqParam(queryParams)})
  93. isLoading.value=false
  94. console.log(resp)
  95. pagination.watchReload=true
  96. //pagination.currentPage=resp.currentPage
  97. if(resp.code===0){
  98. tableDatas.value=resp.data.data
  99. pagination.totalRows=resp.data.totalRow
  100. pagination.pageCount = resp.data.pageCount
  101. _queryParam=queryParams||{}
  102. return 0
  103. }
  104. else{
  105. ElMessage.error(resp.msg||"加载数据失败");
  106. return -1
  107. }
  108. }
  109. catch (e) {
  110. pagination.watchReload=true
  111. isLoading.value=false
  112. ElMessage.error("加载数据失败");
  113. console.log(e)
  114. return -1
  115. }
  116. }
  117. const indexGenerate=(index)=>{
  118. return (pagination.currentPage-1) * pagination.pageSize + index + 1
  119. }
  120. defineExpose({
  121. query,
  122. getPageInfo
  123. })
  124. </script>
  125. <style scoped>
  126. .tab-container{
  127. height:100%;
  128. }
  129. .tab-toolbar{
  130. height:50px;
  131. padding:10px 10px;
  132. box-sizing: border-box;
  133. background-color: #f0f9ff;
  134. display: flex;
  135. justify-content:space-between;
  136. border:1px solid #e3f1f8;
  137. border-bottom:0px;
  138. }
  139. .tab-toolbar .is-loading{
  140. margin:8px 20px;
  141. }
  142. .tab-main{
  143. height: calc(100% - 50px);
  144. }
  145. </style>