💬 补充 hooks 文档
This commit is contained in:
@@ -1 +0,0 @@
|
||||
import './useClickOutside.ts'
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ref, onMounted, onUnmounted, Ref } from 'vue'
|
||||
|
||||
const x = undefined
|
||||
const useClickOutside = (elementRef: Ref<HTMLElement | null>) => {
|
||||
const isClickOutside = ref(false)
|
||||
const handler = (e: MouseEvent) => {
|
||||
if (elementRef.value) {
|
||||
if (elementRef.value.contains(e.target as HTMLElement)) {
|
||||
isClickOutside.value = false
|
||||
} else {
|
||||
isClickOutside.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', handler)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('click', handler)
|
||||
})
|
||||
return isClickOutside
|
||||
}
|
||||
export default useClickOutside
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ref, onMounted, onUnmounted, Ref } from 'vue'
|
||||
|
||||
const useFullScreen = () => {
|
||||
const isFullScreen = ref(false)
|
||||
|
||||
const fullScreen = function () {
|
||||
const docElm = document.documentElement
|
||||
switch (!isFullScreen.value) {
|
||||
case true:
|
||||
if (docElm.requestFullscreen) {
|
||||
docElm.requestFullscreen()
|
||||
}
|
||||
break
|
||||
case false:
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen()
|
||||
}
|
||||
break
|
||||
}
|
||||
isFullScreen.value = !isFullScreen.value
|
||||
}
|
||||
|
||||
return { isFullScreen, fullScreen }
|
||||
}
|
||||
export default useFullScreen
|
||||
@@ -1,103 +0,0 @@
|
||||
function useMove(el: any) {
|
||||
el.style.position = 'fixed'
|
||||
let offsetX: number,
|
||||
offsetY: number,
|
||||
oL: number,
|
||||
oT: number,
|
||||
oLeft: number,
|
||||
oTop: number
|
||||
const browser = {
|
||||
versions: (function () {
|
||||
const u = navigator.userAgent
|
||||
return {
|
||||
mobile: !!u.match(/AppleWebKit.*Mobile.*/), //判断设备
|
||||
// ..... 其他设备信息
|
||||
}
|
||||
})(),
|
||||
}
|
||||
if (!browser.versions.mobile) {
|
||||
//Pc
|
||||
if (el != null) {
|
||||
el.addEventListener('mousedown', function (event: any) {
|
||||
if (event.button == 0 && el != null) {
|
||||
const lexObj: any = getComputedStyle(el)
|
||||
offsetX =
|
||||
event.pageX - el.offsetLeft + parseInt(lexObj['margin-left'])
|
||||
offsetY =
|
||||
event.pageY - el.offsetTop + parseInt(lexObj['margin-right'])
|
||||
const move = function (event: any) {
|
||||
if (el != null) {
|
||||
let x = event.pageX - offsetX
|
||||
let y = event.pageY - offsetY
|
||||
if (x < 0) {
|
||||
x = 0
|
||||
} else if (
|
||||
x >
|
||||
document.documentElement.clientWidth - el.offsetWidth
|
||||
) {
|
||||
x = document.documentElement.clientWidth - el.offsetWidth
|
||||
}
|
||||
if (y < 0) {
|
||||
y = 0
|
||||
} else if (
|
||||
y >
|
||||
document.documentElement.clientHeight - el.offsetHeight
|
||||
) {
|
||||
y = document.documentElement.clientHeight - el.offsetHeight
|
||||
}
|
||||
el.style.left = x + 'px'
|
||||
el.style.top = y + 'px'
|
||||
}
|
||||
return false
|
||||
}
|
||||
document.addEventListener('mousemove', move)
|
||||
const stop = function () {
|
||||
document.removeEventListener('mousemove', move)
|
||||
document.removeEventListener('mouseup', stop)
|
||||
}
|
||||
document.addEventListener('mouseup', stop)
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
} else {
|
||||
//Mobile
|
||||
if (el != null) {
|
||||
const maxW = document.body.clientWidth - el.offsetWidth
|
||||
const maxH = document.body.clientHeight - el.offsetHeight
|
||||
const defaultEvent = function (e: any) {
|
||||
e.preventDefault()
|
||||
}
|
||||
el.addEventListener('touchstart', function (e: any) {
|
||||
const ev = e || window.event
|
||||
const touch = ev.targetTouches[0]
|
||||
oL = touch.clientX - el.offsetLeft
|
||||
oT = touch.clientY - el.offsetTop
|
||||
document.addEventListener('touchmove', defaultEvent, false)
|
||||
el.addEventListener('touchmove', function (e: any) {
|
||||
const ev = e || window.event
|
||||
const touch = ev.targetTouches[0]
|
||||
oLeft = touch.clientX - oL
|
||||
oTop = touch.clientY - oT
|
||||
if (oLeft < 0) {
|
||||
oLeft = 0
|
||||
} else if (oLeft >= maxW) {
|
||||
oLeft = maxW
|
||||
}
|
||||
if (oTop < 0) {
|
||||
oTop = 0
|
||||
} else if (oTop >= maxH) {
|
||||
oTop = maxH
|
||||
}
|
||||
el.style.left = oLeft + 'px'
|
||||
el.style.top = oTop + 'px'
|
||||
})
|
||||
el.addEventListener('touchend', function () {
|
||||
document.removeEventListener('touchmove', defaultEvent)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default useMove
|
||||
@@ -1,7 +0,0 @@
|
||||
import { ref, onMounted, onUnmounted, Ref } from 'vue'
|
||||
|
||||
const useNestedEvent = (elementRef: Ref<HTMLElement | null>) => {
|
||||
const event = ref(false)
|
||||
return event
|
||||
}
|
||||
export default useNestedEvent
|
||||
@@ -1,91 +0,0 @@
|
||||
// @ts-noCheck
|
||||
// 是否滚动
|
||||
export const hasScrollbar = () =>
|
||||
document.body.scrollHeight >
|
||||
(window.innerHeight || document.documentElement.clientHeight)
|
||||
// 窗口宽高
|
||||
export const winArea = (type?: any) =>
|
||||
document.documentElement[type ? 'clientWidth' : 'clientHeight']
|
||||
//
|
||||
export const scrollArea: any = (type: any) => {
|
||||
type = type ? 'scrollLeft' : 'scrollTop'
|
||||
return document.body[type] | document.documentElement[type]
|
||||
}
|
||||
|
||||
export function usePosition(elem?: any, elemView?: any, obj?: any) {
|
||||
if (!elemView) return
|
||||
obj = obj || {}
|
||||
|
||||
//如果绑定的是 document 或 body 元素,则直接获取鼠标坐标
|
||||
if (elem === document || elem.name === 'body') {
|
||||
obj.clickType = 'right'
|
||||
}
|
||||
|
||||
//绑定绑定元素的坐标
|
||||
const rect =
|
||||
obj.clickType === 'right'
|
||||
? (function () {
|
||||
const e = obj.e || window.event || {}
|
||||
return {
|
||||
left: e.clientX,
|
||||
top: e.clientY,
|
||||
right: e.clientX,
|
||||
bottom: e.clientY,
|
||||
}
|
||||
})()
|
||||
: elem.getBoundingClientRect()
|
||||
const elemWidth = elemView.offsetWidth //控件的宽度
|
||||
const elemHeight = elemView.offsetHeight //控件的高度
|
||||
|
||||
const margin = 5
|
||||
let left = rect.left
|
||||
let top = rect.bottom
|
||||
|
||||
//相对元素居中
|
||||
if (obj.align === 'center') {
|
||||
left = left - (elemWidth - elem.offsetWidth) / 2
|
||||
} else if (obj.align === 'right') {
|
||||
left = left - elemWidth + elem.offsetWidth
|
||||
}
|
||||
|
||||
//判断右侧是否超出边界
|
||||
if (left + elemWidth + margin > winArea('width')) {
|
||||
left = winArea('width') - elemWidth - margin //如果超出右侧,则将面板向右靠齐
|
||||
}
|
||||
//左侧是否超出边界
|
||||
if (left < margin) left = margin
|
||||
|
||||
//判断底部和顶部是否超出边界
|
||||
if (top + elemHeight + margin > winArea()) {
|
||||
//优先顶部是否有足够区域显示完全
|
||||
if (rect.top > elemHeight + margin) {
|
||||
top = rect.top - elemHeight - margin * 2 //顶部有足够的区域显示
|
||||
} else {
|
||||
//如果面板是鼠标右键弹出,且顶部没有足够区域显示,则将面板向底部靠齐
|
||||
if (obj.clickType === 'right') {
|
||||
top = winArea() - elemHeight - margin * 2
|
||||
if (top < 0) top = 0 //不能溢出窗口顶部
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//定位类型
|
||||
const position = obj.position
|
||||
if (position) elemView.style.position = position
|
||||
|
||||
//设置坐标
|
||||
elemView.style.left = left + (position === 'fixed' ? 0 : scrollArea(1)) + 'px'
|
||||
elemView.style.top = top + (position === 'fixed' ? 0 : scrollArea()) + 'px'
|
||||
|
||||
//防止页面无滚动条时,又因为弹出面板而出现滚动条导致的坐标计算偏差
|
||||
if (!hasScrollbar()) {
|
||||
const rect1 = elemView.getBoundingClientRect()
|
||||
//如果弹出面板的溢出窗口底部,则表示将出现滚动条,此时需要重新计算坐标
|
||||
if (!obj.SYSTEM_RELOAD && rect1.bottom + margin > winArea()) {
|
||||
obj.SYSTEM_RELOAD = true
|
||||
setTimeout(function () {
|
||||
usePosition(elem, elemView, obj)
|
||||
}, 50)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import type { App } from 'vue'
|
||||
import type { IDefineComponent, InstallOptions } from './module/type/index'
|
||||
|
||||
import './css/layui.css';
|
||||
import '@layui/layer-vue/lib/layer.css';
|
||||
import '@layui/layer-vue/lib/index.css';
|
||||
import '@layui/icons-vue/lib/index.css';
|
||||
|
||||
import { layer } from '@layui/layer-vue'
|
||||
|
||||
@@ -4,11 +4,11 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<script setup lang="ts">
|
||||
import { Nullable } from '/@src/module/type'
|
||||
import { Nullable } from '../type'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { HSBToHEX, RGBSTo, RGBToHSB } from '/@src/module/colorPicker/colorUtil'
|
||||
import { HSBToHEX, RGBSTo, RGBToHSB } from './colorUtil'
|
||||
import ColorPicker from './ColorPicker.vue'
|
||||
import { usePosition } from '/@src/hooks/usePosition'
|
||||
import { usePosition } from '@layui/hooks-vue'
|
||||
|
||||
interface BoxProps {
|
||||
color?: string
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<script setup name="LaySelect" lang="ts">
|
||||
import { defineProps, provide, ref, watch } from 'vue'
|
||||
import useClickOutside from '../../hooks/useClickOutside'
|
||||
import { useClickOutside } from '@layui/hooks-vue'
|
||||
|
||||
const dropdownRef = ref<null | HTMLElement>(null)
|
||||
const isClickOutside = useClickOutside(dropdownRef)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<script setup name="LaySelect" lang="ts">
|
||||
import { defineProps, provide, reactive, ref, watch } from 'vue'
|
||||
import useClickOutside from '../../hooks/useClickOutside'
|
||||
import { useClickOutside } from '@layui/hooks-vue'
|
||||
|
||||
const selectRef = ref<null | HTMLElement>(null)
|
||||
const isClickOutside = useClickOutside(selectRef)
|
||||
|
||||
Reference in New Issue
Block a user