Vue中methods的this指向問(wèn)題淺析
如果是組件的話(huà),將會(huì)是VueComponent實(shí)例對(duì)象,Vue和VueComponent兩個(gè)類(lèi)其實(shí)差不都,今后會(huì)另外開(kāi)章節(jié)描述兩者差別,這里先飄過(guò)。
比如下面的簡(jiǎn)單的一個(gè)demo代碼,點(diǎn)擊按鈕打印出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>
最終打印的結(jié)果將會(huì)如下:
很明顯,vue框架通過(guò)某種方法自動(dòng)幫我們將methods下面的this指向到vue的實(shí)例對(duì)象了。
下面跟蹤下vue的源代碼,看下是怎么實(shí)現(xiàn)的。
首先,我們看下new Vue的入口,也即是Vue類(lèi)的構(gòu)造函數(shù)
function Vue(options) { ... this._init(options); }
構(gòu)造函數(shù)的參數(shù)options就是我們前面new Vue時(shí)傳入的帶有methods和data這些配置項(xiàng)的對(duì)象。
構(gòu)造函數(shù)里面會(huì)做很多初始化的動(dòng)作,這些動(dòng)作都被封裝到_init這個(gè)方法中了。因?yàn)槭峭ㄟ^(guò)this調(diào)用的,所以我們可以猜想到這個(gè)方法應(yīng)該是寫(xiě)到了Vue的prototype上的。
Vue.prototype._init = function (options?: Object) { const vm: Component = this; ... // 將含有methods和data等配置項(xiàng)的對(duì)象合并并掛到Vue實(shí)例對(duì)象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); ... }; }
該方法會(huì)將我們new Vue時(shí)提供的帶有methods和data的配置項(xiàng)放入到Vue實(shí)例對(duì)象的$options屬性中,然后調(diào)用initState方法。
export function initState(vm: Component) { ... if (vm.$options.methods) initMethods(vm, vm.$options.methods); ... }
因?yàn)槲覀兲峁┝薽ethods選項(xiàng),記得吧?我們上面methods寫(xiě)了printThis方法。所以這里會(huì)調(diào)用到initMethods方法,傳入的參數(shù)是Vue實(shí)例對(duì)象vm和我們傳進(jìn)來(lái)的methods選項(xiàng)。
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里面的每個(gè)方法,然后將這些方法以相同的名字在vue實(shí)例對(duì)象中也放一份,比如我們的printThis方法,在vue實(shí)例對(duì)象中也來(lái)一份。
但是放到vue實(shí)例對(duì)象中的這些方法和原來(lái)的有一些區(qū)別,什么區(qū)別呢?就是通過(guò)上面的bind方法做了些調(diào)整。
這個(gè)bind方法看上去是不是很眼熟,名字和我們javascript用來(lái)修改this指向的bind方法一樣。
而事實(shí)上這個(gè)bind方法最終調(diào)用的是一個(gè)叫做nativeBind的方法
function nativeBind (fn: Function, ctx: Object): Function { return fn.bind(ctx) }
該方法做的事情就是將我們傳入來(lái)的method,即我們這里的printThis方法的this的指向,指向到了傳進(jìn)來(lái)的vm,即我們的vue實(shí)例對(duì)象。
而這,也即是為什么我們?cè)趍ethods里面的方法可以通過(guò)this直接訪問(wèn)到Vue實(shí)例對(duì)象的原因了。
到此這篇關(guān)于Vue中methods的this指向問(wèn)題淺析的文章就介紹到這了,更多相關(guān)Vue methods內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue.js實(shí)現(xiàn)一個(gè)SPA登錄頁(yè)面的過(guò)程【推薦】
本篇文章主要介紹了Vue.js寫(xiě)一個(gè)SPA登錄頁(yè)面過(guò)程的相關(guān)知識(shí),具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04Vue封裝localStorage設(shè)置過(guò)期時(shí)間的示例詳解
這篇文章主要介紹了Vue封裝localStorage設(shè)置過(guò)期時(shí)間的相關(guān)資料,在這個(gè)示例中,我們?cè)贛yComponent.vue組件的setup函數(shù)中導(dǎo)入了setItemWithExpiry和getItemWithExpiry函數(shù),并在函數(shù)內(nèi)部使用它們來(lái)設(shè)置和獲取帶有過(guò)期時(shí)間的localStorage數(shù)據(jù),需要的朋友可以參考下2024-06-06關(guān)于vue3+echart5?遇到的坑?Cannot?read?properties?of?undefine
這篇文章主要介紹了vue3+echart5?遇到的坑?Cannot?read?properties?of?undefined?(reading?'type'),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04vue-router 實(shí)現(xiàn)導(dǎo)航守衛(wèi)(路由衛(wèi)士)的實(shí)例代碼
這篇文章主要介紹了vue-router 實(shí)現(xiàn)導(dǎo)航守衛(wèi)(路由衛(wèi)士)的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09Vue實(shí)現(xiàn)天氣預(yù)報(bào)小應(yīng)用
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)天氣預(yù)報(bào)小應(yīng)用,查詢(xún)一些城市的天氣情況,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08vue中watch監(jiān)聽(tīng)對(duì)象中某個(gè)屬性的方法
watch 的用法有個(gè)特點(diǎn),就是當(dāng)值第一次綁定的時(shí)候,不會(huì)執(zhí)行監(jiān)聽(tīng)函數(shù),只有值發(fā)生改變才會(huì)執(zhí)行,如果我們需要在最初綁定值得時(shí)候也執(zhí)行函數(shù),就需要用到 immediate 屬性,這篇文章主要介紹了vue中watch監(jiān)聽(tīng)對(duì)象中某個(gè)屬性的方法,需要的朋友可以參考下2023-04-04vue實(shí)現(xiàn)滾動(dòng)條下滑時(shí)隱藏導(dǎo)航欄,上滑時(shí)顯示導(dǎo)航欄功能
這篇文章主要介紹了vue實(shí)現(xiàn)滾動(dòng)條下滑時(shí)隱藏導(dǎo)航欄,上滑時(shí)顯示導(dǎo)航欄,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-07-07Vue中 axios delete請(qǐng)求參數(shù)操作
這篇文章主要介紹了Vue中 axios delete請(qǐng)求參數(shù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所 幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08