溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue自定義指令中無(wú)法獲取this如何解決

發(fā)布時(shí)間:2022-08-15 16:26:23 來(lái)源:億速云 閱讀:166 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹了Vue自定義指令中無(wú)法獲取this如何解決的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Vue自定義指令中無(wú)法獲取this如何解決文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。

自定義指令中無(wú)法獲取this

問(wèn)題

最近在使用自定義指令時(shí)遇到一個(gè)問(wèn)題,我想在指令里通過(guò)this直接去訪問(wèn)vue實(shí)例數(shù)據(jù),但是顯示未定義,經(jīng)大佬提醒,里面的this很可能不是指向vue實(shí)例

Vue自定義指令中無(wú)法獲取this如何解決

Vue自定義指令中無(wú)法獲取this如何解決

解決方法

在函數(shù)里增加第三個(gè)參數(shù)vnode,vnode.context就是指向當(dāng)前的vue實(shí)例

Vue自定義指令中無(wú)法獲取this如何解決

總結(jié)

指令里的this不是指向vue實(shí)例,可以使用vnode.context獲取this

自定義指令可傳入以下參數(shù)

  • el:指令所綁定的元素,可以用來(lái)直接操作 DOM。

  • binding:一個(gè)對(duì)象,包含以下 property:

  • name:指令名,不包括 v- 前綴。

  • value:指令的綁定值,例如:v-my-directive=“1 + 1” 中,綁定值為 2。

  • oldValue:指令綁定的前一個(gè)值,僅在 update 和 componentUpdated 鉤子中可用。無(wú)論值是否改變都可用。

  • expression:字符串形式的指令表達(dá)式。例如 v-my-directive=“1 + 1” 中,表達(dá)式為 “1 + 1”。

  • arg:傳給指令的參數(shù),可選。例如 v-my-directive:foo 中,參數(shù)為 “foo”。

  • modifiers:一個(gè)包含修飾符的對(duì)象。例如:v-my-directive.foo.bar 中,修飾符對(duì)象為 { foo: true, bar: true }。

  • vnode:Vue 編譯生成的虛擬節(jié)點(diǎn)。

  • oldVnode:上一個(gè)虛擬節(jié)點(diǎn),僅在 update 和 componentUpdated 鉤子中可用。

Vue使用this的這幾個(gè)坑你都知道嗎

最近寫vue項(xiàng)目遇到很多this指向的問(wèn)題,今天來(lái)寫一下我總結(jié)的this指向

看了很多文章、博客,對(duì)于正常函數(shù),誰(shuí)調(diào)用的它,this就指向誰(shuí),而箭頭函數(shù)沒(méi)有this,它的this指向一般就是上下文中,與誰(shuí)調(diào)用它沒(méi)關(guān)系。

但是在Vue實(shí)例中,methods、生命周期函數(shù)中如果用的是正常函數(shù),那么它的this就指向Vue實(shí)例,也就是vm(本文中的vm是指const vm = new Vue({···})中的vm);如果是箭頭函數(shù),在非嚴(yán)格模式下this就指向window對(duì)象,嚴(yán)格模式下是undefind。

這里我分別來(lái)說(shuō)一下普通函數(shù)中的this和Vue中的this

一、普通函數(shù)

普通函數(shù)的this是由動(dòng)態(tài)作用域決定,它總指向于它的直接調(diào)用者。具體可以分為以下四項(xiàng):this總是指向它的直接調(diào)用者, 例如 obj.func() ,那么func()里的this指的是obj。在默認(rèn)情況(非嚴(yán)格模式,未使用 'use strict'),如果函數(shù)沒(méi)有直接調(diào)用者,this為window;在嚴(yán)格模式下,如果函數(shù)沒(méi)有直接調(diào)者,this為undefined使用call,apply,bind綁定的,this指的是綁定的對(duì)象

簡(jiǎn)單總結(jié): 

(1)全局函數(shù)中的this指向window

