当前位置:   article > 正文

el-table表格封装(包括switch,操作栏,元素带点击事件,区分颜色显示,分页,暂无数据等)_el-table 封装

el-table 封装

效果图(字段较多,所以分段截图展示):

表格组件public-table.vue

  1. <template>
  2. <div class="public-table">
  3. <!-- 具体使用方法参考public-table-demo.vue -->
  4. <div class="list-table-cont">
  5. <div class="list-table">
  6. <el-table
  7. @selection-change="handleSelectionChange"
  8. :data="tableData"
  9. :stripe="false"
  10. :border="false"
  11. :fit="true"
  12. :show-header="true"
  13. :highlight-current-row="true"
  14. v-loading="columObj.loading"
  15. :row-class-name="tableRowClassName"
  16. class="public-table-cont"
  17. >
  18. <!-- 选择框是否开启,selectable控制是否单行禁用 -->
  19. <el-table-column
  20. v-if="columObj.selection"
  21. type="selection"
  22. :selectable="columObj.selectable"
  23. width="60"
  24. />
  25. <!-- 普通列 -->
  26. <el-table-column
  27. v-for="(column, columIndex) in columObj.columnData"
  28. :key="columIndex"
  29. :prop="column.prop"
  30. :label="column.label"
  31. :minWidth="column.width"
  32. :fixed="column.fixed"
  33. :align="column.align || 'left'"
  34. :sortable="column.sortable"
  35. :index="columIndex"
  36. show-overflow-tooltip
  37. >
  38. <template slot="header">
  39. {{ column.label }}
  40. <el-popover
  41. v-show="column.isQuestion"
  42. placement="top-start"
  43. title=""
  44. width="200"
  45. trigger="hover"
  46. :content="column.questionCont"
  47. >
  48. <i class="el-icon-question" slot="reference"></i>
  49. </el-popover>
  50. </template>
  51. <template slot-scope="{ row, $index }">
  52. <!-- 默认数据展示,类型为text:true -->
  53. <span
  54. v-if="column.text && column.editRow != $index"
  55. :style="`color:${column.textColor}`"
  56. >
  57. {{ row[column.prop] || '—' }}
  58. </span>
  59. <!-- 对象展示,类型为status:true -->
  60. <span v-if="column.status && row[column.prop]">{{
  61. row[column.prop].msg || '—'
  62. }}</span>
  63. <!-- 自定义内容,数据需要通过自己特殊处理的,类型为slot:true -->
  64. <slot v-if="column.slot" :name="row[column.prop]" :row="row">
  65. <span v-html="column.format(row, $index)"></span>
  66. </slot>
  67. <!-- 自定义格式返回,比如状态,时间拼接等,类型为ownDefined:true-->
  68. <span v-if="column.ownDefined" :style="column.formatColor && column.formatColor(row)">
  69. {{ column.format(row, $index) || '—' }}
  70. </span>
  71. <!--数据有点击事件,可进行点击跳转,弹框等操作,类型为clickable:true -->
  72. <span
  73. v-if="column.clickable"
  74. :class="column.textClass"
  75. @click="column.itemClick(row, $index)"
  76. class="click-style"
  77. >
  78. {{ column.format(row, $index) || '—' }}
  79. </span>
  80. <!-- 返回的数据是简单的数组,类型为isArray:true -->
  81. <span v-if="column.isArray">
  82. <span v-for="(item, index) in row[column.prop]" :key="index">
  83. {{ row[column.prop].length - 1 !== index ? item + ',' : item || '—' }}
  84. </span>
  85. </span>
  86. <!-- 既有默认的返回数据,又有自定义的可点击内容,类型为textClick:true -->
  87. <span v-if="column.textClick">
  88. <span>{{ row[column.prop] || '—' }}</span>
  89. <span class="blue-line">|</span
  90. ><span
  91. class="click-style"
  92. @click="column.itemClick(row, $index)"
  93. :class="column.textClass"
  94. >{{ column.textCont || '—' }}</span
  95. >
  96. </span>
  97. <!-- switch开关,打开时值为true ,关闭时值为false -->
  98. <el-switch
  99. v-if="column.switch"
  100. v-model="row[column.prop]"
  101. :inactive-text="row[column.prop] ? column.openText : column.closeText"
  102. @change="switchChange(row, $index)"
  103. />
  104. <!-- switch开关,打开时值为1 ,关闭时值为0 -->
  105. <el-switch
  106. v-if="column.switchNum"
  107. :active-value="1"
  108. :inactive-value="0"
  109. v-model="row[column.prop]"
  110. :inactive-text="row[column.prop] ? column.openText : column.closeText"
  111. @change="switchChange(row, $index)"
  112. />
  113. <!-- 单个图片展示,类型为image:true -->
  114. <div class="logo-box flex-column-center-center" v-if="column.image">
  115. <el-image
  116. class="logo"
  117. :class="column.imgStyle"
  118. :src="row[column.prop]"
  119. :preview-src-list="[row[column.prop]]"
  120. alt="图片"
  121. />
  122. </div>
  123. <!-- 图片数组 -->
  124. <div class="logo-box flex-column-center-center" v-if="column.imageArr">
  125. <el-image
  126. class="logo"
  127. :class="column.imgStyle"
  128. v-if="row[column.prop].length > 0"
  129. :src="row[column.prop][0]"
  130. :preview-src-list="row[column.prop]"
  131. alt="图片"
  132. />
  133. </div>
  134. <!-- 操作按钮 -->
  135. <span
  136. v-show="column.isOperation"
  137. v-for="(operations, index) in column.operation"
  138. :key="index"
  139. >
  140. <el-button
  141. :icon="operations.icon"
  142. :type="operations.type"
  143. @click="operations.buttonClick(row, $index)"
  144. :class="
  145. operations.format && operations.format(row)
  146. ? operations.disabledClass
  147. : operations.styleClass
  148. "
  149. :disabled="operations.format && operations.format(row)"
  150. size="small"
  151. >{{ operations.label }}</el-button
  152. >
  153. <span v-show="operations.dividerLine" class="divider-line">|</span>
  154. </span>
  155. </template>
  156. </el-table-column>
  157. <!-- 自定义操作栏,与isOperation不能同时存在-->
  158. <slot name="tableOperations"></slot>
  159. <!-- 暂无数据 -->
  160. <div slot="empty" class="empty">
  161. <img :src="`${ASSET_HOST}/event/activity_null.png`" />
  162. <span>暂无数据</span>
  163. </div>
  164. </el-table>
  165. </div>
  166. <!-- 分页 -->
  167. <!-- noPagination为true时不显示分页,默认为false,可不传此参数 -->
  168. <div class="pagination-panel flex-end" v-show="!columObj.noPagination">
  169. <div class="total-pages">
  170. <span>{{ pageObj.total }}</span> 条数据
  171. </div>
  172. <div class="total-pages" :style="{ textAlign: pageObj.position || 'center' }">
  173. <el-pagination
  174. @size-change="handleSizeChange"
  175. @current-change="handleCurrentChange"
  176. :current-page="pageObj.page"
  177. :page-size="pageObj.pageSize"
  178. layout="sizes, prev, pager, next,jumper"
  179. :total="pageObj.total"
  180. >
  181. </el-pagination>
  182. </div>
  183. </div>
  184. </div>
  185. </div>
  186. </template>
  187. <script>
  188. export default {
  189. name: 'public-table', //共用table组件
  190. directives: {
  191. // 自定义指令,用于可编辑input自动获取焦点
  192. focus: {
  193. inserted: function (e) {
  194. e.querySelector('input').focus();
  195. },
  196. },
  197. },
  198. props: {
  199. tableData: {
  200. type: Array,
  201. required: true,
  202. },
  203. columObj: {
  204. type: Object,
  205. required: true,
  206. },
  207. //columObj.type(如果为""空,就不会加载多选框,或者index编号),lazy(是否支持懒加载)
  208. //columnData.columType(列类型,可选text(默认为普通文字模式),input(input可编辑框),switch(switch开关),image(图片),operation(操作按钮))
  209. //prop(参数),label(列名),width(宽度),align(对齐方式),sortable(是否支持排序)
  210. //如果为操作列,则需要填写需要的操作按钮,类型为Objecttype(按钮样式,参考el—botton类型),label(按钮文字)icon(参考el-icon),color(字体颜色),buttonClick为点击后调用的方法名称
  211. pageObj: {
  212. type: Object,
  213. required: true,
  214. },
  215. },
  216. methods: {
  217. // switchChange调用
  218. switchChange(row, $index, prop) {
  219. this.$emit('switchChange', row, $index, prop);
  220. },
  221. // 帮助点击行,获取点击的下标
  222. tableRowClassName({ row, rowIndex }) {
  223. row.rowIndex = rowIndex;
  224. },
  225. // 选择的数据
  226. handleSelectionChange(val) {
  227. this.$emit("handleSelectionChange", val);
  228. },
  229. // 条数变化
  230. handleSizeChange(e) {
  231. this.$emit('handleSizeChange', e);
  232. },
  233. // 页码变化
  234. handleCurrentChange(e) {
  235. this.$emit('handleCurrentChange', e);
  236. },
  237. },
  238. };
  239. </script>
  240. <style lang='scss' scoped>
  241. .public-table {
  242. .el-button {
  243. margin: 0 6px;
  244. }
  245. .text-underline {
  246. text-decoration: underline;
  247. }
  248. .click-style {
  249. cursor: pointer;
  250. }
  251. .text-color {
  252. color: #0064ff;
  253. }
  254. .red-text {
  255. color: red !important;
  256. }
  257. .blue-text {
  258. color: rgba(0, 100, 255, 1) !important;
  259. }
  260. .disabled-text {
  261. color: #999 !important;
  262. }
  263. /deep/ .el-input__inner {
  264. border: none;
  265. }
  266. /deep/ .el-image__inner {
  267. height: 50px;
  268. }
  269. // switch左边文字颜色
  270. /deep/ .el-switch__label--left {
  271. color: #606266;
  272. }
  273. .flex-column-center-center {
  274. display: flex;
  275. flex-direction: column;
  276. align-items: center;
  277. justify-content: center;
  278. }
  279. .logo-box {
  280. width: 50px;
  281. height: 50px;
  282. /deep/.el-image__inner {
  283. height: auto !important;
  284. }
  285. .logo {
  286. width: 50px;
  287. height: 50px;
  288. display: inline-block;
  289. object-fit: cover;
  290. }
  291. .logo-style {
  292. height: 40px !important;
  293. }
  294. .logo-list-style {
  295. width: 80px !important;
  296. height: 80px !important;
  297. }
  298. }
  299. }
  300. </style>

