Vue methods方法this指向問題
Vue methods 中不應該箭頭函數定義methods函數,因為箭頭函數綁定了父級作用域上下文,所以 this 打印出的結果是Window 對象
不使用箭頭函數的情況下,this 實際上是指向了一個 Proxy 對象。
vue 內部實際上對methods屬性中的方法進行了遍歷,將對應的方法且通過bind綁定了this:
// 實例化傳入的參數
export function applyOptions(instance: ComponentInternalInstance) {
// 調用 resolveMergedOptions函數對傳入的參數進行解析
const options = resolveMergedOptions(instance)
// 定義publicThis指向proxy對象
const publicThis = instance.proxy! as any
const ctx = instance.ctx
// 通過對象解構賦值獲取methods屬性
const { methods } = options
// 判斷是否有 methods 屬性
if (methods) {
// 如果存在,使用for-in 進行遍歷
for (const key in methods) {
// 獲取key值
const methodHandler = (methods as MethodOptions)[key]
// 使用 isFunction 判斷是否 key 是否是一個函數
if (isFunction(methodHandler)) {
// In dev mode, we use the `createRenderContext` function to define
// methods to the proxy target, and those are read-only but
// reconfigurable, so it needs to be redefined here
// 判斷是否為dev環境
if (__DEV__) {
Object.defineProperty(ctx, key, {
// 使用bind動態綁定this
value: methodHandler.bind(publicThis),
configurable: true,
enumerable: true,
writable: true
})
} else {
// 使用bind動態綁定this
ctx[key] = methodHandler.bind(publicThis)
}
if (__DEV__) {
checkDuplicateProperties!(OptionTypes.METHODS, key)
}
} else if (__DEV__) {
// 如果key 不是函數,dev環境下控制台打印警告
warn(
`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
`Did you reference the function correctly?`
)
}
}
}
}