(2)對(duì)象中的方法(函數(shù))中的this,指向?qū)ο?,理解:obj.m=function(){},m和fn等價(jià),因此調(diào)用m也相當(dāng)于調(diào)用fn,原理同3)

(3)構(gòu)造函數(shù)中的this指向調(diào)用該構(gòu)造函數(shù)的實(shí)例對(duì)象

(4)特殊this指向: 箭頭函數(shù)沒(méi)有綁定this,this繼承自外圍作用域,理解:查看上一層級(jí)的函數(shù)的this的指向,繼承它??!

(5)綁定this指向:apply,call,bind綁定的對(duì)象

接下來(lái)用實(shí)例來(lái)介紹下各種this問(wèn)題

1.全局環(huán)境下,this 始終指向全局對(duì)象(window), 無(wú)論是否嚴(yán)格模式

    console.log(this.document === document); // true
    // 在瀏覽器中,全局對(duì)象為 window 對(duì)象:
    console.log(this === window); // true
    this.a = 3;
    console.log(window.a); // 3

2.函數(shù)直接調(diào)用,普通函數(shù)內(nèi)部的this分兩種情況,嚴(yán)格模式和非嚴(yán)格模式

    //嚴(yán)格模式下, this為undefined
    function f2(){
      "use strict"; // 這里是嚴(yán)格模式
      return this;
    }
    f2() === undefined; // true
    //而非嚴(yán)格模式下,this 默認(rèn)指向全局對(duì)象window
    function f1(){
      return this;
    }
    f1() === window; // true

     3.對(duì)象中的this,對(duì)象內(nèi)部方法的this指向調(diào)用這些方法的對(duì)象

    //函數(shù)的定義位置不影響其this指向,this指向只和調(diào)用函數(shù)的對(duì)象有關(guān)。
    //多層嵌套的對(duì)象,內(nèi)部方法的this指向離被調(diào)用函數(shù)最近的對(duì)象(window也是對(duì)象,其內(nèi)部對(duì)象調(diào)
    //用方法的this指向內(nèi)部對(duì)象, 而非window)。
    //例一:
    var obj = {
      prop: 37,
      f: function() {
        return this.prop;
      }
    };
    console.log(obj.f());  //37
    var a = obj.f;
    console.log(a());  //undefined
    
    var obj = {prop: 37};
    
    function independent() {
      return this.prop;
    }
    
    obj.f = independent;
    
    console.log(obj.f()); //37
    
    //例二:
    obj.b = {
      num: independent,
      prop: 42
    };
    console.log(obj.b.num()); //42

4.原型鏈中this,原型鏈中的方法的this仍然指向調(diào)用它的對(duì)象 

    var obj = {
      f : function(){ 
        return this.a + this.b; 
      }
    };
    var p = Object.create(obj);
    p.a = 1;
    p.b = 4;
    
    console.log(p.f()); // 5
//在p中沒(méi)有屬性f,當(dāng)執(zhí)行p.f()時(shí),會(huì)查找p的原型鏈,找到 f 函數(shù)并執(zhí)行,但這與函數(shù)內(nèi)部this指向?qū)ο?nbsp;//p 沒(méi)有任何關(guān)系,只需記住誰(shuí)調(diào)用指向誰(shuí)。
 
//以上對(duì)于函數(shù)作為getter & setter 調(diào)用時(shí)同樣適用。

5.構(gòu)造函數(shù)中this,構(gòu)造函數(shù)中的this與被創(chuàng)建的新對(duì)象綁定 

注意:當(dāng)構(gòu)造器返回的默認(rèn)值是一個(gè)this引用的對(duì)象時(shí),可以手動(dòng)設(shè)置返回其他的對(duì)象,如果返回值不是一個(gè)對(duì)象,返回this。

6.call & apply

當(dāng)函數(shù)通過(guò)Function對(duì)象的原型中繼承的方法 call() 和 apply() 方法調(diào)用時(shí), 其函數(shù)內(nèi)部的this值可綁定到 call() & apply() 方法指定的第一個(gè)對(duì)象上, 如果第一個(gè)參數(shù)不是對(duì)象,JavaScript內(nèi)部會(huì)嘗試將其轉(zhuǎn)換成對(duì)象然后指向它。

