vue + vue-resource + element-ui项目中遇到的问题总结

运营智享遇到的问题(前端)
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选中状态
  <el-table :data="list" @filter-change="filterChange">
    <el-table-column
      prop="tag"
      :label="tagNameFormatter"
      column-key="instiStatue"
      :filter-multiple="false"
      :filters="instiStatusList"
      :filter-method="filterTag"
      :filtered-value="filteredValue"
      :formatter="statusFormatter"
      filter-placement="bottom">
    </el-table-column>
  </el-table>
  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元素高度无限增加问题 
  <div class='content'>
    <ul class="list">
      <li class="list_item"> ...... </li>
      <li class="list_item"> ...... </li>
      ......
    </ul>
  </div>
  .content{ width:100%; overflow:auto;}
  如果.list或者.list里的元素设置了:hover的伪类(最常见的是鼠标移入li,改行高亮)并在里面写有属性,hover时就会出现.content高度一直增加的bug.
  bug触发条件:
    1.父级设置overflow:auto;(准确来说是overflow-x:auto;),并且里面的元素宽度超出父级宽度导致横向滚动条出现.
    2.父级元素的任意子元素设有:hover伪类且里面设置有属性(与原属性不一致).
    满足这两个条件,当触发:hover伪类时,bug就会出现.
  解决方案:
    1.给父级设置overflow-x:scroll;(overflow:auto; => overflow-x:scroll;)
      .content{overflow-x:scroll;} -- (子元素宽度未超出父元素宽度时,也会显示滚动条框,视觉体验不太好)
    2.保证父级里的元素不超出父级的宽度,不让父级出现横向滚动条.
    3.保证父级里面的元素没有:hover伪类(这个基本是不可能的..)
    4.给父级加高度
      .content(height:100%;)

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会将&转义为&amp;,请求图片资源会出错
  赋值后 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) 
  <textarea maxlength="10" onBlur="this.value=this.value.substring(0, 10)">
  <el-input type="textarea" model="textareaData" :maxlength="10" @blur="textareaData=textareaData.substring(0, 10)">

15. 文件下载
  1)模版类放前端静态资源
   <a href="static/模版.xlsx" download="模版.xlsx" target="_self"> </a>
   (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不支持 
      目前解决方法: <a href="url" target="_blank" download="模版.xlsx"> </a>直接在新窗口打开,用户另存为

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会提示下载,
      目前解决方法: <a href="url" target="_blank"> </a>直接在新窗口打开,用户另存为
  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);

 


版权声明:本文为weixin_40126227原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。