• 实现表格表头自定义编辑、一键导入、增加列


     1.前言

    本文基于vue2及elementUI的表格组件

     


    2.效果及功能展示 

     


     3.需求背景

    有时候客户急需看到需求实现的页面,而此时后端接口没有,产品原型没有,只能前端出马,画一个静态页面,来展示客户想要的东西,如果是通过F12来改很慢,于是就有了这篇文章,使用它可以轻松的对表格的任何地方进行修改,且可以增加减少行或者列,它完全是由数据控制的,而在此基础上,还支持一键导入的功能,可以不用一个一个的编辑,直接一步到位。


    4.技术实现

    4.1 表格编辑

    要说明的是,我使用的elementUI的表格组件,针对表格他们提供了一些事件,比如 点击表头事件:

    说白了,其实就是将框架提供给我们的事件回调函数中有用的部分,对表头数据进行修改即可

    4.2 表格增加列

    在事件回调中,对数据进行push操作

    4.3 一键导入

    思路是 使用input标签的file文件上传功能(原生的标签过于丑陋,我给隐藏了,使用好看的按钮触发input的click事件即可) ,然后将导入的文件读取,并保存到变量中,转为数组。

    我是在文件中放了两个数组,上面是表头,下面是表格数据。

    我准备的数据源及格式如下:

     


    5.核心代码展示

    1. <template>
    2. <div>
    3. <div class="main-title" @click="$refs.fileInput.click()" >xxx库div>
    4. <input ref="fileInput" style="display:none" type="file" id="data2"
    5. @change="upload()">
    6. <div class="tollboxlist context_box_bg">
    7. <div class="search-box">
    8. <el-table :data="tableData" style="width: 98%;align: center" @cell-click="tsetClick" @header-click="headerTest">
    9. <el-table-column :label="item.propName" :property="item.prop" v-for="item in tableColumnList" :key="item.prop" align="center">
    10. <template slot-scope="scope">
    11. <span @click="getIndex(scope.$index)">{{scope.row[scope.column.property]}}span>
    12. template>
    13. el-table-column>
    14. <el-table-column label="." width="20" prop="addTableHeaderName" align="center"/>
    15. el-table>
    16. <el-dialog :visible.sync="dialogForHeader" title="修改项目流程名称" width="800">
    17. <el-form ref="form" :model="tableHeader" label-width="80px">
    18. <el-form-item label="表头名称">
    19. <el-input v-model="tableHeader.tableHeaderName" placeholder="请输入表头名称" />
    20. el-form-item>
    21. el-form>
    22. <div slot="footer" class="dialog-footer">
    23. <el-button type="primary" @click="submitForm">确 定el-button>
    24. <el-button @click="cancel">取 消el-button>
    25. div>
    26. el-dialog>
    27. <el-dialog :visible.sync="dialogForTable" title="修改项目流程内容" width="800">
    28. <el-form ref="form" :model="tableCell" label-width="120px">
    29. <el-form-item label="流程内容名称">
    30. <el-input v-model="tableCell.tableCellData" placeholder="流程内容名称" />
    31. el-form-item>
    32. el-form>
    33. <div slot="footer" class="dialog-footer">
    34. <el-button type="primary" @click="submitForm1">确 定el-button>
    35. <el-button @click="cancel1">取 消el-button>
    36. div>
    37. el-dialog>
    38. <el-pagination
    39. :page-size="page_size"
    40. background
    41. layout="total, prev, pager, next, sizes,jumper"
    42. :total="total"
    43. :current-page="page"
    44. @size-change="handleSizeChange"
    45. @current-change="handleCurrentChange"
    46. >
    47. el-pagination>
    48. div>
    49. div>
    50. <el-dialog class="zidiandia" title="新建字典" :visible.sync="createDictionaries" v-if="createDictionaries" :before-close="cancelform" width='1184px' :close-on-click-modal="false" :show-close="false">
    51. <div class="dialog_b_btn">
    52. <el-button size="small" @click="handleCreateSave">保存el-button>
    53. <el-button size="small" @click="handleSaveCancel">取消el-button>
    54. div>
    55. <Edit
    56. :exhibitionList="exhibitionList"
    57. :serviceType="serviceType"
    58. :dictionariesType="dictionariesType"
    59. :pageType = "pageType"
    60. ref="createEditRef"
    61. >Edit>
    62. el-dialog>
    63. <el-dialog title="详情" :visible.sync="editDictionaries" :before-close="cancelform" width='1184px' :close-on-click-modal="false" :show-close="false">
    64. <div class="dialog_b_btn">
    65. <el-button size="small" @click="handleClickEdit" v-if="isUpdate">编辑el-button>
    66. <el-button size="small" v-else >编辑中el-button>
    67. <el-button size="small" @click="handleEditSave" v-if="!isUpdate">保存el-button>
    68. <el-button size="small" @click="handleEditCancel">取消el-button>
    69. div>
    70. <Edit
    71. v-if="editShow"
    72. :show="isUpdate"
    73. :exhibitionList="exhibitionList"
    74. :serviceType="serviceType"
    75. :dictionariesType="dictionariesType"
    76. :editData="editData"
    77. :pageType = "pageType"
    78. ref="cancelEditRef"
    79. >Edit>
    80. el-dialog>
    81. div>
    82. template>
    83. <script>
    84. export default {
    85. data() {
    86. return {
    87. // 这里为了简便我就没有调用后台接口获取数据,直接写的假数据 你要用的话可以调用后台接口
    88. 获取tableColumnList,注意数据格式
    89. tableColumnList:
    90. [
    91. {prop: '0', propName: '编号8888'},
    92. {prop: '2', propName: '名字'},
    93. {prop: '3', propName: '保质期'},
    94. {prop: '4', propName: '特点1'},
    95. ],
    96. tableData: [{
    97. 0: '2016-05-01',
    98. 2: '王小虎1',
    99. 3: '上海市普陀区金沙江路 1518 弄',
    100. 4: '2016-05-02',
    101. }, {
    102. 0: '2016-05-02',
    103. 2: '王小虎2',
    104. 3: '上海市普陀区金沙江路 1518 弄',
    105. 4: '2016-05-02',
    106. }, {
    107. 0: '2016-05-03',
    108. 2: '王小虎3',
    109. 3: '上海市普陀区金沙江路 1518 弄',
    110. 4: '2016-05-02',
    111. }, {
    112. 0: '2016-05-04',
    113. 2: '王小虎4',
    114. 3: '上海市普陀区金沙江路 1518 弄',
    115. 4: '2016-05-02',
    116. }, {
    117. 0: '2016-05-05',
    118. 2: '王小虎5',
    119. 3: '上海市普陀区金沙江路 1518 弄',
    120. 4: '2016-05-06',
    121. },
    122. {
    123. 0: '2016-05-07',
    124. 2: '王小虎6',
    125. 3: '上海市普陀区金沙江路 1518 弄',
    126. 4: '2016-05-02',
    127. },
    128. {
    129. 0: '2016-05-07',
    130. 2: '王小虎6',
    131. 3: '上海市普陀区金沙江路 1518 弄',
    132. 4: '2016-05-02',
    133. },
    134. {
    135. 0: '2016-05-07',
    136. 2: '王小虎6',
    137. 3: '上海市普陀区金沙江路 1518 弄',
    138. 4: '2016-05-02',
    139. },
    140. {
    141. 0: '2016-05-07',
    142. 2: '王小虎6',
    143. 3: '上海市普陀区金沙江路 1518 弄',
    144. 4: '2016-05-02',
    145. },
    146. {
    147. 0: '2016-05-07',
    148. 2: '王小虎6',
    149. 3: '上海市普陀区金沙江路 1518 弄',
    150. 4: '2016-05-02',
    151. }
    152. ],
    153. }
    154. },
    155. methods: {
    156. upload(e){
    157. let that = this;
    158. console.log("点击了上传按钮");
    159. let da = window.event || e // change事件获取到的数据
    160. var file = da.target.files[0]
    161. console.log(file, 'file===');
    162. if (true) {
    163. var reader = new FileReader()
    164. reader.readAsText(file, "utf-8")//gbk编码 还有其他方式比如gpk
    165. reader.onload = function (da) {
    166. console.log(da.target.result, 'da',Object.prototype.toString.call(da.target.result));
    167. //查找字符串中第三个‘[’并截取,分别保存到str1和str2中
    168. let str1 = "";
    169. let str2 = "";
    170. var str = da.target.result;
    171. // 计数器,用于记录'['的出现次数
    172. var count = 0;
    173. // 保存第三个'['字符的索引
    174. var startIndex = -1;
    175. // 遍历字符串
    176. for (var i = 0; i < str.length; i++) {
    177. // 如果找到了第2个'['字符
    178. if (str[i] === '[') {
    179. // 计数器加1
    180. count++;
    181. // 如果计数器为3,则保存索引并跳出循环
    182. if (count === 2) {
    183. startIndex = i;
    184. break;
    185. }
    186. }
    187. }
    188. // 如果找到了第三个'['字符
    189. if (startIndex !== -1) {
    190. // 使用字符串的截取函数substring将第三个'['之后的内容截取到str1变量
    191. str1 = str.substring(0,startIndex);
    192. str2 = str.substring(startIndex, str.length );
    193. console.log("str1: " + str1);
    194. console.log("str2: " + str2);
    195. } else {
    196. console.log("未找到第三个'['字符");
    197. }
    198. // console.log(str2, 'str2',Object.prototype.toString.call(str2));
    199. that.daoRuJson = eval('(' + str1 + ')')
    200. let tabelData = eval('(' + str2 + ')')
    201. // that.daoRuJson = eval('(' + da.target.result + ')')
    202. that.tableColumnList = that.daoRuJson
    203. that.tableData = tabelData
    204. console.log("表头数据",that.tableColumnList);
    205. console.log("表格数据",that.tableData);
    206. // console.log(that.daoRuJson, 'that.daoRuJson',Object.prototype.toString.call(that.daoRuJson));
    207. }
    208. }
    209. },
    210. handleEdit(index, row) {
    211. console.log(index, row);
    212. },
    213. handleDelete(index, row) {
    214. console.log(index, row);
    215. },
    216. getIndex(index){
    217. console.log("index",index);
    218. this.tableCellIndex = "";
    219. this.tableCellIndex = index;
    220. },
    221. tsetClick(row, column, cell, event){
    222. this.dialogForTable = true;
    223. this.columnName = "";
    224. this.columnName = column.property;
    225. this.tableCell.tableCellData = "";
    226. this.tableCell.tableCellData = row[this.columnName];
    227. console.log("这里是表格内容单击事件",row);
    228. console.log("这里是表格内容单击事件",column)
    229. // console.log("这里是表格双击事件",cell)
    230. // console.log("这里是表格双击事件",event)
    231. },
    232. //添加表头,修改表头
    233. headerTest(val){
    234. if(val.property == "addTableHeaderName"){
    235. console.log("这里是表格tou部点击,添加头部事件",val)
    236. this.tableColumnList.push({prop: this.num.toString(), propName: '点击编辑项目流程名称'})
    237. for (let i = 0; i < this.tableData.length; i++) {
    238. //this.tableData[i][parseInt(this.num)] = "请添加内容";
    239. this.$set(this.tableData[i],[parseInt(this.num)],"请添加内容");
    240. }
    241. this.num = this.num+1;
    242. }else {
    243. console.log("这里是表格tou部点击,修改头部事件",val)
    244. this.tableHeader.tableHeaderName = "";
    245. this.tableHeader.property = "";
    246. this.tableHeader.tableHeaderName = val.label;
    247. this.tableHeader.property = val.property;
    248. console.log(this.tableHeader.tableHeaderName)
    249. this.dialogForHeader = true;
    250. }
    251. },
    252. //表头编辑提交
    253. submitForm(){
    254. console.log("点击提交按钮");
    255. for (let i = 0; i < this.tableColumnList.length; i++) {
    256. console.log("this.tableHeader.property",this.tableHeader.property)
    257. console.log("this.tableColumnList[i].prop",this.tableColumnList[i].prop)
    258. if(this.tableColumnList[i].prop === this.tableHeader.property){
    259. this.tableColumnList[i].propName = this.tableHeader.tableHeaderName;
    260. }
    261. }
    262. console.log(this.tableColumnList)
    263. this.dialogForHeader = false;
    264. },
    265. //表格内容编辑提交
    266. submitForm1(){
    267. //console.log("点击提交按钮");
    268. if(this.tableCellIndex === "" || this.tableCellIndex === null){
    269. alert("亲,请精准点击表格中的字进行修改!")
    270. }else {
    271. console.log("this.columnName",this.columnName)
    272. console.log("this.tableData[this.tableCellIndex][this.columnName]",this.tableData[this.tableCellIndex][this.columnName])
    273. console.log("this.tableData[this.tableCellIndex]",this.tableData[this.tableCellIndex])
    274. this.tableData[this.tableCellIndex][this.columnName] = this.tableCell.tableCellData;
    275. console.log(this.tableData);
    276. this.rush();
    277. }
    278. this.dialogForTable = false;
    279. },
    280. //强制刷新数据
    281. rush(){
    282. this.$set(this.tableData);
    283. },
    284. //取消表头编辑
    285. cancel(){
    286. //console.log("点击取消按钮");
    287. this.dialogForHeader = false;
    288. },
    289. //取消表格内容编辑
    290. cancel1(){
    291. //console.log("点击取消按钮");
    292. this.dialogForTable = false;
    293. },
    294. },
    295. }
    296. script>

     

     

  • 相关阅读:
    MySQL高级【数据库设计】第八章
    华为配置wlan
    面向对象编程-终结篇 es6新增语法
    tomcat排错实战
    【C++面向对象程序设计】CH5 继承与派生(续)——虚基类
    Arouter源码系列之拦截器原理详解
    C#使用mysql-connector-net驱动连接mariadb报错
    抖音小店无货源,月入过万的玩法技巧!更多实操细节分享
    与机器学习相比,人类的学习包括视觉、听觉、触觉、嗅觉、味觉的串并行混合学习...
    TensorFlow 的基本概念和使用场景
  • 原文地址:https://blog.csdn.net/wanghaoyingand/article/details/133163028