import ueTooltips from '@/components/ueTooltips'
import ueLoading from '@/components/ueLoading'
export default {
install (Vue, options) {
Vue.prototype.$bus = new Vue()
Vue.directive('ue-tooltips', {
inserted (el, binding, vnode) {
const placementType = ['top', 'right', 'bottom', 'left']
const { click, light } = binding.modifiers
const placements = placementType.filter(placement => binding.modifiers[placement])[0] || 'top'
el._tooltipsOptions = {
content: binding.value || '',
placement: placements,
theme: light ? 'light' : 'dark',
target: el
}
el._tooltipsHandler = function tipHandler (e) {
click && e.stopPropagation()
if (binding.value == null) return
if (binding.value === 'object') {
const { content, placement, theme } = binding.value
el._tooltipsOptions = Object.assign(options, { content, placement, theme })
}
el._tooltipsInstance = ueTooltips(el._tooltipsOptions)
}
el._tooltipsMouseleaveHandler = function tipMouseleaveHandler () {
if (el._tooltipsInstance) {
el._tooltipsInstance.updateTips(false)
}
}
if (click) {
el.addEventListener('click', el._tooltipsHandler)
document.addEventListener('click', el._tooltipsMouseleaveHandler)
window.addEventListener('mousewheel', el._tooltipsMouseleaveHandler)
} else {
el.addEventListener('mouseenter', el._tooltipsHandler)
el.addEventListener('mouseleave', el._tooltipsMouseleaveHandler)
}
},
update (el, { value, oldValue }) {
el._tooltipsOptions = value
},
unbind (el) {
if (el._tooltipsHandler) {
el.removeEventListener('click', el._tooltipsHandler)
el.removeEventListener('mouseenter', el._tooltipsHandler)
}
if (el._tooltipsMouseleaveHandler) {
el.removeEventListener('mouseleave', el._tooltipsMouseleaveHandler)
document.removeEventListener('click', el._tooltipsMouseleaveHandler)
window.addEventListener('mousewheel', el._tooltipsMouseleaveHandler)
}
delete el._tooltipsHandler
delete el._tooltipsMouseleaveHandler
delete el._tooltipsOptions
delete el._tooltipsInstance
}
})
Vue.directive('ue-loading', {
inserted (el, { value, modifiers }, vnode) {
const { btn } = modifiers
let visible = value || false
let instance = ueLoading({
target: el,
visible,
isBtn: btn
})
el._loading = visible
el._loadingInstance = instance
instance = null
visible = null
},
update (el, { value }) {
if (el._loading !== value) {
el._loading = value
el._loadingInstance.updateLoading(value)
}
},
unbind (el) {
el._loadingInstance.doDestory()
el._loadingInstance = null
el._loading = null
}
})
Vue.directive('auth', {
inserted (el, { value }, vnode) {
el._authHandler = (el, vnode) => {
const { context: { $store: { getters: { getAuthButtons, getAuthButtonStatus } } } } = vnode
el.classList.add('none')
if (getAuthButtons.length) {
if (getAuthButtonStatus(value)) {
el.classList.remove('none')
} else {
el.parentNode && el.parentNode.removeChild(el)
}
}
}
el._authHandler(el, vnode)
},
update (el, { value }, vnode) {
el._authHandler(el, vnode)
}
})
Vue.directive('goBack', {
inserted (el, { value }, vnode) {
el._goBackHandler = () => {
if (typeof (value) === 'undefined') {
window.history.go(-1)
}
}
el.addEventListener('click', el._goBackHandler)
},
update (el, { value }) {
if (value === true) {
window.history.go(-1)
}
},
unbind (el) {
el.removeEventListener('click', el._goBackHandler)
}
})
Vue.directive('ue-preview', {
inserted (el, { value }, vnode) {
let visible = value || false
let instance = ueMediaPreview({
visible
})
el._preview = visible
el._previewInstance = instance
instance = null
visible = null
},
update (el, { value }) {
if (el._preview !== value) {
el._preview = value
el._previewInstance.updateStatus(value)
}
},
unbind (el) {
el._previewInstance.doDestory()
el._previewInstance = null
el._preview = null
}
})
Vue.directive('ue-backTop', {
inserted (el, binding, vnode) {
el._scrollTimer = null
el._cancelScroll = false
if (!el._backTopDom) {
el._backTopDom = document.createElement('div')
el._backTopDom.className = 'ue-back-top'
el._backTopDom.title = '返回顶部'
el._backTopDom.innerHTML = '<i class="hae-icon icon-backtop"></i>'
document.body.appendChild(el._backTopDom)
}
const scrollHandler = () => {
if (el.scrollTop >= (el.offsetHeight * 0.5)) {
el._backTopDom.className = 'ue-back-top active'
} else {
el._backTopDom.className = 'ue-back-top'
}
}
const resetScrollHandler = () => {
if (el._cancelScroll === false) {
const _baseNum = el.scrollTop <= 20 ? 1 : el.scrollTop * 0.25
clearInterval(el._scrollTimer)
el._scrollTimer = setInterval(() => {
const osTop = el.scrollTop
const ispeed = Math.floor(osTop - _baseNum)
document.documentElement.scrollTop = el.scrollTop = ispeed
if (osTop <= 0) {
clearInterval(el._scrollTimer)
}
}, 50)
} else {
clearInterval(el._scrollTimer)
el._cancelScroll = true
}
}
el.addEventListener('scroll', scrollHandler)
el._backTopDom.addEventListener('click', resetScrollHandler)
},
update (el, binding, vnode) {
el._backTopDom.className = 'ue-back-top'
if (el.scrollTop >= (el.offsetHeight * 0.5)) {
el._backTopDom.className = 'ue-back-top active'
}
},
unbind (el, binding, vnode) {
el._backTopDom.className = 'ue-back-top'
document.body.removeChild(el._backTopDom)
clearInterval(el._scrollTimer)
delete el._scrollTimer
delete el._cancelScroll
delete el._backTopDom
}
})
Vue.directive('ue-copy', {
bind (el, { value }) {
el.$value = value
el._copyHandler = () => {
if (!el.$value) {
return
}
const textarea = document.createElement('textarea')
textarea.readOnly = 'readonly'
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
textarea.value = el.$value
document.body.appendChild(textarea)
textarea.select()
const result = document.execCommand('Copy')
if (result) {
}
document.body.removeChild(textarea)
}
el.addEventListener('click', el._copyHandler)
},
componentUpdated (el, { value }) {
el.$value = value
},
unbind (el) {
el._copyHandler && el.removeEventListener('click', el._copyHandler)
}
})
}
}
import { Tooltips } from '@/components/ue/ueTooltips'
import { Loading } from '@/components/ue/ueLoading'
export default {
install (Vue, options) {
Vue.prototype.$bus = new Vue()
Vue.directive('ue-tooltips', {
inserted (el, binding, vnode) {
const placementType = ['top', 'right', 'bottom', 'left', 'top-right', 'bottom-right']
const { click, light, multiple = false } = binding.modifiers
const placement = placementType.filter(key => binding.modifiers[key])[0] || 'top'
const getValue = function (binding, key = 'content') {
if (Object.prototype.toString.call(binding.value) === '[object Object]') {
return binding.value[key] || ''
}
return binding.value || ''
}
const getStyle = function (element, styleName) {
if (!element || !styleName) return null
try {
var computed = document.defaultView.getComputedStyle(element, '');
return element.style[styleName] || computed ? computed[styleName] : null;
} catch (e) {
return element.style[styleName];
}
}
let content = getValue(binding)
const line = getValue(binding, 'line') || 1
const customClass = getValue(binding, 'customClass')
if (line > 1) {
let str = content || el.textContent.trim()
const lineHeight = parseFloat(getStyle(el, 'lineHeight'), 10)
const padding = (parseFloat(getStyle(el, 'paddingLeft'), 10) || 0) +
(parseFloat(getStyle(el, 'paddingRight'), 10) || 0);
while ((el.offsetHeight - padding) > (line * lineHeight)) {
el.innerText = el.innerText.replace(/(\s)*([a-zA-Z0-9]+|\W)(\.\.\.)?$/, '...')
}
content = str
} else {
Object.entries({
'text-overflow': 'ellipsis',
'white-space': 'nowrap',
'overflow': 'hidden'
}).map(item => {
const [key, value] = item
el.style[key] = value
})
}
el._tooltipsOptions = {
content,
placement,
multiple,
theme: light ? 'light' : 'dark',
target: el,
customClass
}
el._tooltipsHandler = function (e) {
click && e.stopPropagation()
if (el._tooltipsInstance) {
el._tooltipsInstance.updateVisible(true)
}
if (!content) {
const range = document.createRange()
range.setStart(e.target, 0)
range.setEnd(e.target, e.target.childNodes.length)
const rangeWidth = parseInt(range.getBoundingClientRect().width, 10)
const padding = (parseInt(getStyle(e.target, 'paddingLeft'), 10) || 0) +
(parseInt(getStyle(e.target, 'paddingRight'), 10) || 0);
if ((rangeWidth + padding > e.target.offsetWidth || e.target.scrollWidth > e.target.offsetWidth)) {
el._tooltipsOptions.content = e.target.textContent.trim()
} else {
return null
}
}
el._tooltipsInstance = Tooltips(el._tooltipsOptions)
}
el._tooltipsMouseleaveHandler = function (e) {
if (el._tooltipsInstance) {
el._tooltipsInstance.updateVisible(false)
click && (el._tooltipsInstance = null)
}
}
if (click) {
el.addEventListener('click', el._tooltipsHandler)
document.addEventListener('click', el._tooltipsMouseleaveHandler)
} else {
el.addEventListener('mouseenter', el._tooltipsHandler)
el.addEventListener('mouseleave', el._tooltipsMouseleaveHandler)
}
window.addEventListener('mousewheel', el._tooltipsMouseleaveHandler)
},
update (el, { value, oldValue }) {
},
unbind (el) {
if (el._tooltipsHandler) {
el.removeEventListener('click', el._tooltipsHandler)
el.removeEventListener('mouseenter', el._tooltipsHandler)
}
if (el._tooltipsMouseleaveHandler) {
el.removeEventListener('mouseleave', el._tooltipsMouseleaveHandler)
document.removeEventListener('click', el._tooltipsMouseleaveHandler)
window.addEventListener('mousewheel', el._tooltipsMouseleaveHandler)
}
delete el._tooltipsHandler
delete el._tooltipsMouseleaveHandler
delete el._tooltipsOptions
delete el._tooltipsInstance
}
})
Vue.directive('ue-loading', {
inserted (el, { value, modifiers }, vnode) {
const { btn } = modifiers
let visible = value || false
let instance = Loading({
target: el,
visible,
isBtn: btn
})
el._loading = visible
el._loadingInstance = instance
instance = null
visible = null
},
update (el, { value }) {
if (el._loading !== value) {
el._loading = value
el._loadingInstance.updateLoading(value)
}
},
unbind (el) {
el._loadingInstance.doDestory()
el._loadingInstance = null
el._loading = null
}
})
Vue.directive('auth', {
inserted (el, { value }, vnode) {
el._authHandler = (el, vnode) => {
const { context: { $store: { getters: { getAuthButtons, getAuthButtonStatus } } } } = vnode
el.classList.add('none')
if (getAuthButtons.length) {
if (getAuthButtonStatus(value)) {
el.classList.remove('none')
} else {
el.parentNode && el.parentNode.removeChild(el)
}
}
}
el._authHandler(el, vnode)
},
update (el, { value }, vnode) {
el._authHandler(el, vnode)
}
})
Vue.directive('avoid-repeat', {
inserted (el, binding) {
function __avoidRepeatHandler__ () {
if (el.__clickDisabled__) return
el.__clickDisabled__ = true
el.__originalPointerEvents__ = el.style.pointerEvents
el.style.pointerEvents = 'none'
setTimeout(() => {
el.__clickDisabled__ = false
el.style.pointerEvents = el.__originalPointerEvents__
}, binding.value || 500)
}
el.addEventListener('click', __avoidRepeatHandler__)
el.__avoidRepeatHandler__ = __avoidRepeatHandler__
},
unbind (el) {
el.removeEventListener('click', el.__avoidRepeatHandler__)
delete el.__clickDisabled__
delete el.__originalPointerEvents__
}
})
Vue.directive('goBack', {
inserted (el, { value }, vnode) {
el._goBackHandler = () => {
if (typeof (value) === 'undefined') {
window.history.go(-1)
}
}
el.addEventListener('click', el._goBackHandler)
},
update (el, { value }) {
if (value === true) {
window.history.go(-1)
}
},
unbind (el) {
el.removeEventListener('click', el._goBackHandler)
}
})
Vue.directive('ue-preview', {
inserted (el, { value }, vnode) {
let visible = value || false
let instance = ueMediaPreview({
visible
})
el._preview = visible
el._previewInstance = instance
instance = null
visible = null
},
update (el, { value }) {
if (el._preview !== value) {
el._preview = value
el._previewInstance.updateStatus(value)
}
},
unbind (el) {
el._previewInstance.doDestory()
el._previewInstance = null
el._preview = null
}
})
Vue.directive('ue-backTop', {
inserted (el, binding, vnode) {
el._scrollTimer = null
el._cancelScroll = false
if (!el._backTopDom) {
el._backTopDom = document.createElement('div')
el._backTopDom.className = 'ue-back-top'
el._backTopDom.title = '返回顶部'
el._backTopDom.innerHTML = '<i class="hae-icon icon-backtop"></i>'
document.body.appendChild(el._backTopDom)
}
const scrollHandler = () => {
if (el.scrollTop >= (el.offsetHeight * 0.5)) {
el._backTopDom.className = 'ue-back-top active'
} else {
el._backTopDom.className = 'ue-back-top'
}
}
const resetScrollHandler = () => {
if (el._cancelScroll === false) {
const _baseNum = el.scrollTop <= 20 ? 1 : el.scrollTop * 0.25
clearInterval(el._scrollTimer)
el._scrollTimer = setInterval(() => {
const osTop = el.scrollTop
const ispeed = Math.floor(osTop - _baseNum)
document.documentElement.scrollTop = el.scrollTop = ispeed
if (osTop <= 0) {
clearInterval(el._scrollTimer)
}
}, 50)
} else {
clearInterval(el._scrollTimer)
el._cancelScroll = true
}
}
el.addEventListener('scroll', scrollHandler)
el._backTopDom.addEventListener('click', resetScrollHandler)
},
update (el, binding, vnode) {
el._backTopDom.className = 'ue-back-top'
if (el.scrollTop >= (el.offsetHeight * 0.5)) {
el._backTopDom.className = 'ue-back-top active'
}
},
unbind (el, binding, vnode) {
el._backTopDom.className = 'ue-back-top'
document.body.removeChild(el._backTopDom)
clearInterval(el._scrollTimer)
delete el._scrollTimer
delete el._cancelScroll
delete el._backTopDom
}
})
Vue.directive('ue-copy', {
bind (el, { value }) {
el.$value = value
el._copyHandler = () => {
if (!el.$value) {
return
}
const textarea = document.createElement('textarea')
textarea.readOnly = 'readonly'
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
textarea.value = el.$value
document.body.appendChild(textarea)
textarea.select()
const result = document.execCommand('Copy')
if (result) {
}
document.body.removeChild(textarea)
}
el.addEventListener('click', el._copyHandler)
},
componentUpdated (el, { value }) {
el.$value = value
},
unbind (el) {
el._copyHandler && el.removeEventListener('click', el._copyHandler)
}
})
Vue.directive('ue-img-error', {
async inserted (el, { value, modifiers }, vnode) {
el._imgErrorUrl = value || 'images/logo.png'
el._getImgError = (url) => {
return new Promise((resolve, reject) => {
const img = new Image()
img.src = url
img.onload = (e) => {
resolve(img)
}
img.onerror = (e) => {
resolve(null)
}
})
}
el.updateImgSrc = async () => {
let imgError = await el._getImgError(el.src)
if (!imgError) {
imgError = await el._getImgError(el._imgErrorUrl)
if (!imgError) {
el.parentNode && el.parentNode.removeChild(el)
} else {
el.src = el._imgErrorUrl
}
}
}
el.updateImgSrc()
},
async update (el, { value }) {
el.updateImgSrc()
},
unbind (el) {
}
})
Vue.directive('ue-image', {
async inserted (el, { value }, vnode) {
el._imageHandler = async (value) => {
if (!/.(jpg|gif|png|jepg)$/g.test(value)) {
throw new Error('图片地址错误')
}
if (el.tagName.toLocaleLowerCase() !== 'img') {
throw new Error('DOM节点非img')
}
const getImage = (url) => new Promise((resolve) => {
var img = new Image()
img.src = url
img.onload = function () {
if (this.complete) {
resolve(true)
img = null
}
}
img.onerror = function () {
resolve(false)
img = null
}
})
let result = await getImage(value)
if (result) {
el.setAttribute('src', value)
} else {
const defaultSrc = el.getAttribute('data-default-src') || 'images/icon-noData2.png'
result = await getImage(defaultSrc)
if (result) {
el.setAttribute('src', defaultSrc)
} else {
el.parentNode && el.parentNode.removeChild(el)
}
}
}
},
update (el, { value }) {
el._imageHandle(value)
},
unbind (el) {
el._imageHandle = null
}
})
}
}
console