组件封装坑点

1,036 阅读6分钟

elementUI中el-tooltip多个循环展示快速下滑出现抖动

现象:

1.在鼠标悬浮在一行上的时候会出现tooltip提示框,每行都可以,但如果交替悬浮速度够快,浏览器右边就会出现纵向滚动条,只有一瞬会出现这个问题

原因:

1.在于tooltip位置的设置,采用绝对定位absulute

2.在两条信息交替悬浮的时候,tooltip提示框有一瞬display: block;显示,但top,left并没有定位

3.导致tooltip出现在了页面的最下面,占用了几十px的空间

4.导致一瞬间有一个纵向的滚动条、

解决一:

1.设置向上位置为一个不出现在页面中的位置 .el-tooltip__popper.is-dark { top: -500px; }

2.当tooltip显示时style会覆盖掉class的样式,不对使用产生影响

解决二:body:{overflow:hidden}

关于使用element中的popup问题

1.前言

我们知道弹出框都是在触发了某种条件后展示,而一个个的新的弹出框的展示,总是覆盖着上一个弹出框。实现覆盖功能需要保证新的弹出框的z-index要比旧的弹出框的z-index值相等或着更高,为达到这个目的element为所有的弹出框(所有下拉框、提示框、Dialog对话框等等)直接或间接的使用到一个js组件element-ui/src/utils/vue-popper,而这个vue-popper又使用了另一个组件element-ui/src/utils/popup/popup-manager.js

PopupManager

PopupManager中有一个zIndex属性初始值为2000,所有的弹出框的z-index其实都是从这个PopupManager.zIndex中获取的,当要展示一个新的弹出框时,组件便会去获取最新的PopupManager.zIndex,然后为PopupManager.zIndex加1,这样就保证了新的弹出框总是比旧的弹出框z-index大,省去自己一个个设置的麻烦,也减少问题的出现。

2.遇到的问题

element本身的弹出框没有什么问题,问题在于我们擅自使用了element未直接暴露出来的组件,这里以el-select中的select-dropdown.vue为例。

我们通过拷贝el-select源码来定制下拉框的内容和逻辑,一切看起来都很完美,但是有一个致命的问题,自己定制的选择器的下拉框总是会出现时不时无法展示的问题,要疯狂点击才会展示。排查后发现就是z-index的值问题,自定义的下拉框的z-index总是无法跟原生的弹出框z-index同步,原因其实很简单。。。使用的不是同一个PopupManager
原来我们直接复制el-select源码,源码中引入下拉框
import ElSelectMenu from './select-dropdown.vue'
我们修改为
import ElSelectMenu from 'element-ui/packages/select/src/select-dropdown.vue'
再来看select-dropdown.vue源码中对于vue-popper的引用
import Popper from 'element-ui/src/utils/vue-popper'
没毛病,但是其实毛病就出在这引用路径上的src,src就是source源的意思,源码中互相引用没问题,但是我们在项目中使用element组件的使用,并不是来自源码,而是来自源码编译出来的依赖库,是npm模块中lib目录下的文件。所以我们的自定义组件用了一个新的PopupManager对象跟原生element组件不同的PopupManager,导致zIndex不同步,展示错误。

3.解决

复制select-dropdown.vue,将原先
import Popper from 'element-ui/src/utils/vue-popper'
修改为
import Popper from 'element-ui/lib/utils/vue-popper'
el-select改引用为我们修改后的select-dropdown.vue。。。

4.最后

  • 1.es6中import的每个模块都是单例的,同一个对象被所有引用共用
  • 2.引用element中未暴露的组件时,要注意尽量使用lib下的,防止出现类似问题
  • 3.引用npm包的某个文件时时,要注意引用其源码和编译后库的区别 原文地址:segmentfault.com/a/119000001…

element中下拉框select在长页面滚动时,下拉弹框没有跟随下拉

解决一:设置这个属性即可 :popper-append-to-body=“false”

如果解决一不好用,既然下拉列表默认渲染到body,又是定位元素,那是不是body样式导致的?body元素不能设置100% (完美)

el-textarea设置autosize滚动条闪动

方法一:div模拟textarea文本域轻松实现高度自适应

demo演示地址:www.xuanfengge.com/demo/201308…

因为textarea不支持自适应高度,就是定好高度或者是行数之后,超出部分就会显示滚动条,看起来不美观。

而用DIV来模拟时,首先遇到的问题是:div怎么实现输入功能?

可能我们还是第一次见到这个属性contenteditable,如一个普通的block元素上加个contenteditable="true"就实现编辑,出现光标了。如

<div contenteditable="true"></div>