public-table-demo.vue页面引用组件 

  1. <template>
  2. <div class="public-table-demo">
  3. <div class="public-table-demo-titles flex-between">
  4. <div class="public-table-demo-titles-left">封装表格使用示例</div>
  5. </div>
  6. <div class="public-table-demo-cont">
  7. <!-- 表格(直接复制这个组件到对应文件) -->
  8. <public-table
  9. :tableData="tableData"
  10. :columObj="columObj"
  11. :pageObj="pageObj"
  12. @switchChange="switchChange"
  13. @handleSelectionChange="handleSelectionChange"
  14. @handleSizeChange="handleSizeChange"
  15. @handleCurrentChange="handleCurrentChange"
  16. >
  17. <!-- 放开注释代码并删除columnData中的isOperation为true的操作列则为自定义操作栏 -->
  18. <!-- <div slot="tableOperations">
  19. <el-table-column prop="status" width="200" fixed="right" label="操作">
  20. <template slot-scope="scope">
  21. <el-button
  22. type="text"
  23. size="small"
  24. @click.native="editBanner(scope.row)"
  25. >编辑</el-button
  26. >
  27. </template>
  28. </el-table-column>
  29. </div> -->
  30. </public-table>
  31. </div>
  32. </div>
  33. </template>
  34. <script>
  35. export default {
  36. name: 'public-table-demo',
  37. components: {
  38. publicTable: () => import('@/components/common/public-table.vue'),
  39. },
  40. data() {
  41. return {
  42. tableData: [
  43. {
  44. cont: '普通数据',
  45. setColor: '设置为蓝色',
  46. isQuestion: '标题带问号',
  47. logo: 'https://tuoluohuodong.oss-cn-shang hai.aliyuncs.com/digital_system/tuoluoicon.png',
  48. logoList: [
  49. 'https://tuoluohuodong.oss-cn-shang hai.aliyuncs.com/digital_system/30841d9826d04081961102138d606ac3.jpeg',
  50. 'https://tuoluohuodong.oss-cn-shang hai.aliyuncs.com/digital_system/8e696633c92249ce806d417c26c630f5.jpeg',
  51. ],
  52. isOpenSwitch: true,
  53. isOpenSwitchNum: 0,
  54. status: 1,
  55. startTime: '2022-03-31 00:00:00',
  56. endTime: '2023-03-31 00:00:00',
  57. sex: 1,
  58. booth: null,
  59. exhibition: null,
  60. clickValue: '可点击跳转',
  61. productInfoVOList: [
  62. { id: '3523435726235345363', productSn: '419225611403', auditStatus: 1 },
  63. { id: '3523435726235345364', productSn: '673929573648', auditStatus: 2 },
  64. ],
  65. venueVal: ['B', 'C', 'C'],
  66. numDetail: 99,
  67. objmsg: {
  68. msg: '对象啊',
  69. },
  70. },
  71. {
  72. cont: '普通数据',
  73. setColor: '设置为蓝色',
  74. isQuestion: '标题带问号',
  75. logo: 'https://tuoluohuodong.oss-cn-shang hai.aliyuncs.com/digital_system/tuoluoicon.png',
  76. logoList: [
  77. 'https://tuoluohuodong.oss-cn-shang hai.aliyuncs.com/digital_system/d49e5941cc834a28ad0b3cd730bf01ea.jpg',
  78. 'https://tuoluohuodong.oss-cn-shang hai.aliyuncs.com/digital_system/b03a4a6605f540ae9148c008a7bc8193.jpg',
  79. ],
  80. isOpenSwitch: false,
  81. isOpenSwitchNum: 1,
  82. status: 2,
  83. startTime: '2022-03-01 12:00:00',
  84. endTime: '2023-03-01 18:00:00',
  85. sex: 2,
  86. booth: '展馆号',
  87. exhibition: '展位号',
  88. clickValue: '可点击跳转',
  89. productInfoVOList: [
  90. { id: '3578388750457094201', productSn: '019109210492', auditStatus: -1 },
  91. ],
  92. venueVal: ['A', 'C', 'D'],
  93. numDetail: 10,
  94. objmsg: {
  95. msg: '对象啊',
  96. },
  97. },
  98. ], //列表数据
  99. columObj: {
  100. selection: true, // 是否显示选择框
  101. // noPagination:true,//是否显示分页(为true不显示,默认显示分页则不需要此参数)
  102. /***
  103. * column列,
  104. * columType(列类型,可选text(默认为普通文字模式),
  105. * switch(switch开关,后台返回falsetrue),
  106. * switchNum(switch开关,后台返回01),
  107. * image(图片),
  108. * operation(操作按钮)
  109. * textColor(文本颜色,不传则是默认颜色)
  110. * ownDefined(自定义返回内容)
  111. * clickable(内容可点击操作)
  112. * isArray(数组)
  113. * textClick(又有普通内容又有可点击操作内容)
  114. ***/
  115. /***
  116. * prop(参数),
  117. * label(列名),
  118. * width(宽度),
  119. * align(对齐方式,默认左对齐),
  120. * sortable(是否支持排序)
  121. * format(自定义值)
  122. * formatColor(自定义值的颜色,需要则设置)
  123. * textClass(样式设置)
  124. * itemClick(内容点击事件)
  125. * textCont(有点击事件的固定内容)
  126. ***/
  127. columnData: [
  128. {
  129. text: true,
  130. prop: 'cont',
  131. label: '默认',
  132. width: '150',
  133. },
  134. {
  135. text: true,
  136. textColor: '#0064ff',
  137. prop: 'setColor',
  138. label: '设置颜色',
  139. width: '150',
  140. },
  141. {
  142. text: true,
  143. prop: 'isQuestion',
  144. label: '显示问号',
  145. width: '120',
  146. isQuestion: true, //是否显示问号tips
  147. questionCont: '提示内容啊啊', //问号显示的内容
  148. },
  149. {
  150. image: true,
  151. prop: 'logo',
  152. label: 'logo展示',
  153. width: '120',
  154. imgStyle: 'logo-style',
  155. },
  156. {
  157. imageArr: true,
  158. prop: 'logoList',
  159. label: '多张图',
  160. width: '120',
  161. imgStyle: 'logo-list-style',
  162. },
  163. {
  164. switch: true,
  165. prop: 'isOpenSwitch',
  166. label: 'switch按钮(后台返回false或true)',
  167. width: '300',
  168. },
  169. {
  170. switchNum: true,
  171. prop: 'isOpenSwitchNum',
  172. label: 'switch按钮(后台返回0或1)',
  173. width: '260',
  174. },
  175. {
  176. ownDefined: true,
  177. prop: 'status',
  178. label: '状态(自定义颜色)',
  179. width: '180',
  180. format: (row) => {
  181. let text = '';
  182. switch (row.status) {
  183. case 1:
  184. text = '绿色';
  185. break;
  186. case 2:
  187. text = '黄色';
  188. break;
  189. default:
  190. return '—';
  191. }
  192. return text;
  193. },
  194. formatColor: (row) => {
  195. switch (row.status) {
  196. case 1: {
  197. return { color: '#04b935' };
  198. }
  199. case 2: {
  200. return { color: '#ffab4f' };
  201. }
  202. default: {
  203. return { color: '#ee423d' };
  204. }
  205. }
  206. },
  207. },
  208. {
  209. slot: true,
  210. prop: 'productInfoVOList',
  211. label: '数组',
  212. width: '300',
  213. format: (row) => {
  214. const { productInfoVOList } = row;
  215. const auditStatus = { '-1': '报名失败', 1: '报名成功', 2: '审核中' };
  216. let rowEl = productInfoVOList.map((item) => {
  217. return `<div> ${item.productSn}(${auditStatus[item.auditStatus]})</div>`;
  218. });
  219. let rowElVal = rowEl.toString();
  220. return rowElVal.replace(/,/g, ''); //去掉逗号
  221. },
  222. },
  223. {
  224. ownDefined: true,
  225. prop: 'startTime',
  226. label: '时间拼接',
  227. width: '380',
  228. format: (row) => {
  229. return row.startTime + '~' + row.endTime;
  230. },
  231. },
  232. {
  233. ownDefined: true,
  234. prop: 'sex',
  235. label: '性别(后台返回1和2)',
  236. width: '200',
  237. format: (row) => {
  238. let text = '';
  239. switch (row.sex) {
  240. case 1:
  241. text = '男';
  242. break;
  243. case 2:
  244. text = '女';
  245. break;
  246. default:
  247. text = '—';
  248. }
  249. return text;
  250. },
  251. },
  252. {
  253. clickable: true,
  254. prop: 'startTime',
  255. itemClick: this.addBooth,
  256. label: '两个字段且带点击事件',
  257. width: '200',
  258. textClass: 'text-underline',
  259. format: (row) => {
  260. return row.exhibition || row.booth
  261. ? `${row.exhibition || '暂无'} | ${row.booth || '暂无'}`
  262. : '点击设置展位';
  263. },
  264. },
  265. {
  266. clickable: true,
  267. prop: 'clickValue',
  268. itemClick: this.goUrl,
  269. textClass: 'text-color',
  270. label: '带点击事件',
  271. width: '140',
  272. format: (row) => {
  273. return row.clickValue;
  274. },
  275. },
  276. {
  277. isArray: true,
  278. prop: 'venueVal',
  279. label: '数组',
  280. width: '140',
  281. },
  282. {
  283. textClick: true,
  284. prop: 'numDetail',
  285. itemClick: this.goPage,
  286. textClass: 'text-color',
  287. textCont: '点击的文案',
  288. label: '内容与点击事件',
  289. width: '180',
  290. },
  291. {
  292. status: true,
  293. prop: 'objmsg',
  294. label: 'obj类型',
  295. width: '140',
  296. },
  297. /***
  298. * 如果为操作列,则需要填写需要的操作按钮,类型为Object
  299. * type(按钮样式,参考el—botton类型),
  300. * label(按钮文字)
  301. * icon(参考el-icon),
  302. * color(字体颜色),
  303. * isShow(是否显示按钮),
  304. * dividerLine(是否显示分隔线)
  305. * styleClass(按钮样式,不传则为默认)
  306. ***/
  307. {
  308. fixed: 'right',
  309. isOperation: true,
  310. label: '操作',
  311. width: '140',
  312. operation: [
  313. {
  314. type: 'text',
  315. label: '编辑',
  316. icon: '',
  317. buttonClick: this.editTable,
  318. disabledClass: 'disabled-text ',
  319. dividerLine: true,
  320. format:(row) => {
  321. return row.sex==1
  322. },//禁用条件
  323. },
  324. {
  325. type: 'text',
  326. label: '删除',
  327. icon: '',
  328. styleClass: 'red-text',
  329. buttonClick: this.delTable,
  330. },
  331. ],
  332. },
  333. ],
  334. },
  335. pageObj: {
  336. total: 0,
  337. page: 1,
  338. pageSize: 10,
  339. }, //分页对象
  340. };
  341. },
  342. methods: {
  343. // 设置占位
  344. addBooth(row, $index) {
  345. console.log(row, '设置');
  346. },
  347. // 跳转链接
  348. goUrl(row, $index) {
  349. console.log(row, '点击跳转');
  350. },
  351. // 跳转详情
  352. goPage(row, $index) {
  353. console.log(row, '跳转详情');
  354. },
  355. // 编辑事件
  356. editTable(row, $index) {
  357. console.log(row, $index, '编辑');
  358. },
  359. // 删除事件
  360. delTable(row, $index) {
  361. console.log(row, $index, '删除');
  362. },
  363. // 行改变事件
  364. rowOperation(row, $index) {
  365. console.log(row, $index);
  366. },
  367. // cahnge改变事件
  368. switchChange(row, $index) {
  369. console.log(row, $index, 'switch');
  370. },
  371. // 选中的条数
  372. handleSelectionChange(val) {
  373. console.log(val, "选中的数据");
  374. },
  375. // 获取数据的方法
  376. getData() {},
  377. // 改变页数
  378. handleCurrentChange(val) {
  379. this.pageObj.page = val;
  380. this.getData();
  381. },
  382. // 改变页码
  383. handleSizeChange(val) {
  384. this.pageObj.pageSize = val;
  385. this.getData();
  386. },
  387. },
  388. };
  389. </script>
  390. <style lang='scss' scoped>
  391. .public-table-demo {
  392. background: #ffffff;
  393. padding: 0.32rem 0.2rem 0.16rem 0.2rem;
  394. // border: 1px solid #dcdfe6;
  395. border-radius: 4px;
  396. .public-table-demo-titles-left {
  397. font-size: 24px;
  398. font-weight: bold;
  399. }
  400. }
  401. </style>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/621610
推荐阅读
相关标签
  

闽ICP备14008679号