vue 父组件调用子组件的函数_Vue源码全面解析六 initEvents 函数(处理父组件传递的事件)...

d31f778a7e1fe28138e56938714e5a3a.png

首先我们打开'src/core/instance/events.js'文件,代码如下:

export function initEvents (vm: Component) {  vm._events = Object.create(null)  vm._hasHookEvent = false  // init parent attached events  const listeners = vm.$options._parentListeners  if (listeners) {    updateComponentListeners(vm, listeners)  }}

以上代码主要的工作就是获取 'vm.$options._parentListeners'父组件传递过来的事件,如果存在就调用‘updateComponentListeners’函数。

updateComponentListeners函数代码如下:

export function updateComponentListeners (  vm: Component,  listeners: Object,  oldListeners: ?Object) {  target = vm  updateListeners(listeners, oldListeners || {}, add, remove, createOnceHandler, vm)  target = undefined}

可以看到这个函数就3行代码。

1、设置target为vm

2、调用updateListeners函数

3、清空target的值

updateListeners函数代码如下:

export function updateListeners (  on: Object,  oldOn: Object,  add: Function,  remove: Function,  createOnceHandler: Function,  vm: Component) {  let name, def, cur, old, event  for (name in on) {    def = cur = on[name]    old = oldOn[name]    event = normalizeEvent(name)    /* istanbul ignore if */    if (__WEEX__ && isPlainObject(def)) {      cur = def.handler      event.params = def.params    }    if (isUndef(cur)) {      process.env.NODE_ENV !== 'production' && warn(        `Invalid handler for event "${event.name}": got ` + String(cur),        vm      )    } else if (isUndef(old)) {      if (isUndef(cur.fns)) {        cur = on[name] = createFnInvoker(cur, vm)      }      if (isTrue(event.once)) {        cur = on[name] = createOnceHandler(event.name, cur, event.capture)      }      add(event.name, cur, event.capture, event.passive, event.params)    } else if (cur !== old) {      old.fns = cur      on[name] = old    }  }  for (name in oldOn) {    if (isUndef(on[name])) {      event = normalizeEvent(name)      remove(event.name, oldOn[name], event.capture)    }  }}

首先我们先看大致罗列一下此函数的作用:

1、获取新旧事件

2、处理事件的修饰符

3、创建事件调用函数

4、添加为自定义事件

5、销毁旧的事件

接下来我们来慢慢拆分一下这个函数功能。

  def = cur = on[name]  old = oldOn[name]  event = normalizeEvent(name)

‘cur’变量获取当前的事件,‘old’变量获取旧的事件。

‘normalizeEvent’处理当前事件修饰符

有如下三个修饰符:

1、capture 添加事件侦听器时使用 capture 模式

2、once 只触发一次回调

3、passive 以 { passive: true } 模式添加侦听器

 if (isUndef(cur.fns)) {   cur = on[name] = createFnInvoker(cur, vm) }

如果当前事件没有'fns'属性,则创建调用函数(createFnInvoker)。

createFnInvoker代码如下:

export function createFnInvoker (fns: Function | Array, vm: ?Component): Function {  function invoker () {    const fns = invoker.fns    if (Array.isArray(fns)) {      const cloned = fns.slice()      for (let i = 0; i < cloned.length; i++) {        invokeWithErrorHandling(cloned[i], null, arguments, vm, `v-on handler`)      }    } else {      // return handler return value for single handlers      return invokeWithErrorHandling(fns, null, arguments, vm, `v-on handler`)    }  }  invoker.fns = fns  return invoker}

可以看到定义了一个 ‘invoker’ 函数,然后给函数添加了 'fns'属性,然后 直接返回了该函数。

if (isTrue(event.once)) {  cur = on[name] = createOnceHandler(event.name, cur, event.capture)}

如果事件存在 'once' 修饰符,则调用 ‘createOnceHandler’ 函数。

createOnceHandler代码如下:

function createOnceHandler (event, fn) {  const _target = target  return function onceHandler () {    const res = fn.apply(null, arguments)    if (res !== null) {      _target.$off(event, onceHandler)    }  }}

可以看到直接返回了一个函数,这个函数被调用之后会调用 '$off'进行事件关闭。

add(event.name, cur, event.capture, event.passive, event.params)// add函数代码如下function add (event, fn) {  target.$on(event, fn)}

调用add函数,注册自定义事件。

 for (name in oldOn) {    if (isUndef(on[name])) {      event = normalizeEvent(name)      remove(event.name, oldOn[name], event.capture)    }  }

最后是对旧的事件进行关闭操作(remove函数)。

remove函数代码:

function remove (event, fn) {  target.$off(event, fn)}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值