feat 搭建架构骨架
This commit is contained in:
35
src/directives/debounce.ts
Normal file
35
src/directives/debounce.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { Directive } from 'vue'
|
||||
|
||||
interface DebounceBinding {
|
||||
handler: (...args: unknown[]) => void
|
||||
delay?: number
|
||||
}
|
||||
|
||||
type DebounceValue = DebounceBinding['handler'] | DebounceBinding
|
||||
|
||||
const listenerMap = new WeakMap<Element, EventListener>()
|
||||
|
||||
function normalize(value: DebounceValue): DebounceBinding {
|
||||
return typeof value === 'function' ? { handler: value } : value
|
||||
}
|
||||
|
||||
/** v-debounce 防抖点击:v-debounce="fn" 或 v-debounce="{ handler: fn, delay: 500 }" */
|
||||
const debounce: Directive<Element, DebounceValue> = {
|
||||
mounted(el, binding) {
|
||||
const { handler, delay = 300 } = normalize(binding.value)
|
||||
let timer: ReturnType<typeof setTimeout> | null = null
|
||||
const listener: EventListener = () => {
|
||||
if (timer !== null) clearTimeout(timer)
|
||||
timer = setTimeout(() => handler(), delay)
|
||||
}
|
||||
listenerMap.set(el, listener)
|
||||
el.addEventListener('click', listener)
|
||||
},
|
||||
unmounted(el) {
|
||||
const listener = listenerMap.get(el)
|
||||
if (listener) el.removeEventListener('click', listener)
|
||||
listenerMap.delete(el)
|
||||
},
|
||||
}
|
||||
|
||||
export default debounce
|
||||
12
src/directives/index.ts
Normal file
12
src/directives/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { App } from 'vue'
|
||||
import lazy from './lazy'
|
||||
import debounce from './debounce'
|
||||
import throttle from './throttle'
|
||||
|
||||
/** main.ts 调用:统一注册自定义指令 */
|
||||
export function setupDirectives(app: App): void {
|
||||
app
|
||||
.directive('lazy', lazy)
|
||||
.directive('debounce', debounce)
|
||||
.directive('throttle', throttle)
|
||||
}
|
||||
27
src/directives/lazy.ts
Normal file
27
src/directives/lazy.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { Directive } from 'vue'
|
||||
|
||||
const observerMap = new WeakMap<Element, IntersectionObserver>()
|
||||
|
||||
/** v-lazy 图片懒加载:v-lazy="图片地址" */
|
||||
const lazy: Directive<Element, string> = {
|
||||
mounted(el, binding) {
|
||||
if (!(el instanceof HTMLImageElement)) return
|
||||
const target = el
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
const entry = entries[0]
|
||||
if (entry?.isIntersecting) {
|
||||
if (binding.value) target.src = binding.value
|
||||
observer.disconnect()
|
||||
observerMap.delete(el)
|
||||
}
|
||||
})
|
||||
observerMap.set(el, observer)
|
||||
observer.observe(el)
|
||||
},
|
||||
unmounted(el) {
|
||||
observerMap.get(el)?.disconnect()
|
||||
observerMap.delete(el)
|
||||
},
|
||||
}
|
||||
|
||||
export default lazy
|
||||
38
src/directives/throttle.ts
Normal file
38
src/directives/throttle.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { Directive } from 'vue'
|
||||
|
||||
interface ThrottleBinding {
|
||||
handler: (...args: unknown[]) => void
|
||||
interval?: number
|
||||
}
|
||||
|
||||
type ThrottleValue = ThrottleBinding['handler'] | ThrottleBinding
|
||||
|
||||
const listenerMap = new WeakMap<Element, EventListener>()
|
||||
|
||||
function normalize(value: ThrottleValue): ThrottleBinding {
|
||||
return typeof value === 'function' ? { handler: value } : value
|
||||
}
|
||||
|
||||
/** v-throttle 节流点击:v-throttle="fn" 或 v-throttle="{ handler: fn, interval: 500 }" */
|
||||
const throttle: Directive<Element, ThrottleValue> = {
|
||||
mounted(el, binding) {
|
||||
const { handler, interval = 500 } = normalize(binding.value)
|
||||
let lastTime = 0
|
||||
const listener: EventListener = () => {
|
||||
const now = Date.now()
|
||||
if (now - lastTime >= interval) {
|
||||
lastTime = now
|
||||
handler()
|
||||
}
|
||||
}
|
||||
listenerMap.set(el, listener)
|
||||
el.addEventListener('click', listener)
|
||||
},
|
||||
unmounted(el) {
|
||||
const listener = listenerMap.get(el)
|
||||
if (listener) el.removeEventListener('click', listener)
|
||||
listenerMap.delete(el)
|
||||
},
|
||||
}
|
||||
|
||||
export default throttle
|
||||
Reference in New Issue
Block a user