JTreeTable.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <template>
  2. <a-table
  3. :rowKey="rowKey"
  4. :columns="columns"
  5. :dataSource="dataSource"
  6. v-bind="tableProps"
  7. @expand="handleExpand">
  8. <template v-for="(slotItem) of slots" :slot="slotItem" slot-scope="text, record, index">
  9. <slot :name="slotItem" v-bind="{text,record,index}"></slot>
  10. </template>
  11. </a-table>
  12. </template>
  13. <script>
  14. import {getAction} from '@/api/manage'
  15. export default {
  16. name: 'JTreeTable',
  17. props: {
  18. rowKey: {
  19. type: String,
  20. default: 'id'
  21. },
  22. // 根据什么查询,如果传递 id 就根据 id 查询
  23. queryKey: {
  24. type: String,
  25. default: 'parentId'
  26. },
  27. queryParams: {
  28. type: Object,
  29. default: () => {
  30. }
  31. },
  32. // 查询顶级时的值,如果顶级为0,则传0
  33. topValue: {
  34. type: String,
  35. default: null
  36. },
  37. columns: {
  38. type: Array,
  39. required: true
  40. },
  41. url: {
  42. type: String,
  43. required: true
  44. },
  45. childrenUrl: {
  46. type: String,
  47. default: null
  48. },
  49. tableProps: {
  50. type: Object,
  51. default: () => {
  52. }
  53. }
  54. },
  55. data() {
  56. return {
  57. dataSource: []
  58. }
  59. },
  60. computed: {
  61. getChildrenUrl() {
  62. if (this.childrenUrl) {
  63. return this.childrenUrl
  64. } else {
  65. return this.url
  66. }
  67. },
  68. slots() {
  69. let slots = []
  70. for (let column of this.columns) {
  71. if (column.scopedSlots && column.scopedSlots.customRender) {
  72. slots.push(column.scopedSlots.customRender)
  73. }
  74. }
  75. return slots
  76. }
  77. },
  78. watch: {
  79. queryParams: {
  80. deep: true,
  81. handler() {
  82. this.loadData()
  83. }
  84. }
  85. },
  86. created() {
  87. this.loadData()
  88. },
  89. methods: {
  90. /** 加载数据*/
  91. loadData(id = this.topValue, first = true, url = this.url) {
  92. let params = Object.assign({}, this.queryParams || {})
  93. params[this.queryKey] = id
  94. return getAction(url, params).then(res => {
  95. let dataSource = res.result.map(item => {
  96. // 判断是否标记了带有子级
  97. if (item.hasChildren === true) {
  98. // 定义默认展开时显示的loading子级,实际子级数据只在展开时加载
  99. let loadChild = {id: `${item.id}_loadChild`, name: 'loading...', isLoading: true}
  100. item.children = [loadChild]
  101. }
  102. return item
  103. })
  104. if (first) {
  105. this.dataSource = dataSource
  106. }
  107. return Promise.resolve(dataSource)
  108. })
  109. },
  110. /** 点击展开图标时触发 */
  111. handleExpand(expanded, record) {
  112. // 判断是否是展开状态
  113. if (expanded) {
  114. // 判断子级的首个项的标记是否是“正在加载中”,如果是就加载数据
  115. if (record.children[0].isLoading === true) {
  116. this.loadData(record.id, false, this.getChildrenUrl).then(dataSource => {
  117. // 处理好的数据可直接赋值给children
  118. if (dataSource.length === 0) {
  119. record.children = null
  120. } else {
  121. record.children = dataSource
  122. }
  123. })
  124. }
  125. }
  126. }
  127. }
  128. }
  129. </script>
  130. <style scoped>
  131. </style>