contenteditable属性虽是HTML5里面的内容,但是IE似乎老早就支持此标签属性了。所以,兼容性方面还是不用太担心的。

CSS代码

.textarea{
    width: 400px;
    min-height: 20px;
    max-height: 300px;
    _height: 120px;
    margin-left: auto;
    margin-right: auto;
    padding: 3px;
    outline: 0;
    border: 1px solid #a0b3d6;
    font-size: 12px;
    line-height: 24px;
    padding: 2px;
    word-wrap: break-word;
    overflow-x: hidden;
    overflow-y: auto;
    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
    }

HTML代码

<div class="textarea" contenteditable="true"><br /></div>

CSS代码中,因为IE6不支持min/max,所以做了hack,其他的也好理解。 方法二:文本框textarea根据输入内容自适应高度 demo演示地址:www.xuanfengge.com/demo/201308…

这个写法是用原生JS写的,考虑了很多兼容性问题,完全和新浪微博的回复效果一样的功能。有兴趣的童鞋可以仔细分析下代码。

CSS代码

#textarea {
    display: block;
    margin:0 auto;
    overflow: hidden;
    width: 550px;
    font-size: 14px;
    height: 18px;
    line-height: 24px;
    padding:2px;
}
textarea {
    outline: 0 none;
    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
}

javascript代码

/**
 * 文本框根据输入内容自适应高度
 * @param        {HTMLElement}    输入框元素
 * @param        {Number}        设置光标与输入框保持的距离(默认0)
 * @param        {Number}        设置最大高度(可选)
 */

var autoTextarea = function (elem, extra, maxHeight) {
  extra = extra || 0;
  var isFirefox = !!document.getBoxObjectFor || 'mozInnerScreenX' in window,
    isOpera = !!window.opera && !!window.opera.toString().indexOf('Opera'),
    addEvent = function (type, callback) {
      elem.addEventListener ?
        elem.addEventListener(type, callback, false) :
        elem.attachEvent('on' + type, callback);
    },
    getStyle = elem.currentStyle ? function (name) {
      var val = elem.currentStyle[name];
      if (name === 'height' && val.search(/px/i) !== 1) {
        var rect = elem.getBoundingClientRect();
        return rect.bottom - rect.top -
          parseFloat(getStyle('paddingTop')) -
          parseFloat(getStyle('paddingBottom')) + 'px';
      };
      return val;
    } : function (name) {
      return getComputedStyle(elem, null)[name];
    },
    minHeight = parseFloat(getStyle('height'));
  elem.style.resize = 'none';
  var change = function () {
    var scrollTop, height,
      padding = 0,
      style = elem.style;
    if (elem._length === elem.value.length) return;
    elem._length = elem.value.length;
    if (!isFirefox && !isOpera) {
      padding = parseInt(getStyle('paddingTop')) + parseInt(getStyle('paddingBottom'));
    };
    scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    elem.style.height = minHeight + 'px';
    if (elem.scrollHeight > minHeight) {
      if (maxHeight && elem.scrollHeight > maxHeight) {
        height = maxHeight - padding;
        style.overflowY = 'auto';
      } else {
        height = elem.scrollHeight - padding;
        style.overflowY = 'hidden';
      };
      style.height = height + extra + 'px';
      scrollTop += parseInt(style.height) - elem.currHeight;
      document.body.scrollTop = scrollTop;
      document.documentElement.scrollTop = scrollTop;
      elem.currHeight = parseInt(style.height);
    };
  };
  addEvent('propertychange', change);
  addEvent('input', change);
  addEvent('focus', change);
  change();
};

HTML代码(写在body里面的)

<textarea id="textarea" placeholder="回复内容"></textarea>
    <script>
        var text = document.getElementById("textarea");
        autoTextarea(text);// 调用
    </script>

转载自 www.xuanfengge.com/textarea-on…

关于组件发布jenkins自动化打版

  1. npm i
  2. npm rebuild node-sass //解决node-sass报错
  3. npm run dist
  4. npm publish
  5. npm run build

sass-loader 与 node-sass

1.sass-loader

webpack 官网原文的说法: 将sass和scss转化为css

2.node-sass Node-sass是一个库,它将Node.js绑定到LibSass(流行样式表预处理器Sass的C版本)。它允许用户以令人难以置信的速度将.scss文件本地编译为css,并通过连接中间件自动编译。

Vue Loader 是什么?

Vue Loader 是一个 webpack 的 loader,它允许你以一种名为单文件组件 (SFCs)的格式撰写 Vue 组件

npm install指定版本_npm的lock机制解析

^2.0.0 指定的范围是版本号大于等于2.0.0且大版本号为2。即2.6.10这个是符合的,而3.0.0和1.0.0这种是不符合的。