vue2 element使用笔记总结
element
A Vue.js 2.0 UI Toolkit for Web
项目地址:https://gitcode.com/gh_mirrors/eleme/element
免费下载资源
·
1、 select组件,值改变,无法更改label值
解决:绑定change事件,
Change() {
this.$forceUpdate();
},
2、el-tree组件文字超出容器不出现横向滚动条问题
.el-tree>.el-tree-node{
min-width:100%;
display: inline-block;
}
3.组件绑定原生事件使用 .native
修饰符
<el-button
size="small"
type="text"
@click.native.prevent="handleEdit($index, row)">打印日结单
</el-button>
4、时间选择器禁用日期通过 disabledDate
设置
<el-date-picker
v-model="value2"
align="right"
type="date"
placeholder="选择日期"
:picker-options="pickerOptions">
</el-date-picker>
<script>
export default {
data() {
return {
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now();
},
},
value2: '',
};
}
};
</script>
5、表单手机号、身份证校验规则
//1、校验身份证
export const checkIdNumberValid=(tex)=>{
var tip = '输入的身份证号有误!';
var num = tex;
num = num.toUpperCase();
var len, re;
len = num.length;
if(len == 0) return true;
//身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X。
if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(num))){
return false;
}
//验证前两位地区是否有效
var aCity= {11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",
32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",
44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",
62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"}
if(aCity[parseInt(num.substr(0,2))] == null){
return false;
}
//当身份证为15位时的验证出生日期。
if (len == 15){
re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/);
var arrSplit = num.match(re);
//检查生日日期是否正确
var dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4]);
var bGoodDay;
bGoodDay = (dtmBirth.getYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]));
if (!bGoodDay){
return false;
}
}
//当身份证号为18位时,校验出生日期和校验位。
if (len == 18){
re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/);
var arrSplit = num.match(re);
//检查生日日期是否正确
var dtmBirth = new Date(arrSplit[2] + "/" + arrSplit[3] + "/" + arrSplit[4]);
var bGoodDay;
bGoodDay = (dtmBirth.getFullYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]));
if (!bGoodDay){
return false;
}
else{
//检验18位身份证的校验码是否正确。
//校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
var valnum;
var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
var nTemp = 0, i;
for(i = 0; i < 17; i ++){
nTemp += num.substr(i, 1) * arrInt[i];
}
valnum = arrCh[nTemp % 11];
if (valnum != num.substr(17, 1)){
return false;
}
}
}
return true;
}
//2、
let idCardValidity = (rule, code, callback) => {
var city = { 11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江 ", 31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北 ", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏 ", 61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外 " };
var tip = ""
var pass = true
if (!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)) {
tip = "身份证号格式错误"
pass = false;
} else if (!city[code.substr(0, 2)]) {
tip = "地址编码错误"
pass = false
} else {
// 18位身份证需要验证最后一位校验位
if (code.length === 18) {
code = code.split('')
// ∑(ai×Wi)(mod 11)
// 加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
// 校验位
var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
var sum = 0
var ai = 0
var wi = 0
for (var i = 0; i < 17; i++) {
ai = code[i]
wi = factor[i]
sum += ai * wi
}
var last = parity[sum % 11];
if (parity[sum % 11] != code[17]) {
tip = "校验位错误"
pass = false
}
}
}
if (!pass) {
callback(new Error(tip))
} else {
callback()
}
// if (!pass) alert(tip)
// return pass
}
idCard: [{ required: true, message: '请输入证件号', trigger: 'blur' },
{
pattern: /(^\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)|(^\d{6}(18|19|20)\d{2}(0\d|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)$)/,
message: '请输入正确的证件号'
},
{ validator: idCardValidity, trigger: 'blur' }],
}
//校验手机号
var checkPhone = (rule, value, callback) => {
if (!value) {
return callback(new Error('手机号不能为空'));
} else {
const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
console.log(reg.test(value));
if (reg.test(value)) {
callback();
} else {
return callback(new Error('请输入正确的手机号'));
}
}
};
//校验手机号或者座机号
var checkPhone = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入联系人电话'));
} else {
let regPone = null;
let mobile = /^1(3|4|5|6|7|8|9)\d{9}$/; //最新16手机正则
let tel = /^(0[0-9]{2,3}\-)([2-9][0-9]{4,7})+(\-[0-9]{1,4})?$/; //座机
if (value.charAt(0) == 0) { // charAt查找第一个字符方法,用来判断输入的是座机还是手机号
regPone = tel;
} else {
regPone = mobile;
}
if (!regPone.test(value)) {
return callback(
new Error("请填写正确的座机/手机号")
);
}
callback();
}
};
6、upload图片上传2种方式
//头像上传
<el-upload
class="avatar-uploader"
:action="UploadUrl()"
ref="upLoad"
accept="image/png, image/jpg, image/jpeg, image/bmp"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img v-if="this.avatar" :src="this.avatar" class="avatar_img" />
<el-avatar v-else :src="src1"></el-avatar>
</el-upload>
//methods
UploadUrl(){
return
`http://shequ.goufangbian.com.cn/fengheapi/app/uploadImage/${this.$route.query.userId}`
},
handleAvatarSuccess(res, file) {
console.log("上传图片", res);
if (res.code == 0) {
this.avatar = res.data;
this.$toast.success("上传成功!");
}
},
beforeAvatarUpload(file) {
const type =
file.type === "image/jpeg" || "image/jpg" || "image/bmp" || "image/png";
const isLt2M = file.size / 1024 / 1024 < 10;
if (!type) {
this.$toast.fail("上传图片格式PNG、JPG、JPEG、BMP!");
}
if (!isLt2M) {
this.$toast.fail("上传图片大小不能超过 10MB!");
}
return type && isLt2M;
},
//图片数量限制
<el-form-item label="图片上传(最多只可以上传3张)">
<el-upload
class="avatar-uploader"
action="customize"
ref="upLoad"
list-type="picture"
:accept="'image/*'"
capture="camera"
:http-request="upLoad"
:show-file-list="true"
:file-list="ruleForm.imageList"
:on-exceed="handleExceed"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:limit="3">
<i class="el-icon-upload avatar-uploader-icon"></i>
<div class="el-upload__tip" slot="tip">支持jpg/png/bmp文件,且不超过10M</div>
</el-upload>
</el-form-item>
//methods
upLoad(params){
// 通过 FormData 对象上传文件
const _file = params.file;
var formData = new FormData();
formData.append("file", _file);
updataImg(formData).then(res => {
if(res.code == 0){
this.disabledFlg = false
this.ruleForm.imageList.push(res.page.url)
this.$message.success('图片上传成功!');
}else{
this.$message.error(res.msg);
}
});
},
handleAvatarSuccess(res, file) {
//this.form.pic = URL.createObjectURL(file.raw);
console.log(this.form.pic)
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${fileList.length} 个文件`);
},
beforeRemove(file, fileList) {
//return this.$confirm(`确定移除 ${ file.name }?`);
},
beforeAvatarUpload(file) {
//const isJPG = file.type === 'image/jpeg';
const testmsg = /^image\/(jpeg|png|jpg|bmp)$/.test(file.type)
const isLt10M = file.size / 1024 / 1024 < 10;
if (!testmsg) {
this.$message.error('上传图片格式不对!')
return false
}
if (!isLt10M) {
this.$message.error('上传头像图片大小不能超过 10MB!');
}
return testmsg && isLt10M;
},
7.select input 表单校验是 赋值后仍提示校验不通过,需要在初始化时将该字段初始化上,并且如果绑定的值是Number类型,赋值成空字符串也会报错
8、input @input 事件 防抖函数 避免多次触发 (使用loadsh函数)
cnpm i loadsh --save
import _ from "loadsh";
<el-table-column label="价格" align="center">
<template slot-scope="{ row, $index }">
<el-input
:readonly="row.asFixPrice == 0 ? false : true"
v-model="row.itemPrice"
type="number"
@input="changePrice(row)"
></el-input>
</template>
</el-table-column>
//修改价格
changePrice: _.debounce(async row => {
row.itemCharge = Number(row.itemPrice) * Number(row.itemNumber);
let params = {
id: row.id,
itemPrice: row.itemPrice,
itemNumber: row.itemNumber,
itemCharge: row.itemCharge
};
let res = await API["editPackageServiceLittleTypeById"](params);
console.log(res, "111");
if (res.code != 1) return Message.error(res.message);
Message.success(res.message);
}, 500),
9.树形结构默认选中第一子项,展示数据
let node = this.treeData[0].children[0];
this.$nextTick(() => {
// 默认高亮选中节点
this.$refs.tree.setCurrentKey(node.id);
this.$refs.tree.setCheckedNodes([node]);
});
10、强制刷新
this.$forceUpdate();
11、table 合计初始化不展示及设置高度
/deep/ .el-table{
// overflow:visible !important;
.el-table__body-wrapper{
overflow-y: scroll;
}
}
<el-table
:data="tableData"
border
:header-cell-style="{background:'rgb(246,247,251)',color:'#606266'}"
stripe
height="calc(100% - 340px)"
>
12、动态校验
<el-form-item v-if="needRequired" label="统一社会信用代码" :prop="
needRequired
? 'unitNo'
: 'noUnitNo'
">
<el-input
v-model="ruleForm.unitNo"
placeholder="请输人统一社会信用代码"
></el-input>
</el-form-item>
rules: {
unitNo:[
{ required: true, message: "请输入统一社会信用代码", trigger: "blur" },
],
noUnitNo:[
{ required: false },
],
}
watch: {
'ruleForm.unit' (newValue, oldValue) {
if(newValue){
this.needRequired=true
}else{
this.needRequired=false
}
}
},
13、上传
<!-- action 表示图片要上传到的后台API地址 -->
<el-upload :action="uploadURL" :on-preview="handlePreview" :on-remove="handleRemove" list-type="picture" :headers="headerObj" :on-success="handleSuccess">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
// 商品所属的分类数组
goods_cat: [],
// 图片的数组
pics: [],
// 商品的详情描述
goods_introduce: '',
attrs: []
},
// 上传图片的URL地址
uploadURL: 'http://127.0.0.1:8888/api/private/v1/upload',
// 图片上传组件的headers请求头对象
headerObj: {
Authorization: window.sessionStorage.getItem('token')
},
// 处理移除图片的操作
handleRemove(file) {
// console.log(file)
// 1. 获取将要删除的图片的临时路径
const filePath = file.response.data.tmp_path
// 2. 从 pics 数组中,找到这个图片对应的索引值
const i = this.addForm.pics.findIndex(x => x.pic === filePath)
// 3. 调用数组的 splice 方法,把图片信息对象,从 pics 数组中移除
this.addForm.pics.splice(i, 1)
console.log(this.addForm)
},
// 监听图片上传成功的事件
handleSuccess(response) {
console.log(response)
// 1. 拼接得到一个图片信息对象
const picInfo = { pic: response.data.tmp_path }
// 2. 将图片信息对象,push 到pics数组中
this.addForm.pics.push(picInfo)
console.log(this.addForm)
},
14、el-table 加loading效果,v-loading,分页disabled,table中图片加lazy;table 设置列为fixed后错位,fixed加上宽度,前一列不加宽度
15、控制table全选反选
<el-checkbox v-model="checkedAll" @change="checkedAllChange">全选</el-checkbox>
<el-table
:data="chargeData.nonTaxchargeItems"
:header-cell-style="{
background: 'rgb(246,247,251)',
color: '#606266'
}"
ref="table1"
stripe
style="width: 100%"
@selection-change="handleTable1SelectionChange"
>
....
</el-table>
<el-table
:data="chargeData.chargeItems"
:header-cell-style="{
background: 'rgb(246,247,251)',
color: '#606266'
}"
stripe
ref="table2"
style="width: 100%"
@selection-change="handleTable2SelectionChange"
>...
</el-table>
//data
checkedAll:false,//全选
checkedTable1All:false,//非税全选
checkedTable2All:false,//其他全选
//methods
//切换全选
checkedAllChange(val){
console.log(val,this.checkedAll,'全选')
if(val){
this.checkedTable1All=true
this.checkedTable2All=true
//非税
this.$nextTick(() => {
for (let i = 0; i < this.chargeData.nonTaxchargeItems.length; i++) {
this.$refs.table1.toggleRowSelection(
this.chargeData.nonTaxchargeItems[i],
true
);
}
});
//其他费用
this.$nextTick(() => {
for (let i = 0; i < this.chargeData.chargeItems.length; i++) {
this.$refs.table2.toggleRowSelection(
this.chargeData.chargeItems[i],
true
);
}
});
}else{
this.checkedTable1All=false
this.checkedTable2All=false
//非税
this.$nextTick(() => {
for (let i = 0; i < this.chargeData.nonTaxchargeItems.length; i++) {
this.$refs.table1.toggleRowSelection(
this.chargeData.nonTaxchargeItems[i],
false
);
}
});
//其他费用
this.$nextTick(() => {
for (let i = 0; i < this.chargeData.chargeItems.length; i++) {
this.$refs.table2.toggleRowSelection(
this.chargeData.chargeItems[i],
false
);
}
});
}
this.checkedAll=val
},
//非税
handleTable1SelectionChange(val){
//console.log(val,'非税',val.length==this.chargeData.nonTaxchargeItems.length)
if(val.length==this.chargeData.nonTaxchargeItems.length){
this.checkedTable1All=true
}
else{
this.checkedTable1All=false
}
this.handleSelectionChange(val)
},
//其他
handleTable2SelectionChange(val){
//console.log(val,'其他',val.length==this.chargeData.chargeItems.length)
if(val.length==this.chargeData.chargeItems.length){
this.checkedTable2All=true
}
else{
this.checkedTable2All=false
}
this.handleSelectionChange(val)
},
//处理数据
handleSelectionChange(val) {
console.log(val,'处理')
let itemArray = [];
let totalLocal = 0;
val.forEach(item => {
//未结算的
if (item.asSettled == 0) {
//计算总金额
totalLocal += Number(item.itemCharge);
itemArray.push(item);
}
});
this.multipleSelection=[...this.multipleSelection,...itemArray];
this.totalCharge += totalLocal;
},
//watch
watch: {
//非税
checkedTable1All(val){
console.log('非税',val,this.checkedTable2All)
if(val&&this.checkedTable2All){
this.checkedAll=true
}
else{
this.checkedAll=false
}
},
//其他
checkedTable2All(val){
console.log('其他',val,this.checkedTable1All)
if(val&&this.checkedTable1All){
this.checkedAll=true
}
else{
this.checkedAll=false
}
},
}
16、表格固定列最后一行显示不全
.el-table__fixed-right {
height: 100% !important;
}
17、输入框用正则限制但绑定值未更新
<el-input
v-model="form.name"
placeholder="请输入"
@keyup.native="form.name=form.name.replace(/[^\d.]/g,'')"
/>
18、去除type="number"输入框聚焦时的上下箭头及type=number
输入中文,焦点上移
<el-input class="clear-number-input" type="number"></el-input>
//去除箭头
.clear-number-input ::v-deep input[type="number"]::-webkit-outer-spin-button,
.clear-number-input ::v-deep input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none !important;
}
//上移
::v-deep .el-input__inner {
line-height: 1px !important;
}
<el-input type="number" class="clear-number-input" />
19、只校验表单其中一个字段
this.$refs['form'].validateField('mobile', valid => {
if (valid) {
// 发送验证码
}
})
//多值参数传数组
20、表格跨分页多选
<el-table row-key="id">
<el-table-column type="selection" reserve-selection></el-table-column>
</el-table>
21、表单不想显示label但又想显示必填星号怎么办 label=' '
22、el-tree 展开/收起所有节点
<el-tree ref="tree"></el-tree>
expandTree(expand = true) {
const nodes = this.$refs['tree'].store._getAllNodes()
nodes.forEach(node => {
node.expanded = expand
})
}
23、el-popover 位置偏移问题
<el-popover ref="popover" placement="left" trigger="click">
</el-popover>
// 获取数据后
this.$nextTick(() => {
this.$refs['popover'].updatePopper()
})
24、el-dialog 的 destroy-on-close 属性设置无效
<el-dialog :visible.sync="visible" v-if="visible" destroy-on-close>
</el-dialog>
25、el-cascader 选择后需要点击空白处才能关闭
<el-cascader
ref="cascader"
@change="onChange"
/>
onChange() {
this.$refs['cascader'].dropDownVisible = false
}
26、点击按钮使用图片查看器
<template>
<section>
<el-button @click="open">打开图片预览</el-button>
<el-image-viewer
v-if="show"
:on-close="onClose"
:url-list="urls"
:initial-index="initialIndex"
/>
</section>
</template>
<script>
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
export default {
components: {
ElImageViewer
},
data() {
return {
show: false,
urls: ['https://img0.baidu.com/it/u=391928341,1475664833&fm=26&fmt=auto&gp=0.jpg'],
initialIndex: 0
}
},
methods: {
open() {
this.show = true
},
onClose() {
this.show = false
}
}
}
</script>
27、时间选择器限制
<el-form-item label="预约时间">
<el-date-picker
type="datetime"
placeholder="选择开始时间"
v-model="ruleForm.arrivalTime"
format="yyyy-MM-dd HH:mm"
value-format="yyyy-MM-dd HH:mm"
:picker-options="startDatePicker"
></el-date-picker
>-
<el-date-picker
type="datetime"
placeholder="选择结束时间"
v-model="ruleForm.endArrivalTime"
format="yyyy-MM-dd HH:mm"
value-format="yyyy-MM-dd HH:mm"
:picker-options="endDatePicker"
></el-date-picker>
</el-form-item>
data() {
return {
startDatePicker:this.beginDate(),
endDatePicker: this.processDate(),
}},
methods:{
beginDate() {
const self = this;
return {
disabledDate(time) {
console.log(time.getTime(),'选择时间1')
return time.getTime() > Date.now()
}
};
},
processDate() {
const self = this;
return {
disabledDate(time) {
return time.getTime() < Date.now()- 8.64e7;
}
};
},
}
28、表单提交刷新及input type 更改
<el-form
ref="form"
auto-complete="on"
@submit.native.prevent
:model="form"
label-width="0"
:rules="rules"
>
<div class="login_title">
<h2>武清区殡仪车辆监控平台</h2>
<h4 class="little_title">
Wuqing District Funeral vehicle monitoring platform
</h4>
</div>
<div class="login_input">
<el-form-item label="" prop="name">
<el-input
:key="passwordType"
:type="passwordType"
ref="password"
placeholder="请输入账号"
prefix-icon="el-icon-user"
v-model="form.name"
name="name"
tabindex="1"
auto-complete="on"
@keyup.enter.native="login"
>
<i
slot="suffix"
@click="showPwd"
class="iconfont"
:class="
passwordType === 'password' ? 'icon-no_eye' : 'icon-eye'
"
></i>
</el-input>
</el-form-item>
</div>
<div class="login_btn_box">
<el-button
:loading="loading"
class="login_btn"
type="primary"
style="width: 100%; margin-bottom: 30px;"
@click.native.prevent="login"
>登录</el-button
>
</div>
</el-form>
import * as API from "../api/map";
export default {
data() {
return {
loading: false,
form: {
name: "",
},
rules: {
name: [{ required: true, message: "请输入账号", trigger: "blur" }],
},
passwordType: "password",
};
},
methods: {
showPwd() {
if (this.passwordType === "password") {
this.passwordType = "";
} else {
this.passwordType = "password";
}
this.$nextTick(() => {
this.$refs.password.focus();
});
},
login() {
this.$refs.form.validate(async (valid) => {
if (valid) {
this.loading = true;
let res = await API["login"]({ ...this.form });
this.loading = false;
if (res.code !== 1) return this.$message.error(res.message);
sessionStorage.setItem("gps_token", res.data);
this.$router.push("/home");
} else {
console.log("error submit!!");
return false;
}
});
},
},
};
29、el-upload 模拟点击
有时候我们想用 el-upload
的上传功能,但又不想用 el-upload
的样式,如何实现呢?方法也很简单,隐藏 el-upload
,然后再模拟点击就可以了。
30、el-input 设置值后不能修改
this.$set(this.form, 'description', '')
31、Table 单行根据数据状态禁止选择
<el-table-column
type="selection"
:selectable='canCheck'
width="55">
</el-table-column>
canCheck(row){
if(row.processState=='已出藏'){
return false
}else{
return true
}
},
32、table 默认选中
this.$nextTick(() => {
this.tableData.forEach(
(item) => {
if (item.asSettled == 0) {
//未结算的默认选中
this.$refs.multipleTable[0].toggleRowSelection(item, true);
}
}
);
});
33、 table fixed 错位
<el-table
ref="filetable"
:data="tableData"
:header-cell-style="{
background: 'rgb(246,247,251)',
color: '#606266',
}"
:height="tableHeight"
border
@selection-change="handleSelectionChange">
</el-table>
watch: {
tableData(val){
this.doLayout();
},
},
methods: {
//
doLayout(){
this.$nextTick(() => {
this.$refs.filetable.doLayout()
})
},
}
34、table 点击行变颜色、选中变颜色
<el-table
ref="refTableDom"
:data="tableData"
:row-class-name="tableRowClassName"
border
:stripe="false"
:row-style="rowStyle"
@row-click='rowClick'
>
<el-table-column type="selection" align="center" width="55">
</el-table-column>
</el-table>
rowClick(row, column, event){
console.log(row,column, event,'点击')
let index = this.tableData.findIndex(x=>x==row)
console.log(index,'点击')
this.rowIndex = index
},
rowStyle ({ row, rowIndex }) {
if (this.rowIndex === rowIndex) {
return {
'background-color': 'green !important',
"color":"#fff!important"
}
}
},
tableRowClassName({ row, rowIndex }) {
for(let i=0;i<this.multipleSelection.length;i++) {
if (row === this.multipleSelection[i]) {
return 'bg-row';
}
}
if (row.deadGiveStateName == "未交接") {
return "no-handover";
} else if(row.deadGiveStateName == "已交接") {
return "has-handover";
}else{
return ''
}
},
去除hover样式
.el-table--enable-row-hover .el-table__body tr:hover > td {
background-color: inherit!important;
}
35、table合并行
spanArr:[],
position:0,
spanArr2:[],
position2:0,
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
if (columnIndex === 1) {
const _row = this.spanArr2[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
},
getSpanArr(data){
data.forEach((item, index) => {
if (index === 0) {
this.spanArr.push(1);
this.position = 0;
this.spanArr2.push(1);
this.position2 = 0;
} else {
// 判断当前元素与上一个元素是否相同
if (data[index].businessCode === data[index - 1].businessCode) {
this.spanArr[this.position] += 1;
this.spanArr.push(0);
} else {
this.spanArr.push(1);
this.position = index;
}
//姓名
if (data[index].deadName === data[index - 1].deadName) {
this.spanArr2[this.position2] += 1;
this.spanArr2.push(0);
} else {
this.spanArr2.push(1);
this.position2 = index;
}
}
})
},
36、多个table切换 合并的表头样式变乱
1、v-show代替v-if
2、使用v-if 并且给el-table加不同的key
<!-- 骨灰盒 -->
<el-table
key='tableData'
v-if="ruleForm.itemType==0"
:data="tableData"
:span-method="objectSpanMethod"
id='tableData'
height="calc(100% - 40px)"
:header-cell-style="{
background: '#ccc',
color: '#606266'
}"
stripe
border
ref="Table"
>
</el-table>
<!-- 纸棺 -->
<el-table
v-if="ruleForm.itemType==1"
:data="tableData1"
key='tableData1'
id='tableData1'
:span-method="objectSpanMethod"
height="calc(100% - 40px)"
:header-cell-style="{
background: '#ccc',
color: '#606266'
}"
stripe
border
ref="Table"
>
</el-table>
37、table合并单元格、切换 、打印、导出
请求数据
//改变物品类型
changeType(){
this.tableData=[];
this.tableData1=[];
this.spanArr=[]
this.position=0
// this.onSubmit()
},
//查询
async onSubmit() {
this.loading = true;
let postData = {
...this.ruleForm,
queryDate:this.$dayjs(this.ruleForm.queryDate).format("YYYY-MM")
};
//查询接口
let res = await Type["listStockCheck"](postData)
this.loading = false;
if(res.code !==1) return this.$message.error(res.message)
// this.tableData = res.data.list
if(this.ruleForm.itemType==0){
//骨灰盒
this.getSpanArr(res.data)
this.tableData = this.colspanMethod(res.data)
}else{
//纸棺
this.getSpanArr(res.data)
this.tableData1 = this.colspanMethod(res.data)
}
},
表格合并展示
//
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
},
//
getSpanArr(data){
data.forEach((item, index) => {
if (index === 0) {
this.spanArr.push(1);
this.position = 0;
} else {
// 判断当前元素与上一个元素是否相同
if (data[index].supplierName === data[index - 1].supplierName) {
this.spanArr[this.position] += 1;
this.spanArr.push(0);
} else {
this.spanArr.push(1);
this.position = index;
}
}
})
},
表格导出
import FileSaver from "file-saver";
import XLSX from "xlsx";
//导出
exportExcel() {
let xlsxParam = { raw: true };
let name =''
let time = this.$dayjs(this.ruleForm.queryDate).format("YYYY-MM")
let wb={}
if(this.ruleForm.itemType==0){
if( this.tableData.length==0) return this.$message('暂无数据导出')
//骨灰盒
wb= XLSX.utils.table_to_book(
document.querySelector("#tableData"),
xlsxParam
);
name='骨灰盒盘点表'
}else{
//纸棺
if( this.tableData1.length==0) return this.$message('暂无数据导出')
wb= XLSX.utils.table_to_book(
document.querySelector("#tableData1"),
xlsxParam
);
name='纸棺盘点表'
}
/* 从表生成工作簿对象 */
/* 获取二进制字符串作为输出 */
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
try {
FileSaver.saveAs(
//Blob 对象表示一个不可变、原始数据的类文件对象。
//Blob 表示的不一定是JavaScript原生格式的数据。
//File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
//返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。
new Blob([wbout], { type: "application/octet-stream" }),
//设置导出文件名称
`${name}${(new Date()).valueOf()}.xlsx`
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
return wbout;
},
Clodop打印表格
// 合并行
colspanMethod(dataList) {
for (let i = 0; i < dataList.length; i++) {
// 循环开始行
let startRow
// 需合并的行数
let rowspan = 1
// 循环到最后一行时
if (i === dataList.length - 1) {
// 如果最后一行和倒数第二行属性不同,则rowspan=1;否则直接结束循环
if (dataList[i].supplierName !== dataList[i - 1].supplierName) {
dataList[i].rowspan = rowspan
}
break
}
// 内层循环记录rowspan的数量
for (let j = i; j < dataList.length - 1; j++) {
// 记录循环结束的行数
startRow = j
// 属性相同则rowspan+1;否则直接结束内循环
if (dataList[j].supplierName === dataList[j + 1].supplierName) {
rowspan++
} else {
break
}
}
// 为数组添加rowspan属性
dataList[i].rowspan = rowspan
// 控制外循环从内循环结束的行数开始
i = startRow
}
return dataList
},
//打印
printForm(){
if(this.ruleForm.itemType == 0&&this.tableData.length==0) return this.$message('暂无数据打印');
if(this.ruleForm.itemType == 1&&this.tableData1.length==0) return this.$message('暂无数据打印');
let LODOP = getLodop();
if (LODOP == null || !LODOP) {
this.$.messager.alert(
"系统提示",
"您的浏览器不支持打印控件,请用IE重试或安装打印控件后重试"
);
return;
}
let printDate = this.$dayjs(this.ruleForm.queryDate).format("YYYY年MM月")
let tbody=''
let html =''
let goodName=''
if(this.ruleForm.itemType == 0){
goodName=`${printDate}骨灰盒盘点表`
//骨灰盒
this.tableData.forEach((item,index)=>{
if(item.rowspan){
tbody+=`
<tr>
<td style="padding:5px 0;">${index+1}</td>
<td style="padding:0 5px;" rowspan="${item.rowspan}">${item.supplierName || ''}</td>
<td>${item.itemName || ''}</td>
<td>${item.itemUnit||'' }</td>
<td>${item.itemPrice||'' }</td>
<td>${item.mainStore||'' }</td>
<td>${item.cremationStore||'' }</td>
<td></td>
<td>${item.xueLingStore||'' }</td>
<td>${item.totalNumber||'' }</td>
</tr>
`
}else{
tbody+=`
<tr>
<td style="padding:5px 0;">${index+1}</td>
<td>${item.itemName || ''}</td>
<td>${item.itemUnit||'' }</td>
<td>${item.itemPrice||'' }</td>
<td>${item.mainStore||'' }</td>
<td>${item.cremationStore||'' }</td>
<td></td>
<td>${item.xueLingStore||'' }</td>
<td>${item.totalNumber||'' }</td>
</tr>
`
}
})
html+=`
<div style="width:100%;height:100%;padding:0 10px;box-sizing: border-box;">
<p style="font-size: 20px;text-align:center;line-height:30px;box-sizing: border-box;">${goodName}</p>
<table border='1' style='border-collapse: collapse;text-align:center;width: 100%;font-size:12px'>
<thead>
<tr style="font-size:14px">
<th style="padding:0 5px;" rowspan="2">序号</th>
<th rowspan="2">供应商</th>
<th rowspan="2">名称</th>
<th rowspan="2">单位</th>
<th rowspan="2">售价</th>
<th rowspan="2">总仓</th>
<th colspan="2">火化小仓</th>
<th rowspan="2">薛岭仓</th>
<th rowspan="2">合计</th>
</tr>
<tr style="font-size:14px">
<th>盘点数</th>
<th>扣30日销售未出库</th>
</tr>
</thead>
<tbody>
${tbody}
</tbody>
</table>
</div>
`
}else{
console.log(this.tableData1,'555')
//纸棺
goodName=`${printDate}纸棺盘点表`
this.tableData1.forEach((item,index)=>{
console.log(item.rowspan)
if(item.rowspan){
tbody+=`
<tr>
<td style="padding:5px 0;">${index+1}</td>
<td style="padding:0 5px;" rowspan="${item.rowspan}">${item.supplierName || ''}</td>
<td>${item.financialCode || ''}</td>
<td>${item.itemName||'' }</td>
<td>${item.itemUnit||'' }</td>
<td>${item.inPrice ||''}</td>
<td>${item.itemPrice ||'' }</td>
<td>${item.retailStore ||'' }</td>
<td>${item.coldStore ||''}</td>
<td></td>
<td>${item.carStore ||''}</td>
<td></td>
<td>${item.totalNumber ||''}</td>
</tr>
`
}else{
tbody+=`
<tr>
<td style="padding:5px 0;">${index+1}</td>
<td>${item.financialCode || ''}</td>
<td>${item.itemName||'' }</td>
<td>${item.itemUnit||'' }</td>
<td>${item.inPrice ||''}</td>
<td>${item.itemPrice ||'' }</td>
<td>${item.retailStore ||'' }</td>
<td>${item.coldStore ||''}</td>
<td></td>
<td>${item.carStore ||''}</td>
<td></td>
<td>${item.totalNumber ||''}</td>
</tr>
`
}
})
html+=`
<div style="width:100%;height:100%;padding:0 10px;box-sizing: border-box;">
<p style="font-size: 20px;text-align:center;line-height:30px;box-sizing: border-box;">${goodName}</p>
<table border='1' style='border-collapse: collapse;text-align:center;width: 100%;font-size:12px'>
<thead>
<tr style="font-size:14px">
<th style="padding:0 5px;" rowspan="2">序号</th>
<th rowspan="2">供应商</th>
<th rowspan="2">财务编码</th>
<th rowspan="2">名称</th>
<th rowspan="2">单位</th>
<th rowspan="2">进价</th>
<th rowspan="2">售价</th>
<th rowspan="2">零售仓</th>
<th colspan="2">防腐整容组仓</th>
<th colspan="2">收殓组仓</th>
<th rowspan="2">合计</th>
</tr>
<tr style="font-size:14px">
<th>盘点数</th>
<th>扣30日销售未出库</th>
<th>盘点数</th>
<th>扣30日销售未出库</th>
</tr>
</thead>
<tbody>
${tbody}
</tbody>
</table>
</div>
`
}
LODOP.SET_PRINT_PAGESIZE(1,"210mm","297mm" ,"")
// LODOP.SET_SHOW_MODE("LANDSCAPE_DEFROTATED",1);
LODOP.ADD_PRINT_HTM(0, 0, "100%", "100%", html);
LODOP.PREVIEW();
},
完整代码
<template>
<!-- 库存盘点表 -->
<div class="inventoryCounting stock-wrap h100" v-loading="loading">
<div class="PageContent">
<div class="PageItem ">
<el-row class="btn-wrap fileSearch">
<el-form :inline="true" :model="ruleForm" label-width="80px" class="checkForm">
<el-form-item label="物品类型:">
<el-select
class="check_input"
v-model="ruleForm.itemType"
placeholder=""
@change="changeType"
>
<el-option v-for="item in types" :key='item.value' :label="item.label" :value='item.value'></el-option>
</el-select>
</el-form-item>
<el-form-item label="月份:">
<el-date-picker
v-model="ruleForm.queryDate"
type="month"
:clearable="false"
placeholder="选择月">
</el-date-picker>
</el-form-item>
<el-button size="mini" type="primary" @click="onSubmit()">查询</el-button>
<el-button size="mini" type="primary" @click="exportExcel()">导出</el-button>
<el-button size="mini" type="primary" @click="printForm()">打印</el-button>
</el-form>
</el-row>
<!-- 骨灰盒 -->
<el-table
key='tableData'
v-if="ruleForm.itemType==0"
:data="tableData"
:span-method="objectSpanMethod"
id='tableData'
height="calc(100% - 40px)"
:header-cell-style="{
background: '#ccc',
color: '#606266'
}"
stripe
border
ref="Table"
>
<el-table-column
align="center"
type="index"
label="序号"
>
</el-table-column>
<el-table-column
align="center"
prop="supplierName"
label="供应商"
>
</el-table-column>
<el-table-column
prop="itemName"
align="center"
label="名称"
>
</el-table-column>
<el-table-column
prop="itemUnit"
align="center"
label="单位"
>
</el-table-column>
<el-table-column
prop="itemPrice"
align="center"
label="售价"
>
</el-table-column>
<el-table-column
prop="mainStore"
align="center"
label="总仓 "
>
</el-table-column>
<el-table-column
align="center"
label="火化小仓"
width="300px"
>
<el-table-column
prop="cremationStore"
align="center"
label="盘点数 "
width="80px"
>
</el-table-column>
<el-table-column
prop=""
align="center"
label="扣30日销售未出库 "
>
</el-table-column>
</el-table-column>
<el-table-column
prop="xueLingStore"
align="center"
label="薛岭仓 "
>
</el-table-column>
<el-table-column
prop="totalNumber"
align="center"
label="合计 "
>
</el-table-column>
</el-table>
<!-- 纸棺 -->
<el-table
v-if="ruleForm.itemType==1"
:data="tableData1"
key='tableData1'
id='tableData1'
:span-method="objectSpanMethod"
height="calc(100% - 40px)"
:header-cell-style="{
background: '#ccc',
color: '#606266'
}"
stripe
border
ref="Table"
>
<el-table-column
align="center"
type="index"
label="序号"
>
</el-table-column>
<el-table-column
align="center"
prop="supplierName"
label="供应商"
width="100"
>
</el-table-column>
<el-table-column
align="center"
prop="financialCode"
label="财务编码"
width="100"
>
</el-table-column>
<el-table-column
prop="itemName"
align="center"
label="名称"
>
</el-table-column>
<el-table-column
prop="itemUnit"
align="center"
label="单位"
width="60"
>
</el-table-column>
<el-table-column
prop="inPrice"
align="center"
label="进价"
width="60"
>
</el-table-column>
<el-table-column
prop="itemPrice"
align="center"
label="售价"
width="60"
>
</el-table-column>
<el-table-column
prop="retailStore"
align="center"
label="零售仓"
width="60"
>
</el-table-column>
<el-table-column
align="center"
label="防腐整容组仓"
width="300"
>
<el-table-column
prop="coldStore"
align="center"
label="盘点数"
width="80px"
>
</el-table-column>
<el-table-column
prop=""
align="center"
label="扣30日销售未出库"
>
</el-table-column>
</el-table-column>
<el-table-column
align="center"
label="收殓组仓"
width="300px"
>
<el-table-column
prop="carStore"
align="center"
label="盘点数 "
width="80px"
>
</el-table-column>
<el-table-column
prop=""
align="center"
label="扣30日销售未出库 "
>
</el-table-column>
</el-table-column>
<el-table-column
prop="totalNumber"
align="center"
label="合计 "
width="60"
>
</el-table-column>
</el-table>
<!-- <p style="text-align: right; margin-top: 10px">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pager.currentPage"
:page-size="pager.pageSize"
:page-sizes="[20,30,40,50,60]"
background
layout="total,sizes, prev, pager, next, jumper"
:total="pager.total"
>
</el-pagination>
</p> -->
</div>
</div>
</div>
</template>
<script>
import * as Type from "@/api/service";
import FileSaver from "file-saver";
import XLSX from "xlsx";
import { getLodop } from "@/utils/lodopFuncs";
export default {
name: "inventoryCounting",
data() {
return {
types:[{
label:'骨灰盒',
value:0
},
{
label:'纸棺',
value:1
}],
pager: {
pageSize: 20,
total: 0,
currentPage: 1
},
ruleForm: {
itemType:0,
queryDate:new Date()
},
tableData: [], // 表单展示数据
tableData1: [], // 表单展示数据
spanArr:[],
position:0
};
},
created() {
this.onSubmit();
},
methods: {
//
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
},
//
getSpanArr(data){
data.forEach((item, index) => {
if (index === 0) {
this.spanArr.push(1);
this.position = 0;
} else {
// 判断当前元素与上一个元素是否相同
if (data[index].supplierName === data[index - 1].supplierName) {
this.spanArr[this.position] += 1;
this.spanArr.push(0);
} else {
this.spanArr.push(1);
this.position = index;
}
}
})
},
//打印
printForm(){
if(this.ruleForm.itemType == 0&&this.tableData.length==0) return this.$message('暂无数据打印');
if(this.ruleForm.itemType == 1&&this.tableData1.length==0) return this.$message('暂无数据打印');
let LODOP = getLodop();
if (LODOP == null || !LODOP) {
this.$.messager.alert(
"系统提示",
"您的浏览器不支持打印控件,请用IE重试或安装打印控件后重试"
);
return;
}
let printDate = this.$dayjs(this.ruleForm.queryDate).format("YYYY年MM月")
let tbody=''
let html =''
let goodName=''
if(this.ruleForm.itemType == 0){
goodName=`${printDate}骨灰盒盘点表`
//骨灰盒
this.tableData.forEach((item,index)=>{
if(item.rowspan){
tbody+=`
<tr>
<td style="padding:5px 0;">${index+1}</td>
<td style="padding:0 5px;" rowspan="${item.rowspan}">${item.supplierName || ''}</td>
<td>${item.itemName || ''}</td>
<td>${item.itemUnit||'' }</td>
<td>${item.itemPrice||'' }</td>
<td>${item.mainStore||'' }</td>
<td>${item.cremationStore||'' }</td>
<td></td>
<td>${item.xueLingStore||'' }</td>
<td>${item.totalNumber||'' }</td>
</tr>
`
}else{
tbody+=`
<tr>
<td style="padding:5px 0;">${index+1}</td>
<td>${item.itemName || ''}</td>
<td>${item.itemUnit||'' }</td>
<td>${item.itemPrice||'' }</td>
<td>${item.mainStore||'' }</td>
<td>${item.cremationStore||'' }</td>
<td></td>
<td>${item.xueLingStore||'' }</td>
<td>${item.totalNumber||'' }</td>
</tr>
`
}
})
html+=`
<div style="width:100%;height:100%;padding:0 10px;box-sizing: border-box;">
<p style="font-size: 20px;text-align:center;line-height:30px;box-sizing: border-box;">${goodName}</p>
<table border='1' style='border-collapse: collapse;text-align:center;width: 100%;font-size:12px'>
<thead>
<tr style="font-size:14px">
<th style="padding:0 5px;" rowspan="2">序号</th>
<th rowspan="2">供应商</th>
<th rowspan="2">名称</th>
<th rowspan="2">单位</th>
<th rowspan="2">售价</th>
<th rowspan="2">总仓</th>
<th colspan="2">火化小仓</th>
<th rowspan="2">薛岭仓</th>
<th rowspan="2">合计</th>
</tr>
<tr style="font-size:14px">
<th>盘点数</th>
<th>扣30日销售未出库</th>
</tr>
</thead>
<tbody>
${tbody}
</tbody>
</table>
</div>
`
}else{
console.log(this.tableData1,'555')
//纸棺
goodName=`${printDate}纸棺盘点表`
this.tableData1.forEach((item,index)=>{
console.log(item.rowspan)
if(item.rowspan){
tbody+=`
<tr>
<td style="padding:5px 0;">${index+1}</td>
<td style="padding:0 5px;" rowspan="${item.rowspan}">${item.supplierName || ''}</td>
<td>${item.financialCode || ''}</td>
<td>${item.itemName||'' }</td>
<td>${item.itemUnit||'' }</td>
<td>${item.inPrice ||''}</td>
<td>${item.itemPrice ||'' }</td>
<td>${item.retailStore ||'' }</td>
<td>${item.coldStore ||''}</td>
<td></td>
<td>${item.carStore ||''}</td>
<td></td>
<td>${item.totalNumber ||''}</td>
</tr>
`
}else{
tbody+=`
<tr>
<td style="padding:5px 0;">${index+1}</td>
<td>${item.financialCode || ''}</td>
<td>${item.itemName||'' }</td>
<td>${item.itemUnit||'' }</td>
<td>${item.inPrice ||''}</td>
<td>${item.itemPrice ||'' }</td>
<td>${item.retailStore ||'' }</td>
<td>${item.coldStore ||''}</td>
<td></td>
<td>${item.carStore ||''}</td>
<td></td>
<td>${item.totalNumber ||''}</td>
</tr>
`
}
})
html+=`
<div style="width:100%;height:100%;padding:0 10px;box-sizing: border-box;">
<p style="font-size: 20px;text-align:center;line-height:30px;box-sizing: border-box;">${goodName}</p>
<table border='1' style='border-collapse: collapse;text-align:center;width: 100%;font-size:12px'>
<thead>
<tr style="font-size:14px">
<th style="padding:0 5px;" rowspan="2">序号</th>
<th rowspan="2">供应商</th>
<th rowspan="2">财务编码</th>
<th rowspan="2">名称</th>
<th rowspan="2">单位</th>
<th rowspan="2">进价</th>
<th rowspan="2">售价</th>
<th rowspan="2">零售仓</th>
<th colspan="2">防腐整容组仓</th>
<th colspan="2">收殓组仓</th>
<th rowspan="2">合计</th>
</tr>
<tr style="font-size:14px">
<th>盘点数</th>
<th>扣30日销售未出库</th>
<th>盘点数</th>
<th>扣30日销售未出库</th>
</tr>
</thead>
<tbody>
${tbody}
</tbody>
</table>
</div>
`
}
LODOP.SET_PRINT_PAGESIZE(1,"210mm","297mm" ,"")
// LODOP.SET_SHOW_MODE("LANDSCAPE_DEFROTATED",1);
LODOP.ADD_PRINT_HTM(0, 0, "100%", "100%", html);
LODOP.PREVIEW();
},
//导出
exportExcel() {
let xlsxParam = { raw: true };
let name =''
let time = this.$dayjs(this.ruleForm.queryDate).format("YYYY-MM")
let wb={}
if(this.ruleForm.itemType==0){
if( this.tableData.length==0) return this.$message('暂无数据导出')
//骨灰盒
wb= XLSX.utils.table_to_book(
document.querySelector("#tableData"),
xlsxParam
);
name='骨灰盒盘点表'
}else{
//纸棺
if( this.tableData1.length==0) return this.$message('暂无数据导出')
wb= XLSX.utils.table_to_book(
document.querySelector("#tableData1"),
xlsxParam
);
name='纸棺盘点表'
}
/* 从表生成工作簿对象 */
/* 获取二进制字符串作为输出 */
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
try {
FileSaver.saveAs(
//Blob 对象表示一个不可变、原始数据的类文件对象。
//Blob 表示的不一定是JavaScript原生格式的数据。
//File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
//返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。
new Blob([wbout], { type: "application/octet-stream" }),
//设置导出文件名称
`${name}${(new Date()).valueOf()}.xlsx`
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
return wbout;
},
//改变物品类型
changeType(){
this.tableData=[];
this.tableData1=[];
this.spanArr=[]
this.position=0
// this.onSubmit()
},
//查询
async onSubmit() {
//避免多次点击样式错乱
this.spanArr=[]
this.position=0
this.loading = true;
let postData = {
...this.ruleForm,
queryDate:this.$dayjs(this.ruleForm.queryDate).format("YYYY-MM")
};
//查询接口
let res = await Type["listStockCheck"](postData)
this.loading = false;
if(res.code !==1) return this.$message.error(res.message)
// this.tableData = res.data.list
if(this.ruleForm.itemType==0){
//骨灰盒
this.getSpanArr(res.data)
this.tableData = this.colspanMethod(res.data)
}else{
//纸棺
this.getSpanArr(res.data)
this.tableData1 = this.colspanMethod(res.data)
}
},
// 合并行
colspanMethod(dataList) {
for (let i = 0; i < dataList.length; i++) {
// 循环开始行
let startRow
// 需合并的行数
let rowspan = 1
// 循环到最后一行时
if (i === dataList.length - 1) {
// 如果最后一行和倒数第二行属性不同,则rowspan=1;否则直接结束循环
if (dataList[i].supplierName !== dataList[i - 1].supplierName) {
dataList[i].rowspan = rowspan
}
break
}
// 内层循环记录rowspan的数量
for (let j = i; j < dataList.length - 1; j++) {
// 记录循环结束的行数
startRow = j
// 属性相同则rowspan+1;否则直接结束内循环
if (dataList[j].supplierName === dataList[j + 1].supplierName) {
rowspan++
} else {
break
}
}
// 为数组添加rowspan属性
dataList[i].rowspan = rowspan
// 控制外循环从内循环结束的行数开始
i = startRow
}
return dataList
},
// 初始页currentPage、初始每页数据数pagesize和数据data
handleSizeChange(size) {
this.pager.pageSize = size;
this.onSubmit();
},
handleCurrentChange(currentPage) {
this.pager.currentPage = currentPage;
this.onSubmit(); //点击第几页
}
}
};
</script>
<style lang='scss' scoped>
/deep/ .el-form-item{
margin-bottom: 10px!important;
margin-right: 0!important;
}
/deep/ .el-select{
.el-input{
width:100%;
min-width: 100%;
}
}
.tableGoods {
width: 100%;
display: flex;
justify-content: space-between;
}
.table-left {
width: 49%;
height: 400px;
overflow-y: auto;
border: 1px solid #eee;
}
.table-right {
width: 49%;
height: 400px;
overflow-y: auto;
border: 1px solid #eee;
}
.inputAll {
width: 58px;
height: 25px;
border: 1px solid #eee;
border-radius: 5px;
text-align: center;
}
.table_select_supplier {
width: 148px;
}
.btn-wrap {
display: flex;
margin-bottom: 5px;
}
.demo-table-expand {
font-size: 15px;
}
.demo-table-expand label {
width: 90px;
color: #99a9bf;
}
.demo-table-expand {
padding: 20px;
}
.goods-btn {
display: inline-block;
width: 295px;
text-align: right;
}
.purchase-title {
font-size: 18px;
color: #000000;
font-weight: bold;
padding: 20px 0;
}
.submit-wrap {
width: 100%;
text-align: center;
margin-top: 30px;
}
</style>
38、image 图片预览切换错乱
<el-image
v-for="(pic, index) in imgUrlList"
ref="previewImage"
:key="index"
:src="pic"
:preview-src-list="imgUrlList"
@click.capture="handlePreviewImage(index)"
/>
handlePreviewImage(index) {
const imageViewerChild = this.$refs.previewImage[index].$children[0]
console.log(imageViewerChild)
// 重置图片缩放、旋转样式
imageViewerChild && imageViewerChild.reset()
// 每次点击 显示当前点击的图片
imageViewerChild && (imageViewerChild.index = index)
}
39、按需加载Loading v-loading
import {
Button,
Message,
Icon,
Empty,
Loading,
Tooltip
} from 'element-ui';
Vue.use(Button).use(Icon).use(Empty).use(Tooltip)
Vue.use(Loading.directive);
<div class="home" v-loading='loading'></div>
40、form 数组校验
<el-row class="PageInfo"><i class="info-bar"></i>联系人信息</el-row>
<el-row v-for="(item,index) in ruleForm.contacts" :key="index">
<el-form-item label="联系人姓名"
:prop="`contacts.${index}.contactName`"
:rules="[
{
message:'请输入联系人姓名',
trigger:'blur',
required:true
}]"
>
<el-input
v-model="item.contactName"
minlength="2"
maxlength="50"
placeholder="姓名"
>
<!-- <span
slot="append"
style="cursor: pointer"
@click="readDeadIdCard('familyMember')"
>读取</span
> -->
</el-input>
</el-form-item>
<el-form-item label="性别" label-width="50px">
<el-select
v-model="item.contactGenderCode"
clearable
placeholder="请选择性别"
class="w150"
>
<el-option
v-for="item in dictionary.sex"
:key="item.dataCode"
:label="item.dataText"
:value="item.dataCode"
:disabled="item.disableState ? true:false"
/>
</el-select>
</el-form-item>
<el-form-item label="证件类型" label-width="75px">
<el-select
v-model.number="item.contactCertificateTypeCode"
placeholder="请选择证件类型"
class="w150"
>
<el-option
v-for="item in dictionary.certificates"
:key="item.dataCode"
:label="item.dataText"
:value="item.dataCode"
:disabled="item.disableState ? true:false"
/>
</el-select>
</el-form-item>
<el-form-item label="证件号码" label-width="75px">
<el-input
v-model="item.contactCertificateNo"
maxlength="20"
placeholder="请填写证件号码"
></el-input>
</el-form-item>
<el-form-item label="联系电话" label-width="90px"
:prop="`contacts.${index}.contactPhone`"
:rules="[
{
message:'请填写联系电话',
trigger:'blur',
required:true
}]">
<el-input
v-model="item.contactPhone"
maxlength="50"
placeholder="请填写联系电话"
></el-input>
</el-form-item>
<el-button type="primary" icon="el-icon-plus" circle @click="addContact(item,index)"></el-button>
<el-button type="danger" icon="el-icon-minus" circle @click="delContact(item,index)"></el-button>
</el-row>
//
addContact(item,index){
this.ruleForm.contacts.push({
id:0,
contactName:'',
contactGenderCode:'',
contactCertificateTypeCode:'',
contactCertificateNo:'',
contactPhone:''
})
},
async delContact(item,index){
if(item.id){
//接口删除
let res = await Type['deleteContact']({id:item.id})
if(res.code!==1) return this.$message.error(res.message)
this.$message.success(res.message);
this.searchData()
}else{
this.ruleForm.contacts.splice(index,1)
}
},
41、点击按钮预览大图
<el-table-column align='center' label="操作">
<template slot-scope="scope">
<el-button
size="mini"
@click="checkImg(scope.row)"
>
查看图片
</el-button>
<el-image-viewer
v-if="showViewer"
:on-close="closeViewer"
:url-list="srcList"
/>
</template>
</el-table-column>
//变量
showViewer:false,
srcList: [
'https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg',
'https://fuss10.elemecdn.com/1/8e/aeffeb4de74e2fde4bd74fc7b4486jpeg.jpeg'
],
//组件注册
components: {
'el-image-viewer': () => import('element-ui/packages/image/src/image-viewer')
},
//方法
checkImg(row){
// this.srcList=row.imgsList;
this.showViewer = true
},
closeViewer() {
this.showViewer = false;
},
42、table合计行不显示问题
getSummaries({ columns, data }) {
this.$nextTick(() => {
this.$refs.table.doLayout();
});
const sums = [];
let sum = null;
data.forEach((item) => {
sum += item.itemNumber*item.itemPrice;
});
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = "总计";
return;
}
if (index === 5) {
sums[index] = sum;
return;
}
});
// sums[5] = sums[5].toFixed(2);
return sums;
},
43、table根据id合并相同行
getSpanArr(data) {
// data就是我们从后台拿到的数据
for (var i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArr.push(1);
this.pos = 0;
} else {
// 判断当前元素与上一个元素是否相同
if (data[i].id === data[i - 1].id) {
this.spanArr[this.pos] += 1;
this.spanArr.push(0);
} else {
this.spanArr.push(1);
this.pos = i;
}
}
console.log(this.spanArr);
}
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
console.log(`rowspan:${_row} colspan:${_col}`);
return {
// [0,0] 表示这一行不显示, [2,1]表示行的合并数
rowspan: _row,
colspan: _col
};
},
44、el-form-item 动态lable
<el-form-item :label="`本次${actionType}量`">
<el-input v-model="ruleForm.businessCode"></el-input>
</el-form-item>
45、el-popover 使用
<el-popover
placement="bottom"
title=""
width="200"
trigger="hover"
effect="dark"
>
<div>
<span>当前场次:{{ hall1.previous || "" }}</span
><br />
<span>下一场次:{{ hall1.next || "" }}</span>
</div>
<div
slot="reference"
class="box_item mini"
@click="handleSelectHall(hall1)"
>
<img class="hall_img" src="@/assets/hall/small.png" alt="" />
<div class="hall_name">{{ hall1.hallName }}</div>
</div>
</el-popover>
46、v-for循环+表单验证
<el-form-item label="证件类型:"
:prop="`deadList.${index}.deadCertificateTypeCode`"
:rules="[
{
message: '请选择证件类型',
trigger: 'change',
required: true,
},
]">
<el-select
v-model="item.deadCertificateTypeCode"
clearable
filterable
placeholder="请选择证件类型"
class="w220"
>
<el-option
v-for="item in dictionary.certificates"
:key="item.dataCode"
:label="item.dataText"
:value="item.dataCode"
/>
</el-select>
</el-form-item>
47、el-table 隐藏表头固定第一行
:show-header="false"
/deep/ .el-table__row:nth-child(1){
position: sticky; //粘性定位
position: -webkit-sticky;
top: 0;
z-index: 3;
}
GitHub 加速计划 / eleme / element
10
1
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:4 个月前 )
c345bb45
8 个月前
a07f3a59
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update table.md
* Update transition.md
* Update popover.md 8 个月前
更多推荐
已为社区贡献4条内容
所有评论(0)