7.bind 方法

bind方法在ES5引入, 在Function的原型鏈上, Function.prototype.bind。通過(guò)bind方法綁定后, 函數(shù)將被永遠(yuǎn)綁定在其第一個(gè)參數(shù)對(duì)象上, 而無(wú)論其在什么情況下被調(diào)用。

8.DOM事件處理函數(shù),當(dāng)函數(shù)被當(dāng)做監(jiān)聽(tīng)事件處理函數(shù)時(shí), 其 this 指向觸發(fā)該事件的元素 (針對(duì)于addEventListener事件)

  // 被調(diào)用時(shí),將關(guān)聯(lián)的元素變成藍(lán)色
    function bluify(e){
      console.log(this);//在控制臺(tái)打印出所點(diǎn)擊元素
      e.stopPropagation();//阻止時(shí)間冒泡
      e.preventDefault();//阻止元素的默認(rèn)事件    
      this.style.backgroundColor = '#A5D9F3';
    }
    var elements = document.getElementsByTagName('*');// 獲取文檔中的所有元素的列表
    // 將bluify作為元素的點(diǎn)擊監(jiān)聽(tīng)函數(shù),當(dāng)元素被點(diǎn)擊時(shí),就會(huì)變成藍(lán)色
    for(var i=0 ; i<elements.length ; i++){
      elements[i].addEventListener('click', bluify, false);
    }

9.內(nèi)聯(lián)事件,內(nèi)聯(lián)事件中的this指向分兩種情況:

  • 當(dāng)代碼被內(nèi)聯(lián)處理函數(shù)調(diào)用時(shí),它的this指向監(jiān)聽(tīng)器所在的DOM元素

  • 當(dāng)代碼被包括在函數(shù)內(nèi)部執(zhí)行時(shí),其this指向等同于函數(shù)直接調(diào)用的情況,即在非嚴(yán)格模式指向全局對(duì)象window, 在嚴(yán)格模式指向undefined。

10.setTimeout & setInterval,對(duì)于延時(shí)函數(shù)內(nèi)部的回調(diào)函數(shù)的this指向全局對(duì)象window(當(dāng)然我們可以通過(guò)bind方法改變其內(nèi)部函數(shù)的this指向) 

    //默認(rèn)情況下
    function Person() {  
        this.age = 0;  
        setTimeout(function() {
            console.log(this);
        }, 3000);
    }
    //通過(guò)bind綁定
    function Person() {  
        this.age = 0;  
        setTimeout((function() {
            console.log(this);
        }).bind(this), 3000);
    }
    var p = new Person();//3秒后返回構(gòu)造函數(shù)新生成的對(duì)象 Person{...}

11.箭頭函數(shù)中的 this,由于箭頭函數(shù)不綁定this, 它會(huì)捕獲其所在(即定義的位置)上下文的this值, 作為自己的this值 

    // call() / apply() / bind() 方法對(duì)于箭頭函數(shù)來(lái)說(shuō)只是傳入?yún)?shù),對(duì)它的 this 毫無(wú)影響。
    //考慮到 this 是詞法層面上的,嚴(yán)格模式中與 this 相關(guān)的規(guī)則都將被忽略。(可以忽略是否在嚴(yán)格
    //模式下的影響)
    //因?yàn)榧^函數(shù)可以捕獲其所在上下文的this值 所以:
    function Person() {  
        this.age = 0;  
        setInterval(() => {
            this.age++;// 回調(diào)里面的 `this` 變量就指向了期望的那個(gè)對(duì)象了
        }, 3000);
    }
    var p = new Person();
    //以上代碼可以得到我們所以希望的值,下圖可以看到,在setTimeout中的this指向了構(gòu)造函數(shù)新生成
    //的對(duì)象,而普通函數(shù)指向了全局window對(duì)象

二、Vue中的this

1.Vue methods

來(lái)看看官方文檔給出的解釋:

