58946ea071592041935b132e167f91703cb2c870.svn-base 6.5 KB

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