欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue中methods的this指向問(wèn)題淺析

 更新時(shí)間:2022年10月27日 14:36:13   作者:天地會(huì)珠海分舵  
相信我們寫(xiě)Vue代碼時(shí)肯定都會(huì)在methods中用過(guò)this這個(gè)關(guān)鍵字,甚至還打印過(guò)this查看其內(nèi)容。最終發(fā)現(xiàn)該實(shí)例對(duì)象竟然是我們的Vue實(shí)例對(duì)象

如果是組件的話(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)文章

最新評(píng)論