StandardTable.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <template>
  2. <div class="standard-table">
  3. <div class="alert">
  4. <a-alert type="info" :show-icon="true">
  5. <div slot="message">
  6. 已选择&nbsp;<a style="font-weight: 600">{{ selectedRows.length }}</a>&nbsp;&nbsp;
  7. <template v-for="(item, index) in needTotalList" v-if="item.needTotal">
  8. {{ item.title }} 总计&nbsp;
  9. <a :key="index" style="font-weight: 600">
  10. {{ item.customRender ? item.customRender(item.total) : item.total }}
  11. </a>&nbsp;&nbsp;
  12. </template>
  13. <a style="margin-left: 24px" @click="onClearSelected">清空</a>
  14. </div>
  15. </a-alert>
  16. </div>
  17. <a-table
  18. :size="size"
  19. :bordered="bordered"
  20. :loading="loading"
  21. :columns="columns"
  22. :dataSource="current"
  23. :rowKey="rowKey"
  24. :pagination="pagination"
  25. :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: updateSelect }"
  26. >
  27. </a-table>
  28. </div>
  29. </template>
  30. <script>
  31. export default {
  32. name: "StandardTable",
  33. // props: ['bordered', 'loading', 'columns', 'data', 'rowKey', 'pagination', 'selectedRows'],
  34. props: {
  35. /**
  36. * 数据加载函数,返回值必须是 Promise
  37. * 默认情况下必须传递 data 参数;
  38. * 如果使用本地数据渲染表格,业务代码中将获取本地数据包装为 Promise 即可。
  39. *
  40. * currentData 用于向外暴露表格当前渲染的数据,
  41. * 业务开发中也可以直接修改 currentData,从而重新渲染表格(仅推荐用于客户端排序、数据过滤等场景)
  42. */
  43. data: {
  44. type: Function,
  45. required: true
  46. },
  47. dataSource: {
  48. type: Array,
  49. default () {
  50. return []
  51. }
  52. },
  53. columns: {
  54. type: Array,
  55. required: true
  56. },
  57. /* pagination: {
  58. type: Object,
  59. default () {
  60. return {}
  61. }
  62. },*/
  63. pageSize: {
  64. type: Number,
  65. default: 10
  66. },
  67. pageNum: {
  68. type: Number,
  69. default: 1
  70. },
  71. pageSizeOptions: {
  72. type: Array,
  73. default () {
  74. return ['10', '20', '30', '40', '50']
  75. }
  76. },
  77. responseParamsName: {
  78. type: Object,
  79. default () {
  80. return {}
  81. }
  82. },
  83. bordered: {
  84. type: Boolean,
  85. default: false
  86. },
  87. /**
  88. * 表格大小风格,default, middle, small
  89. */
  90. size: {
  91. type: String,
  92. default: 'default'
  93. },
  94. rowKey: {
  95. type: String
  96. },
  97. selectedRows: {
  98. type: Array
  99. }
  100. },
  101. data () {
  102. return {
  103. needTotalList: [],
  104. selectedRowKeys: [],
  105. loading: true,
  106. total: 0,
  107. pageNumber: this.pageNum,
  108. currentPageSize: this.pageSize,
  109. defaultCurrent: 1,
  110. sortParams: {},
  111. current: [],
  112. pagination: {},
  113. paramsName: {},
  114. }
  115. },
  116. created () {
  117. //数据请求参数配置
  118. this.paramsName = Object.assign(
  119. {},
  120. {
  121. pageNumber: "pageNo",
  122. pageSize: "pageSize",
  123. total: "totalCount",
  124. results: "data",
  125. sortColumns: "sortColumns"
  126. },
  127. this.responseParamsName
  128. );
  129. this.needTotalList = this.initTotalList(this.columns)
  130. // load data
  131. this.loadData( { pageNum: this.pageNumber } )
  132. },
  133. methods: {
  134. updateSelect (selectedRowKeys, selectedRows) {
  135. this.selectedRowKeys = selectedRowKeys
  136. let list = this.needTotalList
  137. this.needTotalList = list.map(item => {
  138. return {
  139. ...item,
  140. total: selectedRows.reduce((sum, val) => {
  141. return sum + val[item.dataIndex]
  142. }, 0)
  143. }
  144. })
  145. this.$emit('change', selectedRowKeys, selectedRows)
  146. },
  147. initTotalList (columns) {
  148. const totalList = []
  149. columns.forEach(column => {
  150. if (column.needTotal) {
  151. totalList.push({ ...column, total: 0 })
  152. }
  153. })
  154. return totalList
  155. },
  156. loadData (params) {
  157. let that = this
  158. that.loading = true
  159. params = Object.assign({}, params)
  160. const remoteParams = Object.assign({}, that.sortParams)
  161. remoteParams[that.paramsName.pageNumber] = params.pageNum || that.pageNumber
  162. remoteParams[that.paramsName.pageSize] = params.pageSize || that.currentPageSize
  163. if (params.pageNum) {
  164. that.pageNumber = params.pageNum
  165. }
  166. if (params.pageSize) {
  167. that.currentPageSize = params.pageSize
  168. }
  169. let dataPromise = that.data(remoteParams)
  170. dataPromise.then( response => {
  171. if (!response) {
  172. that.loading = false
  173. return
  174. }
  175. let results = response[that.paramsName.results]
  176. results = (results instanceof Array && results) || []
  177. that.current = results
  178. that.$emit("update:currentData", that.current.slice())
  179. that.$emit("dataloaded", that.current.slice())
  180. that.total = response[that.paramsName.total] * 1
  181. that.pagination = that.pager()
  182. that.loading = false
  183. }, () => {
  184. // error callback
  185. that.loading = false
  186. })
  187. },
  188. // eslint-disable-next-line
  189. onPagerChange (page, pageSize) {
  190. this.pageNumber = page
  191. this.loadData({ pageNum: page })
  192. },
  193. onPagerSizeChange (current, size) {
  194. this.currentPageSize = size
  195. /*
  196. if (current === this.pageNumber) this.loadData()
  197. console.log('page-size-change', current, size)
  198. */
  199. },
  200. onClearSelected () {
  201. this.selectedRowKeys = []
  202. this.updateSelect([], [])
  203. },
  204. pager () {
  205. return {
  206. total: this.total,
  207. showTotal: total => `共有 ${total} 条`,
  208. showSizeChanger: true,
  209. pageSizeOptions: this.pageSizeOptions,
  210. pageSize: this.pageSize,
  211. defaultCurrent: this.defaultCurrent,
  212. onChange: this.onPagerChange,
  213. onShowSizeChange: this.onPagerSizeChange
  214. }
  215. }
  216. },
  217. watch: {
  218. 'selectedRows': function (selectedRows) {
  219. this.needTotalList = this.needTotalList.map(item => {
  220. return {
  221. ...item,
  222. total: selectedRows.reduce( (sum, val) => {
  223. return sum + val[item.dataIndex]
  224. }, 0)
  225. }
  226. })
  227. }
  228. }
  229. }
  230. </script>
  231. <style scoped>
  232. .alert {
  233. margin-bottom: 16px;
  234. }
  235. </style>