在书写petite-vue和Vue最舒服的莫过于通过@click绑定事件,而且在移除元素时框架会帮咱们主动解除绑定。省去了过来通过jQuery的累赘。而事件绑定在petite-vue中就是一个指令(directive),和其余指令相似。

深刻v-on的工作原理

walk办法在解析模板时会遍历元素的个性汇合el.attributes,当属性名称name匹配v-on@时,则将属性名称和属性值压入deferred队列的队尾,当以后元素所有属性绑定和v-modal解决后以及子元素所有属性绑定、v-modal和事件绑定解决后再解决。

那问题来了,为什么要将事件绑定放到最初解决呢?

//文件 ./src/on.tsconst systemModifiers = ['ctrl', 'shift', 'alt', 'meta']const modifiersGuards: Record<  string,  (e: Event, modifiers: Record<string, true>) => void | boolean> = {  stop: e => e.stopPropagation(),  prevent: e => e.preventDefault(),  self: e => e.target !== e.currentTarget,  ctrl: e => !(e as KeyedEvent).ctrlKey,  shift: e => !(e as KeyedEvent).shiftKey,  alt: e => !(e as KeyedEvent).altKey,  meta: e => !(e as KeyedEvent).metaKey,  left: e => 'button' in e && (e as MouseEvent).button !== 0,  middle: e => 'button' in e && (e as MouseEvent).button !== 1,  right: e => 'button' in e && (e as MouseEvent).button !== 2,  /* @click.alt.shift 将别离匹配alt和shift两个modifiers guards,当此时按alt+shift+ctrl时,两个modifiers guards均通过。   * 而@click.alt.shift.exact 将别离匹配alt、shift和exact,当此时按alt+shift+ctrl时,后面两个modifiers guards均通过,但最初的exact guard将返回true,不执行事件回调函数。   */  exact: (e, modifiers) =>     systemModifiers.some(m => (e as any)[`${m}Key`] && !modifiers[m])}export const on: Directive({ el, get, exp, arg, modifiers }) => {  let handler = simplePathRE.test(exp)    ? get(`(e => ${exp}(e)`)    : get(`($event => { ${exp} })`)  if (arg === 'vue:mounted') {    // 如果绑定的是生命周期函数mounted,但因为以后元素早已增加到DOM树上,因而将函数压入micro queue执行    nextTick(handler)    return  }  else if (arg === 'vue:unmounted') {    // 如果绑定的是生命周期函数unmounted,则返回cleanup函数    return () => handler()  }  if (modifiers) {    // 如果存在modifiers,则对事件绑定进行加强    if (arg === 'click') {      // @click.right 对应的DOM事件是contextmenu      if (modifiers.right) arg = 'contextmenu'      // @click.middle 对应的DOM事件是mouseup      if (modifiers.middle) arg = 'mouseup'    }    const raw = hanlder    handler = (e: Event) => {      if ('key' in e && !(hyphenate((e as KeyboardEvent).key) in modifiers)) {        /* 如果为键盘事件,键不在没有在modifiers中指定则不执行事件回调函数         * key值为a、b、CapsLock等,hyphenate将CapsLock转换为caps-lock         */         return      }      for (const key in modifiers) {        // 执行modifiers对应的逻辑,若返回true则不执行事件回调函数        const guard = modiferGuards[key]        if (guard && guard(e, modifiers)) {          return        }        return raw(e)      }    }  }  // 竟然没有返回cleanup函数??大家能够去奉献代码了哈哈  listen(el, arg, handler, modifers)}
//文件 ./src/utils.tsexport const listen = (  el: Element,  event: string,  handler: any,  opotions?: any) => {  el.addEventListener(event, handler, options)}

总结

当初咱们曾经理解了v-bindv-on的工作原理,前面咱们一起看看v-modal吧!