Vue中methods的this指向問題淺析
如果是組件的話,將會是VueComponent實例對象,Vue和VueComponent兩個類其實差不都,今后會另外開章節(jié)描述兩者差別,這里先飄過。
比如下面的簡單的一個demo代碼,點擊按鈕打印出this。
<!DOCTYPE html>
<html lang="en">
<head>
<script src="../../dist/vue.js"></script>
</head>
<body>
<div id="app">
<button @click="printThis">What is this</button>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
counter: 0,
},
methods: {
printThis() {
console.log("this:", this);
},
},
});
</script>
</body>
</html>最終打印的結果將會如下:

很明顯,vue框架通過某種方法自動幫我們將methods下面的this指向到vue的實例對象了。
下面跟蹤下vue的源代碼,看下是怎么實現的。
首先,我們看下new Vue的入口,也即是Vue類的構造函數
function Vue(options) {
...
this._init(options);
}構造函數的參數options就是我們前面new Vue時傳入的帶有methods和data這些配置項的對象。
構造函數里面會做很多初始化的動作,這些動作都被封裝到_init這個方法中了。因為是通過this調用的,所以我們可以猜想到這個方法應該是寫到了Vue的prototype上的。
Vue.prototype._init = function (options?: Object) {
const vm: Component = this;
...
// 將含有methods和data等配置項的對象合并并掛到Vue實例對象vm的$options屬性上
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options);
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
);
...
initState(vm);
...
};
}該方法會將我們new Vue時提供的帶有methods和data的配置項放入到Vue實例對象的$options屬性中,然后調用initState方法。
export function initState(vm: Component) {
...
if (vm.$options.methods) initMethods(vm, vm.$options.methods);
...
}因為我們提供了methods選項,記得吧?我們上面methods寫了printThis方法。所以這里會調用到initMethods方法,傳入的參數是Vue實例對象vm和我們傳進來的methods選項。
function initMethods(vm: Component, methods: Object) {
...
for (const key in methods) {
...
vm[key] =
typeof methods[key] !== "function" ? noop : bind(methods[key], vm);
}
}上面的代碼邏輯主要就是循環(huán)methods里面的每個方法,然后將這些方法以相同的名字在vue實例對象中也放一份,比如我們的printThis方法,在vue實例對象中也來一份。

但是放到vue實例對象中的這些方法和原來的有一些區(qū)別,什么區(qū)別呢?就是通過上面的bind方法做了些調整。
這個bind方法看上去是不是很眼熟,名字和我們javascript用來修改this指向的bind方法一樣。
而事實上這個bind方法最終調用的是一個叫做nativeBind的方法
function nativeBind (fn: Function, ctx: Object): Function {
return fn.bind(ctx)
}該方法做的事情就是將我們傳入來的method,即我們這里的printThis方法的this的指向,指向到了傳進來的vm,即我們的vue實例對象。
而這,也即是為什么我們在methods里面的方法可以通過this直接訪問到Vue實例對象的原因了。
到此這篇關于Vue中methods的this指向問題淺析的文章就介紹到這了,更多相關Vue methods內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue2+elementui的el-table固定列會遮住橫向滾動條及錯位問題解決方案
這篇文章主要介紹了vue2+elementui的el-table固定列會遮住橫向滾動條及錯位問題解決方案,主要解決固定列錯位后, 接下來就是把固定列往上提滾動條的高度就不會影響了,需要的朋友可以參考下2024-01-01
Vue2+SpringBoot實現數據導出到csv文件并下載的使用示例
本文主要介紹了Vue2+SpringBoot實現數據導出到csv文件并下載,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-10-10
vue之“} expected“和“at-rule or selector ex
這篇文章主要介紹了vue之“} expected“和“at-rule or selector expected“報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03

