1
This commit is contained in:
		
							
								
								
									
										77
									
								
								src/directive/el-drag-dialog/drag.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/directive/el-drag-dialog/drag.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
export default {
 | 
			
		||||
  bind(el, binding, vnode) {
 | 
			
		||||
    const dialogHeaderEl = el.querySelector('.el-dialog__header')
 | 
			
		||||
    const dragDom = el.querySelector('.el-dialog')
 | 
			
		||||
    dialogHeaderEl.style.cssText += ';cursor:move;'
 | 
			
		||||
    dragDom.style.cssText += ';top:0px;'
 | 
			
		||||
 | 
			
		||||
    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
 | 
			
		||||
    const getStyle = (function() {
 | 
			
		||||
      if (window.document.currentStyle) {
 | 
			
		||||
        return (dom, attr) => dom.currentStyle[attr]
 | 
			
		||||
      } else {
 | 
			
		||||
        return (dom, attr) => getComputedStyle(dom, false)[attr]
 | 
			
		||||
      }
 | 
			
		||||
    })()
 | 
			
		||||
 | 
			
		||||
    dialogHeaderEl.onmousedown = (e) => {
 | 
			
		||||
      // 鼠标按下,计算当前元素距离可视区的距离
 | 
			
		||||
      const disX = e.clientX - dialogHeaderEl.offsetLeft
 | 
			
		||||
      const disY = e.clientY - dialogHeaderEl.offsetTop
 | 
			
		||||
 | 
			
		||||
      const dragDomWidth = dragDom.offsetWidth
 | 
			
		||||
      const dragDomHeight = dragDom.offsetHeight
 | 
			
		||||
 | 
			
		||||
      const screenWidth = document.body.clientWidth
 | 
			
		||||
      const screenHeight = document.body.clientHeight
 | 
			
		||||
 | 
			
		||||
      const minDragDomLeft = dragDom.offsetLeft
 | 
			
		||||
      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
 | 
			
		||||
 | 
			
		||||
      const minDragDomTop = dragDom.offsetTop
 | 
			
		||||
      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight
 | 
			
		||||
 | 
			
		||||
      // 获取到的值带px 正则匹配替换
 | 
			
		||||
      let styL = getStyle(dragDom, 'left')
 | 
			
		||||
      let styT = getStyle(dragDom, 'top')
 | 
			
		||||
 | 
			
		||||
      if (styL.includes('%')) {
 | 
			
		||||
        styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)
 | 
			
		||||
        styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100)
 | 
			
		||||
      } else {
 | 
			
		||||
        styL = +styL.replace(/\px/g, '')
 | 
			
		||||
        styT = +styT.replace(/\px/g, '')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      document.onmousemove = function(e) {
 | 
			
		||||
        // 通过事件委托,计算移动的距离
 | 
			
		||||
        let left = e.clientX - disX
 | 
			
		||||
        let top = e.clientY - disY
 | 
			
		||||
 | 
			
		||||
        // 边界处理
 | 
			
		||||
        if (-(left) > minDragDomLeft) {
 | 
			
		||||
          left = -minDragDomLeft
 | 
			
		||||
        } else if (left > maxDragDomLeft) {
 | 
			
		||||
          left = maxDragDomLeft
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (-(top) > minDragDomTop) {
 | 
			
		||||
          top = -minDragDomTop
 | 
			
		||||
        } else if (top > maxDragDomTop) {
 | 
			
		||||
          top = maxDragDomTop
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 移动当前元素
 | 
			
		||||
        dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`
 | 
			
		||||
 | 
			
		||||
        // emit onDrag event
 | 
			
		||||
        vnode.child.$emit('dragDialog')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      document.onmouseup = function(e) {
 | 
			
		||||
        document.onmousemove = null
 | 
			
		||||
        document.onmouseup = null
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								src/directive/el-drag-dialog/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/directive/el-drag-dialog/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
import drag from './drag'
 | 
			
		||||
 | 
			
		||||
const install = function(Vue) {
 | 
			
		||||
  Vue.directive('el-drag-dialog', drag)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (window.Vue) {
 | 
			
		||||
  window['el-drag-dialog'] = drag
 | 
			
		||||
  Vue.use(install); // eslint-disable-line
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
drag.install = install
 | 
			
		||||
export default drag
 | 
			
		||||
							
								
								
									
										41
									
								
								src/directive/el-table/adaptive.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/directive/el-table/adaptive.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * How to use
 | 
			
		||||
 * <el-table height="100px" v-el-height-adaptive-table="{bottomOffset: 30}">...</el-table>
 | 
			
		||||
 * el-table height is must be set
 | 
			
		||||
 * bottomOffset: 30(default)   // The height of the table from the bottom of the page.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const doResize = (el, binding, vnode) => {
 | 
			
		||||
  const { componentInstance: $table } = vnode
 | 
			
		||||
 | 
			
		||||
  const { value } = binding
 | 
			
		||||
 | 
			
		||||
  if (!$table.height) {
 | 
			
		||||
    throw new Error(`el-$table must set the height. Such as height='100px'`)
 | 
			
		||||
  }
 | 
			
		||||
  const bottomOffset = (value && value.bottomOffset) || 30
 | 
			
		||||
 | 
			
		||||
  if (!$table) return
 | 
			
		||||
 | 
			
		||||
  const height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset
 | 
			
		||||
  $table.layout.setHeight(height)
 | 
			
		||||
  $table.doLayout()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  bind(el, binding, vnode) {
 | 
			
		||||
    el.resizeListener = () => {
 | 
			
		||||
      doResize(el, binding, vnode)
 | 
			
		||||
    }
 | 
			
		||||
    // parameter 1 is must be "Element" type
 | 
			
		||||
    addResizeListener(window.document.body, el.resizeListener)
 | 
			
		||||
  },
 | 
			
		||||
  inserted(el, binding, vnode) {
 | 
			
		||||
    doResize(el, binding, vnode)
 | 
			
		||||
  },
 | 
			
		||||
  unbind(el) {
 | 
			
		||||
    removeResizeListener(window.document.body, el.resizeListener)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								src/directive/el-table/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/directive/el-table/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
import adaptive from './adaptive'
 | 
			
		||||
 | 
			
		||||
const install = function(Vue) {
 | 
			
		||||
  Vue.directive('el-height-adaptive-table', adaptive)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (window.Vue) {
 | 
			
		||||
  window['el-height-adaptive-table'] = adaptive
 | 
			
		||||
  Vue.use(install); // eslint-disable-line
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
adaptive.install = install
 | 
			
		||||
export default adaptive
 | 
			
		||||
							
								
								
									
										17
									
								
								src/directive/permission/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/directive/permission/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
import permission from './permission'
 | 
			
		||||
import permisaction from './permisaction'
 | 
			
		||||
 | 
			
		||||
const install = function(Vue) {
 | 
			
		||||
  Vue.directive('permission', permission)
 | 
			
		||||
  Vue.directive('permisaction', permisaction)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (window.Vue) {
 | 
			
		||||
  window['permission'] = permission
 | 
			
		||||
  window['permisaction'] = permisaction
 | 
			
		||||
  // eslint-disable-next-line no-undef
 | 
			
		||||
  Vue.use(install)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
permission.install = install
 | 
			
		||||
export default permission
 | 
			
		||||
							
								
								
									
										23
									
								
								src/directive/permission/permisaction.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/directive/permission/permisaction.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
import store from '@/store'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  inserted(el, binding, vnode) {
 | 
			
		||||
    const { value } = binding
 | 
			
		||||
    const all_permission = '*:*:*'
 | 
			
		||||
    const permissions = store.getters && store.getters.permisaction
 | 
			
		||||
 | 
			
		||||
    if (value && value instanceof Array && value.length > 0) {
 | 
			
		||||
      const permissionFlag = value
 | 
			
		||||
 | 
			
		||||
      const hasPermissions = permissions.some(permission => {
 | 
			
		||||
        return all_permission === permission || permissionFlag.includes(permission)
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      if (!hasPermissions) {
 | 
			
		||||
        el.parentNode && el.parentNode.removeChild(el)
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      throw new Error(`请设置操作权限标签值`)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/directive/permission/permission.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/directive/permission/permission.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
import store from '@/store'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  inserted(el, binding, vnode) {
 | 
			
		||||
    const { value } = binding
 | 
			
		||||
    const roles = store.getters && store.getters.roles
 | 
			
		||||
 | 
			
		||||
    if (value && value instanceof Array && value.length > 0) {
 | 
			
		||||
      const permissionRoles = value
 | 
			
		||||
 | 
			
		||||
      const hasPermission = roles.some(role => {
 | 
			
		||||
        return permissionRoles.includes(role)
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      if (!hasPermission) {
 | 
			
		||||
        el.parentNode && el.parentNode.removeChild(el)
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      throw new Error(`need roles! Like v-permission="['admin','editor']"`)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										91
									
								
								src/directive/sticky.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/directive/sticky.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
			
		||||
const vueSticky = {}
 | 
			
		||||
let listenAction
 | 
			
		||||
vueSticky.install = Vue => {
 | 
			
		||||
  Vue.directive('sticky', {
 | 
			
		||||
    inserted(el, binding) {
 | 
			
		||||
      const params = binding.value || {}
 | 
			
		||||
      const stickyTop = params.stickyTop || 0
 | 
			
		||||
      const zIndex = params.zIndex || 1000
 | 
			
		||||
      const elStyle = el.style
 | 
			
		||||
 | 
			
		||||
      elStyle.position = '-webkit-sticky'
 | 
			
		||||
      elStyle.position = 'sticky'
 | 
			
		||||
      // if the browser support css sticky(Currently Safari, Firefox and Chrome Canary)
 | 
			
		||||
      // if (~elStyle.position.indexOf('sticky')) {
 | 
			
		||||
      //     elStyle.top = `${stickyTop}px`;
 | 
			
		||||
      //     elStyle.zIndex = zIndex;
 | 
			
		||||
      //     return
 | 
			
		||||
      // }
 | 
			
		||||
      const elHeight = el.getBoundingClientRect().height
 | 
			
		||||
      const elWidth = el.getBoundingClientRect().width
 | 
			
		||||
      elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
 | 
			
		||||
 | 
			
		||||
      const parentElm = el.parentNode || document.documentElement
 | 
			
		||||
      const placeholder = document.createElement('div')
 | 
			
		||||
      placeholder.style.display = 'none'
 | 
			
		||||
      placeholder.style.width = `${elWidth}px`
 | 
			
		||||
      placeholder.style.height = `${elHeight}px`
 | 
			
		||||
      parentElm.insertBefore(placeholder, el)
 | 
			
		||||
 | 
			
		||||
      let active = false
 | 
			
		||||
 | 
			
		||||
      const getScroll = (target, top) => {
 | 
			
		||||
        const prop = top ? 'pageYOffset' : 'pageXOffset'
 | 
			
		||||
        const method = top ? 'scrollTop' : 'scrollLeft'
 | 
			
		||||
        let ret = target[prop]
 | 
			
		||||
        if (typeof ret !== 'number') {
 | 
			
		||||
          ret = window.document.documentElement[method]
 | 
			
		||||
        }
 | 
			
		||||
        return ret
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const sticky = () => {
 | 
			
		||||
        if (active) {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        if (!elStyle.height) {
 | 
			
		||||
          elStyle.height = `${el.offsetHeight}px`
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        elStyle.position = 'fixed'
 | 
			
		||||
        elStyle.width = `${elWidth}px`
 | 
			
		||||
        placeholder.style.display = 'inline-block'
 | 
			
		||||
        active = true
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const reset = () => {
 | 
			
		||||
        if (!active) {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        elStyle.position = ''
 | 
			
		||||
        placeholder.style.display = 'none'
 | 
			
		||||
        active = false
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const check = () => {
 | 
			
		||||
        const scrollTop = getScroll(window, true)
 | 
			
		||||
        const offsetTop = el.getBoundingClientRect().top
 | 
			
		||||
        if (offsetTop < stickyTop) {
 | 
			
		||||
          sticky()
 | 
			
		||||
        } else {
 | 
			
		||||
          if (scrollTop < elHeight + stickyTop) {
 | 
			
		||||
            reset()
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      listenAction = () => {
 | 
			
		||||
        check()
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      window.addEventListener('scroll', listenAction)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    unbind() {
 | 
			
		||||
      window.removeEventListener('scroll', listenAction)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default vueSticky
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								src/directive/waves/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/directive/waves/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
import waves from './waves'
 | 
			
		||||
 | 
			
		||||
const install = function(Vue) {
 | 
			
		||||
  Vue.directive('waves', waves)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (window.Vue) {
 | 
			
		||||
  window.waves = waves
 | 
			
		||||
  Vue.use(install); // eslint-disable-line
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
waves.install = install
 | 
			
		||||
export default waves
 | 
			
		||||
							
								
								
									
										26
									
								
								src/directive/waves/waves.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/directive/waves/waves.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
.waves-ripple {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    border-radius: 100%;
 | 
			
		||||
    background-color: rgba(0, 0, 0, 0.15);
 | 
			
		||||
    background-clip: padding-box;
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    -webkit-user-select: none;
 | 
			
		||||
    -moz-user-select: none;
 | 
			
		||||
    -ms-user-select: none;
 | 
			
		||||
    user-select: none;
 | 
			
		||||
    -webkit-transform: scale(0);
 | 
			
		||||
    -ms-transform: scale(0);
 | 
			
		||||
    transform: scale(0);
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.waves-ripple.z-active {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
    -webkit-transform: scale(2);
 | 
			
		||||
    -ms-transform: scale(2);
 | 
			
		||||
    transform: scale(2);
 | 
			
		||||
    -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
 | 
			
		||||
    transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
 | 
			
		||||
    transition: opacity 1.2s ease-out, transform 0.6s ease-out;
 | 
			
		||||
    transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								src/directive/waves/waves.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/directive/waves/waves.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
			
		||||
import './waves.css'
 | 
			
		||||
 | 
			
		||||
const context = '@@wavesContext'
 | 
			
		||||
 | 
			
		||||
function handleClick(el, binding) {
 | 
			
		||||
  function handle(e) {
 | 
			
		||||
    const customOpts = Object.assign({}, binding.value)
 | 
			
		||||
    const opts = Object.assign({
 | 
			
		||||
      ele: el, // 波纹作用元素
 | 
			
		||||
      type: 'hit', // hit 点击位置扩散 center中心点扩展
 | 
			
		||||
      color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
 | 
			
		||||
    },
 | 
			
		||||
    customOpts
 | 
			
		||||
    )
 | 
			
		||||
    const target = opts.ele
 | 
			
		||||
    if (target) {
 | 
			
		||||
      target.style.position = 'relative'
 | 
			
		||||
      target.style.overflow = 'hidden'
 | 
			
		||||
      const rect = target.getBoundingClientRect()
 | 
			
		||||
      let ripple = target.querySelector('.waves-ripple')
 | 
			
		||||
      if (!ripple) {
 | 
			
		||||
        ripple = document.createElement('span')
 | 
			
		||||
        ripple.className = 'waves-ripple'
 | 
			
		||||
        ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
 | 
			
		||||
        target.appendChild(ripple)
 | 
			
		||||
      } else {
 | 
			
		||||
        ripple.className = 'waves-ripple'
 | 
			
		||||
      }
 | 
			
		||||
      switch (opts.type) {
 | 
			
		||||
        case 'center':
 | 
			
		||||
          ripple.style.top = rect.height / 2 - ripple.offsetHeight / 2 + 'px'
 | 
			
		||||
          ripple.style.left = rect.width / 2 - ripple.offsetWidth / 2 + 'px'
 | 
			
		||||
          break
 | 
			
		||||
        default:
 | 
			
		||||
          ripple.style.top =
 | 
			
		||||
            (e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop ||
 | 
			
		||||
              document.body.scrollTop) + 'px'
 | 
			
		||||
          ripple.style.left =
 | 
			
		||||
            (e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft ||
 | 
			
		||||
              document.body.scrollLeft) + 'px'
 | 
			
		||||
      }
 | 
			
		||||
      ripple.style.backgroundColor = opts.color
 | 
			
		||||
      ripple.className = 'waves-ripple z-active'
 | 
			
		||||
      return false
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!el[context]) {
 | 
			
		||||
    el[context] = {
 | 
			
		||||
      removeHandle: handle
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    el[context].removeHandle = handle
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return handle
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  bind(el, binding) {
 | 
			
		||||
    el.addEventListener('click', handleClick(el, binding), false)
 | 
			
		||||
  },
 | 
			
		||||
  update(el, binding) {
 | 
			
		||||
    el.removeEventListener('click', el[context].removeHandle, false)
 | 
			
		||||
    el.addEventListener('click', handleClick(el, binding), false)
 | 
			
		||||
  },
 | 
			
		||||
  unbind(el) {
 | 
			
		||||
    el.removeEventListener('click', el[context].removeHandle, false)
 | 
			
		||||
    el[context] = null
 | 
			
		||||
    delete el[context]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user