主要实现代码
type Fn = (...args: any[]) => void
interface Events {
[name: string]: Fn[]
}
export class EventEmitter {
events: Events
constructor() {
this.events = {}
}
on(type: string, fn: Fn) {
if (!this.events[type]) {
this.events[type] = []
}
this.events[type].push(fn)
}
off(type?: string, fn?: Fn) {
if (!type && !fn) {
this.events = {}
return this
}
if (type) {
if (!fn) {
this.events[type] = []
return this
}
const events = this.events[type]
if (!events) {
return this
}
let count = events.length
while (count--) {
if (events[count] === fn) {
events.splice(count, 1)
}
}
return this
}
}
emit(type: string, ...args: any[]) {
const events = this.events[type]
if (!events) {
return
}
let ret
for (let i = 0; i < events.length; i++) {
const fn = events[i]
if (fn) {
ret = fn.apply(this, args) as unknown
if (ret === true) {
return ret
}
}
}
}
distory() {
this.events = {}
}
}
因为触发事件和实现不在一个文件中,添加了一个单利处理事件
let eventBus: EventEmitter
export function useEventBus() {
if (!eventBus) {
eventBus = new EventEmitter()
}
return eventBus
}
type Fn = (...args: any[]) => void
interface Events {
[name: string]: Fn[]
}
export class EventEmitter {
events: Events
constructor() {
this.events = {}
}
on(type: string, fn: Fn) {
if (!this.events[type]) {
this.events[type] = []
}
this.events[type].push(fn)
}
off(type?: string, fn?: Fn) {
if (!type && !fn) {
this.events = {}
return this
}
if (type) {
if (!fn) {
this.events[type] = []
return this
}
const events = this.events[type]
if (!events) {
return this
}
let count = events.length
while (count--) {
if (events[count] === fn) {
events.splice(count, 1)
}
}
return this
}
}
emit(type: string, ...args: any[]) {
const events = this.events[type]
if (!events) {
return
}
let ret
for (let i = 0; i < events.length; i++) {
const fn = events[i]
if (fn) {
ret = fn.apply(this, args) as unknown
if (ret === true) {
return ret
}
}
}
}
distory() {
this.events = {}
}
}
使用方法
<div class="shop-cart__ball-container">
<div v-for="(v, i) in items" :key="i">
<Transition @beforeEnter="beforeEnter" @enter="enter" @afterEnter="afterEnter">
<div class="ball" v-show="v.isShow">
<div class="inner"></div>
</div>
</Transition>
</div>
</div>
.ball-container {
.ball {
position: fixed;
bottom: 10px;
left: 25px;
transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41);
.inner {
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--op-primary-color);
transition: all 0.4s linear;
}
}
}