前言:我使用的是vue+element admin,里面用的组件都来自于element.eleme.io
备注:host:如果配置为127.0.0.1,只能本机访问,如果配置为0.0.0.0,则可以局域网访问
如果想内网穿透:报 invalid host header,只需在webpack.dev.conf.js加上
devServer: {
disableHostCheck: true,
}
以下都是我使用过程中用到的小窍门我会记录下来:
1.获取表格tableData的索引值,注意不是每列里的key,是index
使用:scope.$index
效果:比如我想要只在第一列显示增加按钮
那我可以加一个
v-if="scope.$index === 0"
效果:
2.判断对象是否为空可以用ES6语法判断它的长度
Object.keys(this.form.paramList).length === 0
3.vue在数组指定位置追加列
this.tableDataGzh.splice(-1, 0, list);//在倒数第二列追加
实现效果在追加和删除:
4.element里togglerowselection无效爬坑
官网demo: http://element-cn.eleme.io/#/duo-xuan
我想在打开编辑框时默认就选中为true的数据,可是官方demo没有详细说这个咋用,我一直以为那个row是对应的行数字
官方代码:
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(row);
});
我测试官方的row就是数字,然后我在我的项目里这样写无效果。
解决代码:
this.tableDataGzh.map((tableinfo, index) => {
if (tableinfo['isApi'] === true) {
this.$nextTick(() => { // 延迟回调
console.log(this.$refs["multipleTable"])
this.$refs["multipleTable"].toggleRowSelection(this.tableDataGzh[index], true);
})
}
})
实际上要传的是对应的列,不是第几列数。说明:
multipleTable是对应table的ref
效果:
5.element的多选框实现单选:
vue:
<el-table-column label="放大关键词">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.isBigWord"
@change="handleChecked(scope.$index)">
</el-checkbox>
</template>
</el-table-column>
js:
handleChecked(val) {
for (let i = 0; i < this.tableDataXcx.length; i++) {
if (i !== val) {
this.tableDataXcx[i]['isBigWord'] = false;
}
}
},
6.格式化时间
在 utils目录里的index.js里写:
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if (('' + time).length === 10) time = parseInt(time) * 1000
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
export function formatTime(time, option) {
time = +time * 1000
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
然后把这个文件在script里引入:
import {parseTime} from '@/utils'
vue文件里写:
<el-table-column :label="$t('messageManage.createTime')" min-width="100" align="center">
<template slot-scope="scope">
<span>{{ scope.row.createTime/1000 | formatTime }}</span>
</template>
</el-table-column>
效果:
vue里写:
<el-table-column :label="$t('messageManage.createTime')" min-width="100" align="center">
<template slot-scope="scope">
<span>{{ scope.row.createTime | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
效果:
js:
this.tableData.list.forEach(message => {
/* 格式化时间 */
if (message.createTime) {
message.createTime = parseTime(message.createTime)
}
})
vue:
<el-table-column :label="$t('messageManage.createTime')" prop="createTime" min-width="100" align="center"/>
效果和上面的一个一样
7.[Vue warn]: Error in render: "TypeError: _self.$scopedSlots.default is not a function"报错解决:
经过反复排查,没发现哪里写的有问题,最后在 https://forum.vuejs.org/t/weird-vuejs-error-with-elementui-table-self-scopedslots-default-is-not-a-function/12933/4找到答案
1.要么把v-if改成v-show
2.要么用v-if的时候加个key属性
8.Select 选择器在编辑时默认值不显示对应的名称
因为前期没那么多数据,就先把下拉写成死的,却遇到编辑页不显示对应名称的问题,但是不写死的那种都是OK的。最后看接口返回值发现返回的key不是string类型而是number,以后写死值的时候一定要注意类型
改成
效果:
9.element的select下拉选中不显示对应的项
因为上面一个下拉框选中会联动下面一个下拉框,上面一个下拉框选中后应该把下面的下拉框选中值重置,我之前是直接把的值设为null,在编辑时没事,但是新增时上面选中后,下面的下拉框选中不显示内容,于是我加了个判断,就是在下面一个下拉判断是不是之前有值,有就设为null,这样就可以避免在新增时下拉框选中不显示值的问题,还可以在上面一个下拉更改时,下面的框被重置掉
10.element如何并排显示,用<el-col></el-col>给span,整个span默认应该是分成了24块,下面的span和不超过24就行,
:gutter="50"这个值是块之间间隔
<el-row :gutter="50">
<el-col :span="10">
<el-form-item :label-width="formLabelWidth" label="主订单号:">
123
</el-form-item>
</el-col>
<el-col :span="8">
123
</el-col>
<el-col :span="6">
123
</el-col>
</el-row>
效果图:
不加gutter
加:gutter="50"
11.2019-3-15今天遇到浏览器接收接口response和preview的显示的值还不一样,发现原来接口传的那个值是long类型,js会把它给精度丢失掉,浏览器显示的值用的preview的值,显示时少了一位,建议转成string
12.js转换数组某列类型
getBizTypeByBizId(params).then(res => {
const _data = res.data
if (_data && _data.code === '200') {
let BizIdOptions = _data.data
this.BizIdOptions = BizIdOptions.map((item) => {
item.bizId = Number(item.bizId)
return{
...item,
}
});
}
}).catch(err => {
console.log(err.stack)
})
效果:
13.上传图片限制高宽
官网的demo没有说怎么限制高宽(像素) 只有大小和图片格式
官网:
修改后:
<el-form-item :label-width="formLabelWidth" label="店铺logo" prop="shopLogoUrl">
<el-upload
class="avatar-uploader"
action="/ms-api/account/uploadScenicAccountPic"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
<span>图片格式:png;图片尺寸:150x150</span>
</el-form-item>
handleAvatarSuccess(res, file) {
if (res.code === '200') {
this.imageUrl = res.data[0].url
this.form.shopLogoUrl = this.imageUrl
} else {
this.$notify({
title: "失败",
message: res.msg,
type: "error",
});
}
},
beforeAvatarUpload(file) {
const isPNG = file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isPNG) {
this.$message.error('上传图片只能是 PNG 格式!');
}
if (!isLt2M) {
this.$message.error('上传图片大小不能超过2M!');
}
const isSize = new Promise(function(resolve, reject) {
let width = 150;
let height = 150;
let _URL = window.URL || window.webkitURL;
let image = new Image();
image.onload = function() {
let valid = image.width === width && image.height === height;
valid ? resolve() : reject();
};
image.src = _URL.createObjectURL(file);
}).then(
() => {
return file;
},
() => {
this.$message.error('上传图片尺只能是 150*150!');
return Promise.reject();
}
);
return isPNG && isLt2M && isSize;
},