作为一个后端开发人员,因项目需求暂转页面开发的伪前端人员,在项目需求实现中的小收获在这里做一下分享。
话不多说,看代码
article1. vue登录记住密码之cookeis缓存
- 页面代码
1 <template> 2 <el-form :rules="loginRules" ref="loginForm" :model="loginForm"> 3 <el-form-item prop="username"> 4 <el-input size="small" keyup.enter.native="handleLogin" v-model="loginForm.username" placeholder="请输入用户名"> 5 </el-input> 6 </el-form-item> 7 <el-form-item prop="password"> 8 <el-input size="small" @keyup.enter.native="handleLogin" v-model="loginForm.password" placeholder="请输入密码"> 9 </el-form-item> 10 <el-checkbox v-model="checked">记住密码</el-checkbox> 11 <el-form-item> 12 <el-button type="primary" size="small" :loading="false" @click.native.prevent="handleLogin" class="login-submit"> 13 <span v-if="!loading">登 录</span> 14 <span v-else> 15 <i slot="prefix" class="el-icon-loading"></i> 16 登 录 中...</span> 17 </el-button> 18 </el-form-item> 19 </el-form> 20 </template>
- js函数
1 <script> 2 import { Base64 } from 'js-base64' 3 export default { 4 name: 'userlogin', 5 data() { 6 return { 7 loginForm: { 8 username: '', 9 password: '' 10 }, 11 checked: false, 12 } 13 }, 14 mounted() { 15 this.getCookie() 16 }, 17 methods: { 18 handleLogin() { 19 this.$refs.loginForm.validate(valid => { 20 if (valid) { 21 if (this.checked === true) { 22 this.setCookie(this.loginForm.username, Base64.encode(this.loginForm.password), 7) 23 } else { 24 this.clearCookie() 25 } 26 // 调用后端api接口实现相关功能,省略 27 } 28 }) 29 }, 30 // 设置cookie 31 setCookie(c_name, c_pwd, exdays) { 32 const exdate = new Date() // 获取时间 33 exdate.setTime(exdate.getTime() + 24 * 60 * 60 * 1000 * exdays) // 设置过期时间 34 // 字符串拼接cookie 35 window.document.cookie = 'username' + '=' + c_name + ';path=/;expires=' + exdate.toGMTString() 36 window.document.cookie = 'password' + '=' + c_pwd + ';path=/;expires=' + exdate.toGMTString() 37 }, 38 // 读取cookie 39 getCookie() { 40 if (document.cookie.length > 0) { 41 const arr = document.cookie.toString().split('; ') 42 for (let i = 0; i < arr.length; i++) { 43 const arr2 = arr[i].split('=') // 再次切割 44 // 判断查找相对应的值 45 if (arr2[0] === 'username') { 46 this.loginForm.username = arr2[1] // 保存到保存数据的地方 47 } else if (arr2[0] === 'password') { 48 this.loginForm.password = Base64.decode(arr2[1]) 49 } 50 } 51 } 52 }, 53 // 清除cookie 54 clearCookie() { 55 this.setCookie('', '', -1) // 修改2值都为空,天数为负1天就好了 56 } 57 } 58 } 59 </script>
- 密码加解密根据喜好自行下载 本文采用Base64 npm install --save js-base64 然后引用即可
article2. 基于ElementUI 分页插件实现页面分页和后端分页
- 基于ui插件的前端分页,通过slice函数对数据集合进行分页 <el-table :data="invperiods.slice((currentPage-1)*pageSize,currentPage*pageSize)"></el-table>,对于数据量较少的简单数据查询可适当采用前端分页
1 <template> 2 <section class="app-container"> 3 <el-col :span="24" class="toolbar" style="margin-top: -10px"> 4 <el-form :inline="true" :model="filters" ref="filters" :rules="rules" size="mini"> 5 <el-form-item prop="periodCode" label="期间名称"> 6 <el-input v-model.trim="filters.periodCode" placeholder="期间名称"></el-input> 7 </el-form-item> 8 <el-form-item prop="periodStatus" label="期间状态"> 9 <el-select v-model="filters.periodStatus" placeholder="请选择" size="mini"> 10 <el-option v-for="item in status" :key="item.key" :value="item.value" :label="item.key"></el-option> 11 </el-select> 12 </el-form-item> 13 <el-form-item> 14 <el-button type="primary" @click="Query">查询</el-button> 15 </el-form-item> 16 <el-form-item> 17 <el-button type="info" @click="handleReset">重置</el-button> 18 </el-form-item> 19 </el-form> 20 </el-col> 21 <!--列表--> 22 <el-table :data="invperiods.slice((currentPage-1)*pageSize,currentPage*pageSize)" :height="tableHeight" :header-cell-style="tableHeaderColor" size="mini" border 23 :cell-style="cellStyle" :row-style="rowStyle" v-loading="findLoading" element-loading-text="数据加载中"> 24 <el-table-column type="selection" label="可选"> 25 </el-table-column> 26 <el-table-column v-for="v in theader.columns" :prop="v.field" :label="v.title" :key="v.field"> 27 <template slot-scope="scope"> 28 <span v-if="v.field === 'PeriodStatus'"> 29 <span v-for="item in status"> 30 <span v-if="scope.row.PeriodStatus === item.value">{{ item.key }}</span> 31 </span> 32 </span> 33 <span v-else-if="v.field === 'PBeginDate' || v.field === 'PEndDate'"> 34 {{ scope.row[v.field] | dateFormat }} 35 </span> 36 <span v-else-if="v.field === 'PBeginTime' || v.field === 'PEndTime'">{{ scope.row[v.field] | timeFormat }}</span> 37 <span v-else>{{ scope.row[v.field] }}</span> 38 </template> 39 </el-table-column> 40 <el-table-column label="操作" width="80"> 41 <template slot-scope="scope"> 42 <el-popover placement="top" width="160" :ref="scope.row.PeriodName"> 43 <el-form :model="editForm" :rules="editFormRules" ref="editForm" size="mini"> 44 <el-form-item label="状态" prop="PeriodStatus" class="disposition"> 45 <el-select v-model="editForm.PeriodStatus" placeholder="请选择" size="mini"> 46 <el-option v-for="item in status" :key="item.key" :value="item.value" :label="item.key"></el-option> 47 </el-select> 48 </el-form-item> 49 </el-form> 50 <div style="text-align: right; margin: 3px"> 51 <el-button size="mini" type="info" @click="$refs[scope.row.PeriodName].doClose()">取消</el-button> 52 <el-button type="primary" size="mini" @click="updateData(scope.row.PeriodName)">确定</el-button> 53 </div> 54 <el-button slot="reference" size="mini" @click="handleEdit(scope.$index, scope.row)" type="success" icon="el-icon-edit"></el-button> 55 </el-popover> 56 </template> 57 </el-table-column> 58 </el-table> 59 <!--工具条--> 60 <el-col :span="24" class="toolbar"> 61 <el-pagination background 62 @size-change="handleSizeChange" 63 @current-change="handleCurrentChange" 64 :current-page="currentPage" 65 :page-sizes="[50, 100, 200, 500]" 66 :page-size=pageSize 67 layout="total, sizes, prev, pager, next, jumper" 68 :total=total> 69 </el-pagination> 70 </el-col> 71 </section> 72 </template> 73 74 <script> 75 76 export default { 77 name: 'index', 78 data() { 79 return { 80 invperiods: [], 81 findLoading: false, 82 filters: {}, 83 rules: {}, 84 editForm: {}, 85 editFormRules: {}, 86 total: 0, 87 pageSize: 50, 88 currentPage: 1 89 } 90 }, 91 filters: { 92 dateFormat: function(value) { 93 return dateFormat(value) 94 }, 95 timeFormat: function(value) { 96 return timeFormat(value) 97 } 98 }, 99 methods: { 100 101 handleSizeChange(val) { 102 this.pageSize = val 103 }, 104 handleCurrentChange(val) { 105 this.currentPage = val 106 }, 107 Query() { 108 this.findLoading = true 109 const data = {} 110 GetInvPeriod(data).then(res => { 111 this.total = res.length // 后端接口返回的总记录数 112 this.invperiods = res.data // 此处又后端处理返回的列表集合 113 this.findLoading = false 114 }) 115 }, 116 handleReset() { 117 this.$refs.filters.validate(valid => { 118 if (valid) { 119 this.$refs['filters'].resetFields() 120 } 121 }) 122 } 123 } 124 } 125 </script>
- 后端分页,采用Oracle数据库,Mybatis 分页插件,具体实现可自行搜索相关博客或查看官方文档。因数据量过大或多表关联引起的慢SQL导致查询时数据库取消用户请求,用户体验很不好,故而采用后端分页,需要前端传入PageIndex和PageSize,即查询页码和每页查询的记录数。
1 <template> 2 <section class="app-container"> 3 <el-col :span="24" class="toolbar" style="margin-top: -10px"> 4 <el-form :inline="true" :model="filters" ref="filters" :rules="rules" size="mini"> 5 <el-form-item prop="periodCode" label="期间名称"> 6 <el-input v-model.trim="filters.periodCode" placeholder="期间名称"></el-input> 7 </el-form-item> 8 <el-form-item prop="periodStatus" label="期间状态"> 9 <el-select v-model="filters.periodStatus" placeholder="请选择" size="mini"> 10 <el-option v-for="item in status" :key="item.key" :value="item.value" :label="item.key"></el-option> 11 </el-select> 12 </el-form-item> 13 <el-form-item> 14 <el-button type="primary" @click="Query">查询</el-button> 15 </el-form-item> 16 <el-form-item> 17 <el-button type="info" @click="handleReset">重置</el-button> 18 </el-form-item> 19 </el-form> 20 </el-col> 21 <!--列表--> 22 <el-table :data="invperiods :height="tableHeight" :header-cell-style="tableHeaderColor" size="mini" border 23 :cell-style="cellStyle" :row-style="rowStyle" v-loading="findLoading" element-loading-text="数据加载中"> 24 <el-table-column type="selection" label="可选"> 25 </el-table-column> 26 <el-table-column v-for="v in theader.columns" :prop="v.field" :label="v.title" :key="v.field"> 27 <template slot-scope="scope"> 28 <span v-if="v.field === 'PeriodStatus'"> 29 <span v-for="item in status"> 30 <span v-if="scope.row.PeriodStatus === item.value">{{ item.key }}</span> 31 </span> 32 </span> 33 <span v-else-if="v.field === 'PBeginDate' || v.field === 'PEndDate'"> 34 {{ scope.row[v.field] | dateFormat }} 35 </span> 36 <span v-else-if="v.field === 'PBeginTime' || v.field === 'PEndTime'">{{ scope.row[v.field] | timeFormat }}</span> 37 <span v-else>{{ scope.row[v.field] }}</span> 38 </template> 39 </el-table-column> 40 <el-table-column label="操作" width="80"> 41 <template slot-scope="scope"> 42 <el-popover placement="top" width="160" :ref="scope.row.PeriodName"> 43 <el-form :model="editForm" :rules="editFormRules" ref="editForm" size="mini"> 44 <el-form-item label="状态" prop="PeriodStatus" class="disposition"> 45 <el-select v-model="editForm.PeriodStatus" placeholder="请选择" size="mini"> 46 <el-option v-for="item in status" :key="item.key" :value="item.value" :label="item.key"></el-option> 47 </el-select> 48 </el-form-item> 49 </el-form> 50 <div style="text-align: right; margin: 3px"> 51 <el-button size="mini" type="info" @click="$refs[scope.row.PeriodName].doClose()">取消</el-button> 52 <el-button type="primary" size="mini" @click="updateData(scope.row.PeriodName)">确定</el-button> 53 </div> 54 <el-button slot="reference" size="mini" @click="handleEdit(scope.$index, scope.row)" type="success" icon="el-icon-edit"></el-button> 55 </el-popover> 56 </template> 57 </el-table-column> 58 </el-table> 59 <!--工具条--> 60 <el-col :span="24" class="toolbar"> 61 <el-pagination background 62 @size-change="handleSizeChange" 63 @current-change="handleCurrentChange" 64 :current-page="currentPage" 65 :page-sizes="[50, 100, 200, 500]" 66 :page-size=pageSize 67 layout="total, sizes, prev, pager, next, jumper" 68 :total=total> 69 </el-pagination> 70 </el-col> 71 </section> 72 </template> 73 74 <script> 75 76 export default { 77 name: 'index', 78 data() { 79 return { 80 invperiods: [], 81 findLoading: false, 82 filters: {}, 83 rules: {}, 84 editForm: {}, 85 editFormRules: {}, 86 total: 0, 87 pageSize: 50, 88 currentPage: 1 89 } 90 }, 91 filters: { 92 dateFormat: function(value) { 93 return dateFormat(value) 94 }, 95 timeFormat: function(value) { 96 return timeFormat(value) 97 } 98 }, 99 methods: { 100 101 handleSizeChange(val) { 102 this.pageSize = val 103 this.Query() 104 }, 105 handleCurrentChange(val) { 106 this.currentPage = val 107 this.Query() 108 }, 109 Query() { 110 this.findLoading = true 111 const data = { 112 ... 113 entity.PageIndex = this.currentPage 114 entity.PageSize = this.pageSize 115 ... 116 } 117 GetInvPeriod(data).then(res => { 118 this.total = res.RowCount // 后端接口返回的总记录数 119 this.invperiods = res.data // 此处又后端处理返回的列表集合 120 this.findLoading = false 121 }) 122 }, 123 handleReset() { 124 this.$refs.filters.validate(valid => { 125 if (valid) { 126 this.$refs['filters'].resetFields() 127 } 128 }) 129 } 130 } 131 } 132 </script>
article3. 基于ElementUI 实现table表格导出Excel(根据github上大神的代码,在此只是简单的记录一下以便后面复用时更加方便)
- 需要下载安装依赖包 npm install file-saver npm install xlsx
- 将核心功能js文件引入相关页面
Export2Excel.js
1 /* eslint-disable */ 2 require('script-loader!file-saver'); 3 import XLSX from 'xlsx' 4 5 function generateArray(table) { 6 var out = []; 7 var rows = table.querySelectorAll('tr'); 8 var ranges = []; 9 for (var R = 0; R < rows.length; ++R) { 10 var outRow = []; 11 var row = rows[R]; 12 var columns = row.querySelectorAll('td'); 13 for (var C = 0; C < columns.length; ++C) { 14 var cell = columns[C]; 15 var colspan = cell.getAttribute('colspan'); 16 var rowspan = cell.getAttribute('rowspan'); 17 var cellValue = cell.innerText; 18 if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue; 19 20 //Skip ranges 21 ranges.forEach(function (range) { 22 if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) { 23 for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null); 24 } 25 }); 26 27 //Handle Row Span 28 if (rowspan || colspan) { 29 rowspan = rowspan || 1; 30 colspan = colspan || 1; 31 ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}}); 32 } 33 ; 34 35 //Handle Value 36 outRow.push(cellValue !== "" ? cellValue : null); 37 38 //Handle Colspan 39 if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null); 40 } 41 out.push(outRow); 42 } 43 return [out, ranges]; 44 }; 45 46 function datenum(v, date1904) { 47 if (date1904) v += 1462; 48 var epoch = Date.parse(v); 49 return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); 50 } 51 52 function sheet_from_array_of_arrays(data, opts) { 53 var ws = {}; 54 var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}}; 55 for (var R = 0; R != data.length; ++R) { 56 for (var C = 0; C != data[R].length; ++C) { 57 if (range.s.r > R) range.s.r = R; 58 if (range.s.c > C) range.s.c = C; 59 if (range.e.r < R) range.e.r = R; 60 if (range.e.c < C) range.e.c = C; 61 var cell = {v: data[R][C]}; 62 if (cell.v == null) continue; 63 var cell_ref = XLSX.utils.encode_cell({c: C, r: R}); 64 65 if (typeof cell.v === 'number') cell.t = 'n'; 66 else if (typeof cell.v === 'boolean') cell.t = 'b'; 67 else if (cell.v instanceof Date) { 68 cell.t = 'n'; 69 cell.z = XLSX.SSF._table[14]; 70 cell.v = datenum(cell.v); 71 } 72 else cell.t = 's'; 73 74 ws[cell_ref] = cell; 75 } 76 } 77 if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range); 78 return ws; 79 } 80 81 function Workbook() { 82 if (!(this instanceof Workbook)) return new Workbook(); 83 this.SheetNames = []; 84 this.Sheets = {}; 85 } 86 87 function s2ab(s) { 88 var buf = new ArrayBuffer(s.length); 89 var view = new Uint8Array(buf); 90 for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; 91 return buf; 92 } 93 94 export function export_table_to_excel(id) { 95 var theTable = document.getElementById(id); 96 var oo = generateArray(theTable); 97 var ranges = oo[1]; 98 99 /* original data */ 100 var data = oo[0]; 101 var ws_name = "Sheet"; 102 103 var wb = new Workbook(), ws = sheet_from_array_of_arrays(data); 104 105 /* add ranges to worksheet */ 106 // ws['!cols'] = ['apple', 'banan']; 107 ws['!merges'] = ranges; 108 109 /* add worksheet to workbook */ 110 wb.SheetNames.push(ws_name); 111 wb.Sheets[ws_name] = ws; 112 113 var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'}); 114 115 saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx") 116 } 117 118 export function export_json_to_excel({header, data, filename='excel-list', autoWidth=true}={}) { 119 /* original data */ 120 data=[...data] 121 data.unshift(header); 122 var ws_name = "Sheet"; 123 var wb = new Workbook(), ws = sheet_from_array_of_arrays(data); 124 125 if(autoWidth){ 126 /*设置worksheet每列的最大宽度*/ 127 const colWidth = data.map(row => row.map(val => { 128 /*先判断是否为null/undefined*/ 129 if (val == null) { 130 return {'wch': 10}; 131 } 132 /*再判断是否为中文*/ 133 else if (val.toString().charCodeAt(0) > 255) { 134 return {'wch': val.toString().length * 2}; 135 } else { 136 return {'wch': val.toString().length}; 137 } 138 })) 139 /*以第一行为初始值*/ 140 let result = colWidth[0]; 141 for (let i = 1; i < colWidth.length; i++) { 142 for (let j = 0; j < colWidth[i].length; j++) { 143 if (result[j]['wch'] < colWidth[i][j]['wch']) { 144 result[j]['wch'] = colWidth[i][j]['wch']; 145 } 146 } 147 } 148 ws['!cols'] = result; 149 } 150 151 /* add worksheet to workbook */ 152 wb.SheetNames.push(ws_name); 153 wb.Sheets[ws_name] = ws; 154 155 var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'}); 156 saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), filename + ".xlsx"); 157 }
3. 要实现导出功能的页面
1 <template> 2 <section class="app-container"> 3 4 <el-checkbox label="Excel单元格自动宽度" v-model="autoWidth" true-label="true" false-label="false" border size="mini" style="display: inline;"></el-checkbox> 5 <el-link type="primary" @click="dialogVisible = true" style="float: right;">选择栏位<i class="el-icon-document-add el-icon--right"></i></el-link> 6 <el-table :data="reportTransInfos" :header-cell-style="tableHeaderColor" size="mini" border 7 :cell-style="cellStyle" :row-style="rowStyle" v-loading="findLoading" :element-loading-text="loadingData" 8 @selection-change="selsChange" :row-key="getRowKeys" ref="multipleTable"> 9 <el-table-column type="selection" :reserve-selection="true"></el-table-column> 10 <el-table-column v-for="v in thead" :prop="v.field" :label="v.title" :width="v.width" :key="v.field" :header-align="v.headerAlign" :align="v.align"> 11 </el-table-column> 12 </el-table> 13 </section> 14 </template> 15 16 <script> 17 import thead from '@/utils/table' 18 export default { 19 name: 'index', 20 data() { 21 return { 22 23 thead: thead.transInfo_thead, // 表头列 24 autoWidth: true, // 导出excel 自动宽度 25 // bookType: 'xlsx', // 导出文件类型 26 filename: '库存事务', 27 sels: [], 28 getRowKeys(row) { 29 // 获取唯一标识的行数据 30 return row.index 31 } 32 } 33 }, 34 35 methods: { 36 // 全选单选多选 37 selsChange(sels) { 38 this.sels = sels 39 }, 40 exportExcel() { 41 if (this.sels.length) { 42 this.findLoading = true 43 this.loadingData = '正在导出数据...' 44 import('@/vendor/Export2Excel').then(excel => { 45 const tHeader = [] 46 const filterVal = [] 47 this.thead.forEach(item => { 48 tHeader.push(item.title) 49 filterVal.push(item.field) 50 }) 51 const list = this.sels 52 const data = this.formatJson(filterVal, list) 53 excel.export_json_to_excel({ 54 header: tHeader, 55 data, 56 filename: this.filename, 57 autoWidth: this.autoWidth 58 }) 59 this.$refs.multipleTable.clearSelection() 60 this.findLoading = false 61 }) 62 } else { 63 this.$message({ 64 message: '请至少勾选一条记录', 65 type: 'warning' 66 }) 67 } 68 }, 69 formatJson(filterVal, jsonData) { 70 return jsonData.map(v => filterVal.map(j => v[j])) 71 } 72 } 73 } 74 </script>
article4. 基于UI的table多选框的数据实现分页数据勾选记忆功能
鉴于article2,3 实现了分页和表格列勾选下载功能,此时需求是用户在多页间每页勾选需要下载的记录信息进行下载,此时就需要在翻页后记住之前勾选的记录数
1 <template> 2 <section class="app-container"> 3 4 <!--列表--> 5 <el-checkbox label="Excel单元格自动宽度" v-model="autoWidth" true-label="true" false-label="false" border size="mini" style="display: inline;"></el-checkbox> 6 <el-link type="primary" @click="dialogVisible = true" style="float: right;">选择栏位<i class="el-icon-document-add el-icon--right"></i></el-link> 7 <el-table :data="reportTransInfos" :header-cell-style="tableHeaderColor" 8 size="mini" border :height="tableHeight" 9 :cell-style="cellStyle" :row-style="rowStyle" v-loading="findLoading" :element-loading-text="loadingData" 10 @selection-change="selsChange" :row-key="getRowKeys" ref="multipleTable"> 11 <el-table-column type="selection" :reserve-selection="true"></el-table-column> 12 <el-table-column v-for="v in thead" :prop="v.field" :label="v.title" :width="v.width" :key="v.field" :header-align="v.headerAlign" :align="v.align"> 13 <template slot-scope="scope"> 14 <span v-if="v.field === 'TransDate'"> 15 {{ scope.row[v.field] | dateFormat }} 16 </span> 17 <span v-else>{{ scope.row[v.field] }}</span> 18 </template> 19 </el-table-column> 20 </el-table> 21 <!--工具条--> 22 <el-col :span="24" class="toolbar"> 23 <el-pagination background 24 @size-change="handleSizeChange" 25 @current-change="handleCurrentChange" 26 :current-page="currentPage" 27 :page-sizes="[50, 100, 200, 500]" 28 :page-size=pageSize 29 layout="total, sizes, prev, pager, next, jumper" 30 :total=total> 31 </el-pagination> 32 </el-col> 33 </section> 34 </template> 35 36 <script> 37 import thead from '@/utils/table' 38 export default { 39 name: 'index', 40 data() { 41 return { 42 43 thead: thead.transInfo_thead, 44 loadingData: '', 45 findLoading: false, 46 autoWidth: true, // 导出excel 自动宽度 47 // bookType: 'xlsx', // 导出文件类型 48 filename: '库存事务', 49 cellStyle: { 'padding': '0px' }, 50 reportTransInfos: [], 51 transTyle: [], // 事务类型 52 total: 0, 53 pageSize: 50, 54 currentPage: 1, 55 sels: [], // 被勾选的数据集 56 getRowKeys(row) { 57 // 获取唯一标识的行数据 58 return row.index 59 } 60 } 61 }, 62 filters: { 63 dateFormat: function(value) { 64 return dateFormat(value) 65 }, 66 timeFormat: function(value) { 67 return timeFormat(value) 68 } 69 }, 70 methods: { 71 // 省略其他方法 72 ... 73 handleSizeChange(val) { 74 this.pageSize = val 75 this.Query() 76 }, 77 handleCurrentChange(val) { 78 this.currentPage = val 79 this.Query() 80 }, 81 Query() { 82 this.$refs['filters'].validate((valid) => { 83 if (valid) { 84 this.findLoading = true 85 this.loadingData = '数据正在加载中...' 86 const data = { 87 ... 88 PageIndex = this.currentPage // 传给后端接口的页码 89 PageSize = this.pageSize // 查询返回多少条记录 90 ... 91 } 92 GetReportTransInfo(data).then(res => { 93 this.total = res.RowCount 94 this.reportTransInfos = res.ReportTransEntities 95 // 勾选的index值,确保唯一性,避免控制台包重复的key 96 this.reportTransInfos.forEach((item, i) => { 97 item.index = this.currentPage.toString() + i.toString() 98 }) 99 this.findLoading = false 100 }).catch(error => { 101 // do something... 102 }) 103 } 104 }) 105 }, 106 107 // 全选单选多选 108 selsChange(sels) { 109 this.sels = sels 110 }, 111 exportExcel() { 112 if (this.sels.length) { 113 this.findLoading = true 114 this.loadingData = '正在导出数据...' 115 import('@/vendor/Export2Excel').then(excel => { 116 const tHeader = [] 117 const filterVal = [] 118 this.thead.forEach(item => { 119 tHeader.push(item.title) 120 filterVal.push(item.field) 121 }) 122 const list = this.sels 123 const data = this.formatJson(filterVal, list) 124 excel.export_json_to_excel({ 125 header: tHeader, 126 data, 127 filename: this.filename, 128 autoWidth: this.autoWidth 129 }) 130 this.$refs.multipleTable.clearSelection() 131 this.findLoading = false 132 }) 133 } else { 134 this.$message({ 135 message: '请至少勾选一条记录', 136 type: 'warning' 137 }) 138 } 139 }, 140 formatJson(filterVal, jsonData) { 141 return jsonData.map(v => filterVal.map(j => v[j])) 142 } 143 } 144 } 145 </script>
article5. 基于UI 实现表单查询弹出框table列表单选功能
1 <template> 2 <section class="app-container"> 3 4 <!-- 弹出框 --> 5 <el-dialog title="" :visible.sync="dialogFormVisible"> 6 <el-table :data="locations.slice((currentPage-1)*pageSize,currentPage*pageSize)" :height="tableHeight" 7 size="mini" border @row-click="getSingleRow" v-loading="dialogLoading" element-loading-text="数据加载中"> 8 <el-table-column width="50" align="center"> 9 <template slot-scope="scope"> 10 <el-radio v-model="radio" :label="scope.row"> </el-radio> <!-- 空格符用来因此数字index --> 11 </template> 12 </el-table-column> 13 <el-table-column v-for="v in inv_thead" :prop="v.field" :label="v.title" :key="v.field" :width="v.width"> 14 </el-table-column> 15 </el-table> 16 <el-col :span="24" class="toolbar"> 17 <el-pagination background 18 @size-change="handleLocSize" 19 @current-change="handleLocCurrent" 20 :current-page=currentPage 21 :page-sizes="[50, 100, 200, 500]" 22 :page-size=pageSize 23 layout="total, sizes, prev, pager, next, jumper" 24 :total=total> 25 </el-pagination> 26 </el-col> 27 28 <div slot="footer" class="dialog-footer"> 29 <el-button size="mini" type="primary" @click="dialog">确 定</el-button> 30 <el-button size="mini" @click="dialogFormVisible = false">取 消</el-button> 31 </div> 32 </el-dialog> 33 34 </section> 35 </template> 36 37 <script> 38 // ... 39 export default { 40 name: 'index', 41 data() { 42 return { 43 locations: [], 44 dialogFormVisible: false, 45 radio: '', 46 selected: {}, 47 dialogLoading: false, 48 total: 0, 49 pageSize: 50, 50 currentPage: 1 51 } 52 }, 53 methods: { 54 getSingleRow(row) { 55 this.radio = this.locations.indexOf(row) 56 this.selected = row 57 }, 58 dialog() { 59 if (this.selected.LocCode) { 60 this.$set(this.filters, 'LocCode', this.selected.LocCode) // 将单选中的数据的那个字段值回显到form输入表单中 61 this.dialogFormVisible = false 62 } else { 63 this.$message({ 64 message: '请先选择数据', 65 type: 'warning' 66 }) 67 } 68 } 69 } 70 } 71 </script>
article6.对于多表单查询弹出框且多页面使用时可组件引入