magiccube-vue3
Version:
vue3-js版组件库
105 lines (81 loc) • 2.73 kB
JavaScript
import { createVNode, render as $render, isVNode } from 'vue'
import script from './Component'
const GAP_SIZE = 16
let SEED = 1
const positionType = {
'top-right': [],
'top-left': [],
'bottom-right': [],
'bottom-left': [],
}
const notify = (args) => {
if (typeof window === 'undefined') return false
let options = null
if (typeof args === 'string' || isVNode(args)) {
options = { message: args }
} else {
options = { ...args }
}
const position = options.position || 'top-right'
/**
* setting vertical distance
*/
let verticalOffset = options.offset || 0
positionType[position].forEach(({ vm }) => {
verticalOffset += (vm.el?.offsetHeight || 0) + GAP_SIZE
})
verticalOffset += GAP_SIZE
const id = `notification_${SEED++}`
const userOnClose = options.onClose
const props = {
...options,
offset: verticalOffset,
visible: false,
id,
onClose: () => {
close(id, position, userOnClose, el)
},
}
const container = document.createElement('div') // 创建container
const vm = createVNode(
script,
props,
isVNode(props.message) ? {
default: () => props.message
} : null
)
$render(vm, container)
positionType[position].push({ vm })
const el = container.firstElementChild
document.body.appendChild(el)
}
function close(id, position, userOnClose, ele) {
const commonPositionArr = positionType[position] // 同一位置点击生成的提示框数组
const index = commonPositionArr.findIndex(
({ vm }) => {
return vm.component.props?.id === id
}
)
if (index === -1) return false
const { vm: currentRemove } = commonPositionArr[index] // 该下标所在的元素
if(!currentRemove) return false
const removedHeight = currentRemove.el.offsetHeight // 该下标元素的高
const verticalPosition = position.startsWith('top')? 'top' : 'bottom' // 获取该下标是top or bottom
if(typeof userOnClose === 'function') {
userOnClose(commonPositionArr[index])
}
commonPositionArr.splice(index, 1) // 删除该下标元素
setTimeout(() => {
document.body.removeChild(ele)
}, 0)
/* 还剩下的数组 */
const length = commonPositionArr.length
if(length < 1) return false
/* 更新每一个vm的top = 当前点击的 */
for(let i = index; i< length; i++) {
const { el, component} = commonPositionArr[i].vm
const pos = parseInt(el.style[verticalPosition], 10) - removedHeight - GAP_SIZE
component.props.offset = pos
}
}
export default notify