Vue组件中方法的this一直指向vm,源码标记
Vue组件中的方法this固定指向当前组件Vm具体的原因是源码中使用了装饰者模式进行了this强制绑定
·
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
*/
}
}
源码
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是改变不了指向的
更多推荐
已为社区贡献4条内容
所有评论(0)