vue细节处理

629 阅读1分钟

善于利用行内样式设置css属性实现差异化

<div class="bubble" style="--size:60px"></div>
<div class="bubble" style="--size:80px"></div>
  .bubble {
    width: var(--size);
    height: var(--size);
    transform: translateY(calc(100vh - var(--size)/2));
  }
  • 可以元素style绑定data里的变量 然后css又用css变量var获取数值,即可实现js与css数值同步(比如动态修改颜色)
<div :style="compBgcolor" class="box">
.box{
    background:var(--bg-color);
}

data(){
    bgColor:'red'
}
computed:{
    compBgcolor(){
        return `--bg-color:`${this.bgColor};`
    }
}

width用100% 不要用100vw

  • 有纵向滚动条时,如果width设为100vw 会导致出现横向滚动条

自定义拖动指令

Vue.directive('drag', (el) => {
  const oDiv = el // 当前元素
  /*html设置drag-min-top属性时,小于该高度不能拖动成功*/
  const minTop = oDiv.getAttribute('drag-min-top')
  /*拖动超过该区域范围 会给dom加个dragged属性*/
  const ifMoveSizeArea = 20 
  oDiv.onmousedown = e => {
    let target = oDiv
    while (window.getComputedStyle(target).position !== 'absolute' && target !== document.body) {
      target = target.parentElement
    }

    document.onselectstart = () => {
      return false
    }
    if (!target.getAttribute('init_x')) {
      target.setAttribute('init_x', target.offsetLeft)
      target.setAttribute('init_y', target.offsetTop)
    }

    const initX = parseInt(target.getAttribute('init_x'))
    const initY = parseInt(target.getAttribute('init_y'))

    // 鼠标按下,计算当前元素距离可视区的距离
    const disX = e.clientX - target.offsetLeft
    const disY = e.clientY - target.offsetTop
    document.onmousemove = e => {
      // 通过事件委托,计算移动的距离
      // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
      const l = e.clientX - disX
      const t = e.clientY - disY
      const { marginTop: mt, marginLeft: ml } = window.getComputedStyle(target)
      // 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
      target.style.left = l - parseInt(ml) + 'px'
      target.style.top = (t < minTop ? minTop : t) - parseInt(mt) + 'px'
      if (Math.abs(l - initX) > ifMoveSizeArea || Math.abs(t - initY) > ifMoveSizeArea) {
        target.setAttribute('dragged', '')
      } else {
        target.removeAttribute('dragged')
      }
    }
    document.onmouseup = e => {
      document.onmousemove = null
      document.onmouseup = null
      document.onselectstart = null
    }
    // return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
    return false
  }
})

监听某个dom尺寸变化

  • npm安装 resize-observer-polyfill

移动端click事件触发范围过大的问题

  • 点击白色区域会展开,黑色区域只是过渡分割,不该触发事件
  • 移动端点击黑色也会触发上面白色的点击事件(认为指头大,增大了点击事件范围)
  • 解决方案:黑色用div,且也写click事件,这样有click事件的元素被点击,就不会找它范围内其它具有click事件的元素触发 image.png

调动画

image.png

  • 先把动画速度变慢,再点击暂停 拖动进度条看 image.png

下拉列表高度自适应且有动画

  • res里包裹下拉列表

    .res{
      overflow: hidden;
      transition: max-height 0.5s cubic-bezier(0,1,0,1);
      max-height: 0px;
    } 
    //focus-within 该元素自身或它的后代focus时生效
    //点击res里的列表 会导致失焦。所以还需要.res:hover来确保鼠标在列表里时 高度维持住
    .search-wrap:focus-within .res, .res:hover{
      max-height: 200vh;
      transition: max-height 1s ease-in-out;
    }
    
  • 由于内部元素可能撑不起max-height高度,而动画执行时是以max-height作为整个过程。

  • 会出现2个bug

  • 1.下拉出现时会有滚动条,(采用overflow:hidden解决)

  • 2.收起动画有延迟(动画进程是基于max-height的,所以内部高度小时,会觉着反应慢)

  • 2的解决方案是非hover时,收起动画前期进程非常迅速,到后面能看到动画尾巴就行

image.png

el-tooltip

  • disabled属性,控制是否启用tooltip展示冒泡框的功能
  • value属性,冒泡框出现为true,消失为false(冒泡位置取决于该属性切换,会重新计算)
  • 当手动控制disabled使能/失能该功能时,若disabled改为true的同时鼠标在tooltip上触发了冒泡框,位置会错位,需要tooltip组件一个ref="tool",修改diaabled之后调用 $refs.tool.updatePopper()

ui一些没有上传iconfont的小图标的使用

  • 一般图标和文字可能要同时变颜色,如果传统的搞法要导出两套图标,太麻烦
    1、把小图标保存为svg
    2、把svg里的 fill="xxx" 这个属性全删了
  • 方案二(推荐)
    使用iconmoon 把新图标合并到之前的字体图标文件库里

flex-grow也可以有过渡效果

  • transition:flex-grow .3s;
  • flex-grow:1;//flex内盒子只有一个有该属性时,占满剩余高度

vue2 computed的缺陷

  • computed如果在初次执行时没有访问全部的依赖对象(有分支),会导致某些内部明明有的依赖变化了但是不更新
  • vue遇到不能解决的不刷新的时候都加个key(一般不刷新都是触发diff算法的bug了)