672d9096c1ea52db3c6dce3a6148ca86cc606296.svn-base 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <template>
  2. <div>
  3. <el-table :data="formatData" :row-style="showRow" v-bind="$attrs">
  4. <el-table-column v-if="columns.length===0" width="150">
  5. <template slot-scope="scope">
  6. <span v-for="space in scope.row._level" :key="space" class="ms-tree-space" />
  7. <span v-if="iconShow(0,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
  8. <i v-if="!scope.row._expanded" class="el-icon-plus" />
  9. <i v-else class="el-icon-minus" />
  10. </span>
  11. {{ scope.$index }}
  12. </template>
  13. </el-table-column>
  14. <el-table-column v-for="(column, index) in columns" v-else :key="column.value" :label="column.text" :width="column.width">
  15. <template slot-scope="scope">
  16. <span v-for="space in scope.row._level" v-if="index === 0" :key="space" class="ms-tree-space" />
  17. <span v-if="iconShow(index,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
  18. <i v-if="!scope.row._expanded" class="el-icon-plus" />
  19. <i v-else class="el-icon-minus" />
  20. </span>
  21. <el-checkbox-group v-if="Array.isArray(scope.row[column.value])" v-model="scope.row.selectchecked" @change="handleCheckedCitiesChange(scope.$index, scope.row,scope.row[column.option])">
  22. <el-checkbox v-for="(interset) in scope.row[column.value]" :key="interset.id" :label="interset.id">{{ interset.description }}</el-checkbox>
  23. </el-checkbox-group>
  24. <el-checkbox v-else-if="scope.row.type===1" v-model="scope.row.checkAll" :indeterminate="scope.row.isIndeterminate" @change="handleCheckAllChange(scope.$index, scope.row,scope.row[column.option])">{{ scope.row[column.value] }}</el-checkbox>
  25. <span v-else>{{ scope.row[column.value] }}</span>
  26. <el-checkbox v-if="scope.row[column.act]" v-model="scope.row.checkAll" :indeterminate="scope.row.isIndeterminate" @change="handleCheckAllChange1(scope.$index, scope.row,column.option)">{{ scope.row[column.act] }}</el-checkbox>
  27. </template>
  28. </el-table-column>
  29. <slot />
  30. </el-table>
  31. <footer>
  32. <el-button @click="getAuth">确定</el-button>
  33. </footer>
  34. </div>
  35. </template>
  36. <script>
  37. /**
  38. Auth: Lei.j1ang
  39. Created: 2018/1/19-13:59
  40. */
  41. import treeToArray from './eval'
  42. export default {
  43. name: 'TreeTable',
  44. props: {
  45. data: {
  46. type: [Array, Object],
  47. required: true
  48. },
  49. columns: {
  50. type: Array,
  51. default: () => []
  52. },
  53. evalFunc: Function,
  54. evalArgs: Array,
  55. expandAll: {
  56. type: Boolean,
  57. default: true
  58. }
  59. },
  60. computed: {
  61. // 格式化数据源
  62. formatData: function() {
  63. let tmp
  64. if (!Array.isArray(this.data)) {
  65. console.log(this.data, 'this.data')
  66. tmp = [this.data]
  67. } else {
  68. console.log(this.data, 'this.data')
  69. tmp = this.data
  70. }
  71. const func = this.evalFunc || treeToArray
  72. const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll]
  73. return func.apply(null, args)
  74. }
  75. },
  76. created() {
  77. this.defaultSelcet()
  78. },
  79. methods: {
  80. showRow: function(row) {
  81. const show = (row.row.parent ? (row.row.parent._expanded && row.row.parent._show) : true)
  82. row.row._show = show
  83. return show ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' : 'display:none;'
  84. },
  85. // 切换下级是否展开
  86. toggleExpanded: function(trIndex) {
  87. const record = this.formatData[trIndex]
  88. record._expanded = !record._expanded
  89. },
  90. // 图标显示
  91. iconShow(index, record) {
  92. return (index === 0 && record.children && record.children.length > 0)
  93. },
  94. handleCheckAllChange(index, row, opt) {
  95. console.log(index, row, opt)
  96. this.cc()
  97. if (row.selectchecked.length && row.selectchecked.length !== opt.length) {
  98. const arr = []
  99. opt.forEach(element => {
  100. arr.push(element.id)
  101. })
  102. row.selectchecked = arr
  103. row.checkAll = true
  104. row.isIndeterminate = false
  105. } else if (!row.selectchecked.length) {
  106. const arr = []
  107. opt.forEach(element => {
  108. arr.push(element.id)
  109. })
  110. row.selectchecked = arr
  111. row.checkAll = true
  112. row.isIndeterminate = false
  113. } else {
  114. row.selectchecked = []
  115. row.checkAll = false
  116. row.isIndeterminate = false
  117. }
  118. },
  119. handleCheckedCitiesChange(index, row, opt) {
  120. row.checkAll = row.selectchecked.length === opt.length
  121. row.isIndeterminate = row.selectchecked.length > 0 && row.selectchecked.length < opt.length
  122. this.cc()
  123. },
  124. handleCheckAllChange1(index, row, opt) {
  125. if (row.children) {
  126. row.children.forEach(val => {
  127. const arr = []
  128. if (row.checkAll) {
  129. val[opt].forEach(element => {
  130. arr.push(element.id)
  131. })
  132. val.selectchecked = arr
  133. val.checkAll = true
  134. val.isIndeterminate = false
  135. } else {
  136. val.selectchecked = []
  137. val.checkAll = false
  138. val.isIndeterminate = false
  139. }
  140. })
  141. }
  142. this.cc()
  143. },
  144. defaultSelcet() {
  145. this.data.forEach(val => {
  146. if (val.children) {
  147. val.children.forEach(el => {
  148. if (el.selectchecked.length && el.selectchecked.length !== el[this.columns[0].option].length) {
  149. el.isIndeterminate = true
  150. el.checkAll = false
  151. } else if (el.selectchecked.length && el.selectchecked.length === el[this.columns[0].option].length) {
  152. el.isIndeterminate = false
  153. el.checkAll = true
  154. } else {
  155. el.isIndeterminate = false
  156. el.checkAll = false
  157. }
  158. })
  159. this.cc()
  160. }
  161. })
  162. },
  163. cc() {
  164. this.data.forEach(val => {
  165. const checkAllArr = []
  166. const isIndeterminateArr = []
  167. if (val.children) {
  168. val.children.forEach(el => {
  169. checkAllArr.push(el.checkAll)
  170. isIndeterminateArr.push(el.isIndeterminate)
  171. })
  172. }
  173. if (new Set(checkAllArr).size === 1) { // && new Set(isIndeterminateArr).size !== 1
  174. if (checkAllArr[0] && isIndeterminateArr[0] === false) {
  175. val.isIndeterminate = false
  176. val.checkAll = true
  177. } else if (checkAllArr[0] && new Set(isIndeterminateArr).size !== 1) {
  178. val.isIndeterminate = false
  179. val.checkAll = true
  180. } else if (!checkAllArr[0] && new Set(isIndeterminateArr).size !== 1) {
  181. val.isIndeterminate = true
  182. val.checkAll = false
  183. } else if (!checkAllArr[0] && new Set(isIndeterminateArr).size === 1) {
  184. if (!isIndeterminateArr[0]) {
  185. val.isIndeterminate = false
  186. val.checkAll = false
  187. } else {
  188. val.isIndeterminate = true
  189. val.checkAll = false
  190. }
  191. } else {
  192. val.isIndeterminate = false
  193. val.checkAll = false
  194. }
  195. } else {
  196. val.isIndeterminate = true
  197. val.checkAll = false
  198. }
  199. })
  200. },
  201. getAuth() {
  202. this.$emit('getAuth', this.data)
  203. }
  204. }
  205. }
  206. </script>
  207. <style rel="stylesheet/css">
  208. @keyframes treeTableShow {
  209. from {opacity: 0;}
  210. to {opacity: 1;}
  211. }
  212. @-webkit-keyframes treeTableShow {
  213. from {opacity: 0;}
  214. to {opacity: 1;}
  215. }
  216. .el-table__body{
  217. text-align: left;
  218. }
  219. </style>
  220. <style lang="scss" rel="stylesheet/scss" scoped>
  221. footer{
  222. display: flex;
  223. justify-content: flex-end;
  224. margin-top: 15px;
  225. }
  226. $color-blue: #2196F3;
  227. $space-width: 18px;
  228. .ms-tree-space {
  229. position: relative;
  230. top: 1px;
  231. display: inline-block;
  232. font-style: normal;
  233. font-weight: 400;
  234. line-height: 1;
  235. width: $space-width;
  236. height: 14px;
  237. &::before {
  238. content: ""
  239. }
  240. }
  241. .processContainer{
  242. width: 100%;
  243. height: 100%;
  244. }
  245. table td {
  246. line-height: 26px;
  247. }
  248. .tree-ctrl{
  249. position: relative;
  250. cursor: pointer;
  251. color: $color-blue;
  252. margin-left: -$space-width;
  253. }
  254. </style>