methods 將被混入到 Vue 實(shí)例中??梢灾苯油ㄟ^(guò) 實(shí)例vm 訪問(wèn)這些方法,或者在指令表達(dá)式中使用。方法中的 this自動(dòng)綁定為 Vue 實(shí)例(vm)。

注意,不應(yīng)該使用箭頭函數(shù)來(lái)定義 method 函數(shù) (例如 plus: () => this.a++)。理由是箭頭函數(shù)綁定了父級(jí)作用域的上下文,所以 this 將不會(huì)按照期望指向 Vue 實(shí)例,this.a 將是 undefined。

長(zhǎng)話短說(shuō),官方的意思是:在Vue實(shí)例中,methods中如果用的是正常函數(shù),那么它的this就指向Vue實(shí)例;如果是箭頭函數(shù),this就指向window對(duì)象;

總結(jié):

Vue methods 中不應(yīng)該箭頭函數(shù)定義methods函數(shù),因?yàn)榧^函數(shù)綁定了父級(jí)作用域上下文,所以 this 打印出的結(jié)果是Window 對(duì)象;不使用箭頭函數(shù)的情況下,this 實(shí)際上是指向了一個(gè) Proxy 對(duì)象。

原因是vue 內(nèi)部實(shí)際上對(duì)methods屬性中的方法進(jìn)行了遍歷,將對(duì)應(yīng)的方法通過(guò)bind綁定了this,使得this指向?qū)嵗齰m

2.Vue中生命周期鉤子和自定義方法中的this指向當(dāng)前的 Vue 實(shí)例

所有的生命周期鉤子自動(dòng)綁定 this 上下文到實(shí)例中,因此你可以訪問(wèn)數(shù)據(jù),對(duì) property 和方法進(jìn)行運(yùn)算。這意味著你不能使用箭頭函數(shù)來(lái)定義一個(gè)生命周期方法 (例如 created: () => this.checkTodos())。這是因?yàn)榧^函數(shù)綁定了父上下文,因此 this 與你期待的 Vue 實(shí)例不同,this.checkTodos 的行為未定義。

3. Vue 中回調(diào)函數(shù)中的 this:

  • 若回調(diào)函數(shù)為匿名函數(shù),非嚴(yán)格模式下指向 window,嚴(yán)格模式下為 undefined。

  • 若回調(diào)函數(shù)為自定義方法,則 this 指向 Vue 實(shí)例。

  • 若回調(diào)函數(shù)為 箭頭函數(shù),則 this 指向 Vue 實(shí)例。

4. Vue 中 addEventListener 中的 this

通常,事件監(jiān)聽(tīng)函數(shù)中的 this 都指向綁定事件的那個(gè)元素, 但是在 Vue 中,監(jiān)聽(tīng)函數(shù)中的 this 也指向 Vue 實(shí)例

5.在data里定義Object類型的變量時(shí)的this

在data里定義Object類型的變量時(shí),會(huì)發(fā)現(xiàn)Object中訪問(wèn)不到vue的this屬性,例如:

export default {
  data(){
    return {
      a: "123",
      b: {
        c: this.a
      }
    };
  },
  created() {
    console.log("b: ", this.b.c); // undefined
  }
}

想在b中訪問(wèn)this.a的數(shù)據(jù),直接訪問(wèn)會(huì)返回undefined,因?yàn)檫@時(shí)c中的this指向的是b。這種情況可以用到Object的get屬性進(jìn)行屬性定義,例如:

export default {
  data(){
    return {
      a: "123",
      b: {
        _target: () => this,
        get target() {
          return this._target();
        },
 
        get c() {
          return this.target.a;
        },
      },
    };
  },
  created() {
    console.log("b: ", this.b.c); // 123
  }
}

此處將this映射到了Object變量?jī)?nèi)部,然后通過(guò)get的形式定義屬性并獲取,這樣就解決問(wèn)題啦。 

關(guān)于“Vue自定義指令中無(wú)法獲取this如何解決”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Vue自定義指令中無(wú)法獲取this如何解決”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI