index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. <template>
  2. <div class="TableView">
  3. <el-table
  4. class="elTable"
  5. ref="dataTable"
  6. :data="tableData"
  7. border
  8. size="mini"
  9. highlight-current-row
  10. @selection-change="selectLine"
  11. @current-change="handleCurrentChange"
  12. @sort-change="changeSort"
  13. @row-dblclick="rowdblclick"
  14. :header-row-style="{ height: +this.GLOBAL.MAX_HEADER_H + 'px' }"
  15. :header-cell-style="{
  16. padding: '0px',
  17. background: '#f6f6f6',
  18. color: '#6c6c6c'
  19. }"
  20. :row-style="{ height: +this.GLOBAL.MAX_ROW_H + 'px' }"
  21. :cell-style="{ padding: '0px' }"
  22. row-key="id"
  23. :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
  24. >
  25. <!-- :height="height" 多选框 -->
  26. <el-table-column
  27. v-if="showSelect"
  28. type="selection"
  29. width="50"
  30. align="center"
  31. :selectable="checkboxT"
  32. ></el-table-column>
  33. <el-table-column type="expand" v-if="isExpand">
  34. <template slot-scope="scope">
  35. <slot name="expand" :data="scope" />
  36. </template>
  37. </el-table-column>
  38. <el-table-column
  39. label="序号"
  40. type="index"
  41. width="70px"
  42. align="center"
  43. v-if="isSerial"
  44. >
  45. <template slot-scope="scope">
  46. <span>{{ (currentPage - 1) * pageSize + scope.$index + 1 }}</span>
  47. </template>
  48. </el-table-column>
  49. <!-- 文本数据渲染 -->
  50. <template v-for="item in tableHead">
  51. <!--自定义列 操作模块 fixed="right" -->
  52. <el-table-column
  53. v-if="item.columnType == 'operation' && item.isShow"
  54. :prop="item.prop"
  55. :label="item.label"
  56. :key="item.prop"
  57. :min-width="item.minWidth"
  58. :width="item.width"
  59. :align="item.align || 'center'"
  60. fixed="right"
  61. >
  62. <template slot-scope="scope">
  63. <slot :name="item.slotName" :data="scope" />
  64. </template>
  65. </el-table-column>
  66. <!--自定义列 :sortable="sortable ? sortable :'custom' "-->
  67. <el-table-column
  68. :show-overflow-tooltip="item.tooltip == null ? true : item.tooltip"
  69. v-else-if="item.columnType == 'slot' && item.isShow"
  70. :prop="item.prop"
  71. :label="item.label"
  72. :key="item.prop"
  73. :min-width="item.minWidth"
  74. :width="item.width"
  75. :align="item.align ? item.align : 'center'"
  76. :sortable="item.sortable == null ? false : item.sortable"
  77. >
  78. <template slot-scope="scope">
  79. <slot :name="item.slotName" :data="scope" />
  80. </template>
  81. </el-table-column>
  82. <!--普通文本 :sort-orders="['ascending', 'descending']" -->
  83. <el-table-column
  84. :show-overflow-tooltip="item.tooltip == null ? true : item.tooltip"
  85. v-else-if="item.isShow && !item.type && !item.columnType"
  86. :prop="item.prop"
  87. :label="item.label"
  88. :key="item.prop"
  89. :min-width="item.minWidth"
  90. :width="item.width"
  91. :align="item.align ? item.align : 'center'"
  92. :sortable="item.sortable == null ? false : item.sortable"
  93. ></el-table-column>
  94. <!--根据不同类型显示不同的输入框 可以是下拉选择 /按钮 /输入框 还可以自己定义更多 -->
  95. <el-table-column
  96. v-else-if="item.type && item.isShow && !item.columnType"
  97. :label="item.label"
  98. :key="item.prop"
  99. :min-width="item.minWidth"
  100. :width="item.width"
  101. :align="item.align ? item.align : 'center'"
  102. :sortable="item.sortable == null ? false : item.sortable"
  103. >
  104. <template slot-scope="scope">
  105. <el-select
  106. v-if="item.type == 'select'"
  107. size="mini"
  108. v-model="scope.row[item.prop]"
  109. @change="handleEdit(scope.$index, scope.row)"
  110. placeholder="请选择"
  111. value
  112. >
  113. <el-option
  114. v-for="option in item.data"
  115. :disabled="disabled"
  116. :value="option.name"
  117. :key="option.name"
  118. :label="option.name"
  119. />
  120. </el-select>
  121. <el-button
  122. v-else-if="item.type == 'btn'"
  123. :disabled="disabled"
  124. @click="onSelected(scope.$index, scope.row)"
  125. type="primary"
  126. size="mini"
  127. >{{ item.text }}</el-button
  128. >
  129. <el-input
  130. v-else-if="item.type == 'text'"
  131. size="mini"
  132. :disabled="item.disabled || disabled"
  133. v-model="scope.row[item.prop]"
  134. placeholder="请输入"
  135. @change="handleEdit(scope.$index, scope.row)"
  136. />
  137. <el-input
  138. v-only-number="{ min: 0, max: GLOBAL.MAX_PRICE, precision: 2 }"
  139. v-else-if="item.type == 'money'"
  140. size="mini"
  141. :disabled="item.disabled || disabled"
  142. v-model="scope.row[item.prop]"
  143. placeholder="请输入"
  144. @change="handleEdit(scope.$index, scope.row)"
  145. />
  146. <el-input-number
  147. v-onlyInt
  148. size="mini"
  149. v-else-if="item.type === 'number'"
  150. v-model="scope.row[item.prop]"
  151. :min="0"
  152. label="排序编号"
  153. @change="handleEdit(scope.$index, scope.row)"
  154. ></el-input-number>
  155. <!-- <span>{{scope.row[item.prop]}}</span> -->
  156. </template>
  157. </el-table-column>
  158. </template>
  159. </el-table>
  160. <div class="paginationInfo" v-show="pageShow">
  161. <pagination
  162. ref="p"
  163. :page-size="pageRequest.pageSize"
  164. :total="total"
  165. :current-page="pageRequest.pageIndex"
  166. @changePage="changePage"
  167. @changePageSize="changePageSize"
  168. ></pagination>
  169. <div class="pool">{{ totalizeStr }}</div>
  170. </div>
  171. </div>
  172. </template>
  173. <script>
  174. import pagination from '@/components/pagination'
  175. export default {
  176. name: 'e-table',
  177. components: { pagination },
  178. /**
  179. * @name:
  180. * @test: test font
  181. * @msg:
  182. * @param {
  183. * 接收参数:
  184. * tableHeadConfig 列的名称、接收值 | Array
  185. * label 列的名称 | String
  186. * prop 列的对应值 | String
  187. * columnType 定义当前列为插槽 | slot | String
  188. * slotName 定义当前列插槽的名字 | String
  189. * width 定义当前列的宽度 | String
  190. * sortable 列的排序
  191. * isTime 列是否是时间
  192. * tooltip :false
  193. *
  194. * 示例:配置
  195. * tableHeadConfig:[
  196. * {
  197. * label : "缩略图",
  198. * prop : "skuName",
  199. * columnType : "slot",
  200. * slotName : "thumbnail",
  201. * width : 240
  202. * }
  203. * ]
  204. *
  205. * tableLoadData 异步获取的table文本数据信息
  206. * align 表格单元格内容排列顺序 left|center|right
  207. * showSelect 表格是否可多选
  208. * height 表格默认撑开高度(未用)
  209. * heightOffset 表格最大高度偏移量
  210. * pageShow 显示分页(默认显示)
  211. * pageSize 分页》 页条
  212. * total 分页》 总数
  213. * currentPage 分页 》当前页码
  214. * totalizeStr 合计说明处理
  215. * 事件:
  216. * 获取当前选中行
  217. * 调用页面用 @selectLine="xxx" 进行监听处理
  218. * 从后台获取数据,重新排序 changeSort
  219. * 双击行事件rowdblclick
  220. * 分页获取更改的页码 changePage
  221. * 分页获取更改条数/页 changePageSize
  222. * }
  223. * @return:
  224. */
  225. props: {
  226. tableHeadConfig: {
  227. type: Array,
  228. default: () => {
  229. return [
  230. {
  231. label: 'skuId',
  232. prop: 'skuId'
  233. },
  234. {
  235. label: '操作',
  236. columnType: 'slot',
  237. slotName: 'operation'
  238. }
  239. ]
  240. }
  241. },
  242. tableLoadData: {
  243. type: Array,
  244. default: () => {
  245. return []
  246. }
  247. },
  248. align: {
  249. type: String,
  250. default: 'center'
  251. },
  252. isSerial: {
  253. type: Boolean,
  254. default: true
  255. },
  256. isExpand: {
  257. type: Boolean,
  258. default: false
  259. },
  260. sortable: {
  261. type: Boolean,
  262. default: false
  263. },
  264. showSelect: {
  265. type: Boolean,
  266. default: false
  267. },
  268. height: {
  269. type: [Number, String],
  270. default: 50
  271. },
  272. heightOffset: {
  273. type: [Number, String],
  274. default: 150
  275. },
  276. isTime: {
  277. type: Boolean,
  278. default: false
  279. },
  280. pageShow: {
  281. type: Boolean,
  282. default: true
  283. },
  284. isDisabled: {
  285. type: Boolean,
  286. default: true
  287. },
  288. pageSize: {
  289. type: [Number, String],
  290. default: 10
  291. },
  292. total: {
  293. type: [Number, String],
  294. default: 0
  295. },
  296. currentPage: {
  297. type: Number,
  298. default: 1
  299. },
  300. totalizeStr: {
  301. type: String,
  302. default: ''
  303. },
  304. selectQuantity: {
  305. type: [String, Number],
  306. default: 0
  307. }
  308. },
  309. data() {
  310. return {
  311. selectList: [],
  312. disabled: false,
  313. // 分页信息
  314. pageRequest: {
  315. pageIndex: 1,
  316. pageSize: 10,
  317. sort: null,
  318. order: null
  319. }
  320. }
  321. },
  322. computed: {
  323. tableData() {
  324. return this.tableLoadData
  325. },
  326. tableHead() {
  327. return this.tableHeadConfig
  328. }
  329. },
  330. created() {},
  331. mounted() {},
  332. methods: {
  333. checkboxT(row, index) {
  334. return this.isDisabled
  335. },
  336. // 分页查询
  337. getPageList() {
  338. this.$emit('getPageList', this.pageRequest)
  339. },
  340. // 从后台获取数据,重新排序
  341. changeSort(val) {
  342. if (val) {
  343. this.pageRequest.pageIndex = 1
  344. this.pageRequest.sort = val.prop
  345. this.pageRequest.order = val.order
  346. this.getPageList()
  347. // console.log("排序的参数")
  348. this.$emit('changeSort', { sort: val.prop, order: val.order })
  349. }
  350. },
  351. // 分页获取更改的页码
  352. changePage(val) {
  353. this.pageRequest.pageIndex = val
  354. this.getPageList()
  355. this.$emit('changePage', val)
  356. },
  357. // 分页获取更改条数/页
  358. changePageSize(val) {
  359. this.pageRequest.pageSize = val
  360. this.pageRequest.pageIndex = 1
  361. this.getPageList()
  362. this.$emit('changePageSize', val)
  363. },
  364. //双击行事件
  365. rowdblclick(row, column) {
  366. if (row) {
  367. // this.$emit("rowdblclick", row);
  368. }
  369. },
  370. // 选择切换
  371. handleCurrentChange(val) {
  372. this.$emit('handleCurrentChange', val)
  373. },
  374. //选择
  375. selectLine(val) {
  376. this.selectList = val
  377. if (this.selectQuantity > 0) {
  378. if (this.selectList.length > this.selectQuantity) {
  379. // this.$refs.dataTable.clearSelection();
  380. // this.$refs.dataTable.toggleRowSelection(val[val.length-1]) ;
  381. // 截取前20位
  382. this.selectList = val.slice(0, this.selectQuantity)
  383. // 截取20位之后的数组 禁止选中
  384. let tempArr = val.slice(this.selectQuantity)
  385. if (tempArr.length !== 0) {
  386. tempArr.forEach(ele => {
  387. this.$refs.dataTable.toggleRowSelection(ele, false)
  388. })
  389. }
  390. this.$message.closeAll()
  391. this.$message.warning('只能请选择' + this.selectQuantity + '个')
  392. }
  393. }
  394. this.$emit('selectLine', this.selectList)
  395. // if (
  396. // this.$refs.dataTable.selection &&
  397. // this.$refs.dataTable.selection.length > 0
  398. // ) {
  399. // this.$emit('selectLine', this.$refs.dataTable.selection);
  400. // }
  401. },
  402. handleEdit(index, row) {
  403. this.$emit('handleEdit', { index: index, row: row })
  404. },
  405. onSelected: function (index, row) {
  406. this.$emit('onTableBtn', { index: index, row: row })
  407. }
  408. // this.$refs.dataTable.doLayout();
  409. }
  410. }
  411. </script>
  412. <style lang="less" scoped>
  413. .TableView .elTable {
  414. border: 1px solid #4bd198 !important;
  415. }
  416. .TableView .el-link {
  417. font-size: 12px !important;
  418. margin: 0 2px;
  419. }
  420. .TableView .el-table::before {
  421. height: 0 !important;
  422. }
  423. .TableView .elTable th {
  424. background: #f2f2f2 !important;
  425. }
  426. .TableView .elTable .cell {
  427. line-height: 40px !important;
  428. }
  429. .TableView .el-table__fixed-right::before,
  430. .TableView .el-table__fixed::before {
  431. height: 0 !important;
  432. }
  433. .paginationInfo {
  434. display: flex;
  435. justify-content: flex-end;
  436. border-top: 1px solid #e6e6e6;
  437. padding: 7px 0;
  438. margin-top: 10px;
  439. .pool {
  440. padding: 10px 10px;
  441. color: #6c6c6c;
  442. text-align: right;
  443. }
  444. }
  445. /*当表格选中的时候 会自动添加 .current-row 这些代码很好理解了*/
  446. .tb-edit .el-input,
  447. .tb-edit .el-input-number,
  448. .tb-edit .el-select {
  449. display: none;
  450. }
  451. .tb-edit .current-row .el-input.el-input-number,
  452. .tb-edit .current-row .el-select {
  453. display: block;
  454. }
  455. .tb-edit .current-row .el-input .el-input-number + span,
  456. .tb-edit .current-row .el-select + span {
  457. display: none;
  458. }
  459. </style>