美文网首页
Vue3为dom组件增加可拖拽改变大小的属性

Vue3为dom组件增加可拖拽改变大小的属性

作者: 道行者 | 来源:发表于2023-02-21 12:00 被阅读0次

    添加如下js文件resizable.js:

    // 支持上下左右四边拖动。若内部元素太贴边,不易触发拖动事件,最好在拖动一边加边框,使鼠标容易选中。
    // 使用方式:
    // <div v-resizable="'right, bottom'">
    export default {
      install: (app) => {
        const sideArr = ['right', 'left', 'top', 'bottom']
        const errmsg = 'resizable needs string value of: ' + sideArr
        const minSize = 40
        const dragSize = 5
    
        app.directive('resizable', {
          mounted(el, binding, vnode, oldVnode) {
            const dragable = {}
            const oriCur = el.style.cursor
            const sides = binding.value.replace(' ', '').split(',')
            let dragSide = ''
            let dragging = false
    
            if (sides.length === 0) {
              throw errmsg
            }
            for (let i = 0; i < sides.length; i++) {
              if (sideArr.indexOf(sides[i]) < 0 ) {
                throw errmsg
              }
              dragable[sides[i]] = true
            }
    
            el.addEventListener('mousemove', (e) => {
              if (dragging) return
    
              if (dragable['right'] && el.offsetWidth - e.offsetX < dragSize) {
                el.style.cursor = 'ew-resize'
                dragSide = 'right'
              }
              else if (dragable['left'] && e.offsetX < dragSize) {
                el.style.cursor = 'ew-resize'
                dragSide = 'left'
              }
              else if (dragable['top'] && e.offsetY < dragSize) {
                el.style.cursor = 'ns-resize'
                dragSide = 'top'
              }
              else if (dragable['bottom'] && el.offsetHeight - e.offsetY < dragSize) {
                el.style.cursor = 'ns-resize'
                dragSide = 'bottom'
              }
              else {
                el.style.cursor = oriCur
                dragSide = ''
              }
            })
    
            el.addEventListener('mousedown', (e) => {
              if ( !dragSide ) return
    
              dragging= true
              const cstyle = window.getComputedStyle(el)
              const width = Number.parseInt(cstyle.width)
              const height = Number.parseInt(cstyle.height)
              const elW = width > 0 ? width : el.offsetWidth
              const elH = height > 0 ? height : el.offsetHeight
              const clientX = e.clientX
              const clientY = e.clientY
    
              const movefun = (e) => {
                e.preventDefault()
                if (dragSide === 'right' && (e.clientX > clientX || el.offsetWidth >= minSize)) {
                  el.style.width = elW + (e.clientX - clientX) + 'px'
                }
                else if (dragSide === 'left' && (e.clientX < clientX || el.offsetWidth >= minSize)) {
                  el.style.width = elW + (clientX - e.clientX) + 'px'
                }
                else if (dragSide === 'top' && (e.clientY < clientY || el.offsetHeight >= minSize)) {
                  el.style.height = elH + (clientY - e.clientY) + 'px'
                }
                else if (dragSide === 'bottom' && (e.clientY > clientY || el.offsetHeight >= minSize)) {
                  el.style.height = elH + (e.clientY - clientY) + 'px'
                }
              }
              const removefun = () => {
                dragging= false
                document.removeEventListener('mousemove', movefun)
                document.removeEventListener('mouseup', removefun)
              }
    
              document.addEventListener('mousemove', movefun)
              document.addEventListener('mouseup', removefun) 
            })
          }
        })
      }
    }
    

    main.js中应用它:

    import resizable from '@/directive/resizable'
    
    const app = createApp(App)
    app.use(resizable)
    

    在组件属性中就只可以设置了,比如,右边和下边都可以拖拽改变大小:

    <div v-resizable="'right, bottom'">
    </div>
    

    因为是通过设置style来改变大小的,所以实际大小改变情况还可能受其他css样式等限制。

    相关文章

      网友评论

          本文标题:Vue3为dom组件增加可拖拽改变大小的属性

          本文链接:https://www.haomeiwen.com/subject/tuinkdtx.html