- ......
- ......
......
运营智享遇到的问题(前端)
vue + vue-resource + element-ui + vue-router + node.js + sass
1. el-table filter tag 使用filter-method处理数据过滤,当该标签下没有数据时标签切换不起作用
解决: 1.用el-table的filter-change方法处理过滤逻辑,而不用el-table-column的filter-method方法;
2.filter tag 设置默认值
初始化table时, filter-change和filter-method方法都不会调用,所以初始值设置只是改变tag的UI状态,获取不到当前选择的tag值,
自己设置一个变量tagValue接收tag值,初始化时默认赋值,在将显示的label值相应formatter回显,filter-change时赋值相应的tagValue.
:filter-value="filterValue" //tag选中状态
:label="tagNameFormatter"
column-key="instiStatue"
:filter-multiple="false"
:filters="instiStatusList"
:filter-method="filterTag"
:filtered-value="filteredValue"
:formatter="statusFormatter"
filter-placement="bottom">
tagNameFormatter(){//标签名格式化
let label = '';
for(let i = 0 ; i < this.instiStatusList.length; i++){
if(this.tagValue == this.instiStatusList[i].value){
label = this.instiStatusList[i].text;
}
}
return label;
}
filterChange(filter){//过滤(tag值改变) el-table方法
this.filteredValue = [];
this.filteredValue.push(filter.instiStatus[0]);
this.tagValue = filter.instiStatus[0];
this.getList();//查询列表数据
}
filterTag(value, row){//过滤(tag值改变) el-table-column方法
}
statusFormatter(row, column){//状态格式化
let label = '';
for(let i = 0 ; i < this.instiStatusList.length; i++){
if(row.status == this.instiStatusList[i].value){
label = this.instiStatusList[i].text;
}
}
return label;
}
2. loading遮罩层 ie9 遮罩全透明时,可以点击到遮罩层下的元素
解决: .loading{background: rgba(255, 255, 255, 0.01);}
3. el-pagination ie9中页码和下一页按钮之间右侧有很大一段空白
解决: .el-pagination{
.el-pager{
li{
float: left;
}
}
}
4. 同一组件内多次调用pagination或切换tab页pagination,pageSize置为1开始
切换tab或pagination时将pagination.total = 0, pagination.pageNum = 1;
5. vue检测变化的注意事项
受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。例如:
var vm = new Vue({
data:{
a:1
}
})
// `vm.a` 是响应的
vm.b = 2
// `vm.b` 是非响应的
ue 不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上:
this.$set(this.someObject,'b',2)
6. el-dialog 在ie9 左右不居中(transform 2d在ie9需加上-ms-前缀)
//解决方法: 不使用transform
el-dialog(--small){
width: 960px;
height: 770px;
//加上后三句代码
transform: none;
position: static;
margin: 5rem auto; // 5rem -> 按情况确定
}
7. 解决输入框背景颜色
input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px #fff inset !important;
}
8. ie9 v-for 渲染图片list 渲染85张左右后, 图片加载失败
(由src更新触发的图片资源下载不完整,图片显示x),后面检查发现是内存使用达到6.8G时
图片加载就会失败,是ie9浏览器内存管理的问题,前端不需要解决,好像也解决不了..
9. ie9 hover元素高度无限增加问题
10. ie9浏览器对频繁操作dom支持不好,会卡顿甚至卡死,尽量避免大量操作dom元素
11. nginx超时设置(避免post请求处理时间过长,可能出现重复提交的问题)
nginx 重试机制 proxy_next_upstream http_502 http_504 error timeout invalid_header;
上面的配置表示,如果后端服务器如下情况,将会把请求转发到下一台后端服务器上。
error - 在连接到一个服务器,发送一个请求,或者读取应答时发生错误。
timeout - 在连接到服务器,转发请求或者读取应答时发生超时。
invalid_header - 服务器返回空的或者错误的应答。
http_502 - 服务器返回502代码。
http_504 - 服务器返回504代码。
继续查看超时时间
proxy_read_timeout 15;
超时时间为15s,所以后端服务器响应慢,nginx没有在15s内收到返回的数据,所以将请求切换到下一台后端机器了,所以,同样的情况下, 请求第二台后端机器时,也没有在规定的时间内得到响应,所以又切换到第三台机器了,最终导致短信发送了三次。
几个参数说明:
proxy_send_timeout 后端服务器数据回传时间(代理发送超时时间)
proxy_read_timeout 连接成功后,后端服务器响应时间(代理接收超时时间)
proxy_connect_timeout nginx连接后端的超时时间,一般不超过75s
如何解决呢?
1、第一种办法:因为后端机器无法再进行优化减少响应时间,所以可以更改nginx的超时时间,将原本的15s更改为40s,这样可以保证结果正常返回。
2、第二种办法 :关闭自动切换到下台机器的功能,即将proxy_next_upstream配置为off。但是这样虽然能解决问题,但是会导致nginx的容错能力下降。
3、第三种办法:从业务角度出发,本质上我们是需要只发一次短信的。 所以可以采用分布式锁的方式解决。
以上现象还可能出现在以下的场景:
1、上传excel,然后服务端处理excel内容,插入到db里面的时候,可能存在多次转发导致数据重复。
2、post请求处理时间过长,可能出现重复提交的问题。
本项目中设置了 proxy_send_timeout 180; proxy_read_timeout 180;
12. 后端取回的img URL 赋值给img.src ,ie9会将&转义为&,请求图片资源会出错
赋值后 imgUrl = imgUrl.replace(/amp;/g,'');
13. 遇到file元素设置cursor:pointer无效的情况
input[type='file']{
cursor: pointer;
font-size: 0;
}
经测试,可以通过设置font-size:0;解决,chrome,ie9都可以适用
14. textarea解决maxlength的兼容问题(ie9)
15. 文件下载
1)模版类放前端静态资源
(download属性设置文件名强制下载, ie9不支持)
2) 文件流下载
方法一: ie9下载未能解决(识别不了文件类型)
Vue.http.get('url',{ responseType: 'blob'})
.then(res => {
const fileName = "考勤信息.xlsx";
const blob = response.data;
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
let elink = document.createElement("a"); // 创建a标签
elink.download = fileName;
elink.style.display = "none";
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click(); // 触发点击a标签事件
document.body.removeChild(elink);
}
}).catch(err => {})
方法二: 后台文件流上传到ecs(另一个存储平台),取回文件URL,返回前端下载
3) URL下载
指定文件mimeType的文件,浏览器会默认打开预览,添加download属性指定附件名称后会下载,ie9不支持
目前解决方法: 直接在新窗口打开,用户另存为
16. 文件上传(使用的pulpload上传插件)
1) 文件上传返回json数据,ie9提示文件下载,后台改content-type:text/html;
2) ie9 ajax请求头不能自定义设置,设置不了token,去掉权限校验,可以通过multipart_params传参;
3) 文件通过后台上传到另一个平台,需要后台指定content-type,不然取回的文件URL都是application/octet-stream类型
(mp4/mp3 ie浏览器(9,10, 11)识别不了mime类型,不能播放);
指定类型后的文件,取回的URL在浏览器会直接打开,不能强制下载,mp4在ie会提示下载,
目前解决方法: 直接在新窗口打开,用户另存为
4) Chrome上传zip格式文件,弹出选择文件框要延迟7-8s,未解决
https://blog.csdn.net/mingover/article/details/55045533
http://www.piaoyi.org/computer/Google-Chrome-input-file-delay-3-5.html
5) 使用plupload
import plupload from 'plupload'
若要使用图片预览 需引入 moxie.min.js(index.html)
6) 多文件上传
用pulpload 直接选择多文件,上传时会调用多次上传接口
解决: 用pulpload上传单个文件,上传多次,保存返回的fileId, 把fileIdList在通过另一个接口传给后台关联保存.
17. js实现不提示直接关闭网页窗口
function closePageForm(){
window.opener=null;
window.open('','_self');
window.close();
}
18. 解决 ie9 input input删除操作无法触发数据变动监听
main.js里添加
(function (d) {
if (navigator.userAgent.indexOf('MSIE 9') === -1) return;
d.addEventListener('selectionchange', function() {
var el = d.activeElement;
if (el.tagName === 'TEXTAREA' || (el.tagName === 'INPUT')) {
var ev = d.createEvent('CustomEvent');
ev.initCustomEvent('input', true, true, {});
el.dispatchEvent(ev);
}
});
})(document);