Vue组件中方法的this一直指向vm,源码标记

Vue组件中,methods内的方法通过源码中的bind操作,确保this始终指向当前组件实例。即使在子组件中调用或使用call改变上下文,this仍保持不变。这种机制保证了方法内部的this正确性,防止了上下文丢失的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue组件中的方法this固定指向当前组件Vm
原因:源码中对methods方法进行了遍历bind(fn),固定了this为当前实例

示例代码


var fatherVm = {
    template: '<children-vm :testFnFn="testFn"/>',
    component: {
        childrenVm // var定义的话可以这样写
    },
    data() {
        return {
            info: 'fatherVm'
        }
    },
    methods: {
        testFn() {
            console.log("testFn -> testFn", this.info)
        }
    }
}

var childrenVm = {
    template: '<div></div>',
    props: ['testFn'],
    data() {
        return {
            info: 'childrenVm'
        }
    },
    created() {
        this.testFn()
        this.testFn.call({ info: 'custom' })
        /**
    * 输出为
    * "testFn -> testFn fatherVm"
    * "testFn -> testFn fatherVm"
    * thsi指向一直为 fatherVm
    */
    }
}

MDN function bind >

源码

vue 2.6源码
function initMethods (vm: Component, methods: Object) {
  const props = vm.$options.props
  for (const key in methods) {
    if (process.env.NODE_ENV !== 'production') {
      if (typeof methods[key] !== 'function') {
        warn(
          `Method "${key}" has type "${typeof methods[key]}" in the component definition. ` +
          `Did you reference the function correctly?`,
          vm
        )
      }
      if (props && hasOwn(props, key)) {
        warn(
          `Method "${key}" has already been defined as a prop.`,
          vm
        )
      }
      if ((key in vm) && isReserved(key)) {
        warn(
          `Method "${key}" conflicts with an existing Vue instance method. ` +
          `Avoid defining component methods that start with _ or $.`
        )
      }
    }
    // 装饰者闭包模式,返回的是一个新的function,内部还有执行fn,所以外部fn call时的this改变影响不到内层fn的this
    vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm)
  }
}

export const bind = Function.prototype.bind
  ? nativeBind
  : polyfillBind
/* istanbul ignore next */
function polyfillBind (fn: Function, ctx: Object): Function {
  function boundFn (a) {
    const l = arguments.length
    return l
      ? l > 1
        ? fn.apply(ctx, arguments)
        : fn.call(ctx, a)
      : fn.call(ctx)
  }

  boundFn._length = fn.length
  return boundFn
}

function nativeBind (fn: Function, ctx: Object): Function {
  return fn.bind(ctx)
}

装饰者闭包模式,返回的是一个新的function,闭包了内部执行function的this为当前实例vm
call,apply是改变不了指向的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值