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

Vue自定義指令中無法獲取this的問題及解決

 更新時間:2022年08月15日 12:00:04   作者:Vitaliner  
這篇文章主要介紹了Vue自定義指令中無法獲取this的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

自定義指令中無法獲取this

問題

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

在這里插入圖片描述

在這里插入圖片描述

解決方法

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

在這里插入圖片描述

總結(jié)

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

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

  • el:指令所綁定的元素,可以用來直接操作 DOM。
  • binding:一個對象,包含以下 property:
  • name:指令名,不包括 v- 前綴。
  • value:指令的綁定值,例如:v-my-directive=“1 + 1” 中,綁定值為 2。
  • oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
  • expression:字符串形式的指令表達(dá)式。例如 v-my-directive=“1 + 1” 中,表達(dá)式為 “1 + 1”。
  • arg:傳給指令的參數(shù),可選。例如 v-my-directive:foo 中,參數(shù)為 “foo”。
  • modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象為 { foo: true, bar: true }。
  • vnode:Vue 編譯生成的虛擬節(jié)點(diǎn)。
  • oldVnode:上一個虛擬節(jié)點(diǎn),僅在 update 和 componentUpdated 鉤子中可用。

Vue使用this的這幾個坑你都知道嗎

最近寫vue項目遇到很多this指向的問題,今天來寫一下我總結(jié)的this指向

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

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

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

一、普通函數(shù)

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

簡單總結(jié): 

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

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

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

(4)特殊this指向: 箭頭函數(shù)沒有綁定this,this繼承自外圍作用域,理解:查看上一層級的函數(shù)的this的指向,繼承它?。?/p>

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

接下來用實例來介紹下各種this問題

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

?? ?console.log(this.document === document); // true
?? ?// 在瀏覽器中,全局對象為 window 對象:
?? ?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)指向全局對象window
?? ?function f1(){
?? ? ?return this;
?? ?}
?? ?f1() === window; // true

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

?? ?//函數(shù)的定義位置不影響其this指向,this指向只和調(diào)用函數(shù)的對象有關(guān)。
?? ?//多層嵌套的對象,內(nèi)部方法的this指向離被調(diào)用函數(shù)最近的對象(window也是對象,其內(nèi)部對象調(diào)
? ? //用方法的this指向內(nèi)部對象, 而非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)用它的對象 

?? ?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中沒有屬性f,當(dāng)執(zhí)行p.f()時,會查找p的原型鏈,找到 f 函數(shù)并執(zhí)行,但這與函數(shù)內(nèi)部this指向?qū)ο?//p 沒有任何關(guān)系,只需記住誰調(diào)用指向誰。
?
//以上對于函數(shù)作為getter & setter 調(diào)用時同樣適用。

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

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

6.call & apply

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

7.bind 方法

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

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

? // 被調(diào)用時,將關(guān)聯(lián)的元素變成藍(lán)色
? ? function bluify(e){
? ? ? console.log(this);//在控制臺打印出所點(diǎn)擊元素
? ? ? e.stopPropagation();//阻止時間冒泡
? ? ? e.preventDefault();//阻止元素的默認(rèn)事件 ? ?
? ? ? this.style.backgroundColor = '#A5D9F3';
? ? }
? ? var elements = document.getElementsByTagName('*');// 獲取文檔中的所有元素的列表
? ? // 將bluify作為元素的點(diǎn)擊監(jiān)聽函數(shù),當(dāng)元素被點(diǎn)擊時,就會變成藍(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)用時,它的this指向監(jiān)聽器所在的DOM元素
  • 當(dāng)代碼被包括在函數(shù)內(nèi)部執(zhí)行時,其this指向等同于函數(shù)直接調(diào)用的情況,即在非嚴(yán)格模式指向全局對象window, 在嚴(yán)格模式指向undefined。

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

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

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

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

二、Vue中的this

1.Vue methods

來看看官方文檔給出的解釋:

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

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

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

總結(jié):

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

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

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

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

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

  • 若回調(diào)函數(shù)為匿名函數(shù),非嚴(yán)格模式下指向 window,嚴(yán)格模式下為 undefined。
  • 若回調(diào)函數(shù)為自定義方法,則 this 指向 Vue 實例。
  • 若回調(diào)函數(shù)為 箭頭函數(shù),則 this 指向 Vue 實例。

4. Vue 中 addEventListener 中的 this

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

5.在data里定義Object類型的變量時的this

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

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

想在b中訪問this.a的數(shù)據(jù),直接訪問會返回undefined,因為這時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變量內(nèi)部,然后通過get的形式定義屬性并獲取,這樣就解決問題啦。 

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • vue3實現(xiàn)頁面跳轉(zhuǎn)的示例代碼

    vue3實現(xiàn)頁面跳轉(zhuǎn)的示例代碼

    這篇文章給大家介紹了vue3如何實現(xiàn)頁面跳轉(zhuǎn),文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • vue+xlsx實現(xiàn)表格的導(dǎo)入導(dǎo)出功能

    vue+xlsx實現(xiàn)表格的導(dǎo)入導(dǎo)出功能

    這篇文章主要介紹了vue+xlsx實現(xiàn)表格的導(dǎo)入導(dǎo)出功能,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-11-11
  • 使用vue-cli創(chuàng)建項目并webpack打包的操作方法

    使用vue-cli創(chuàng)建項目并webpack打包的操作方法

    本文給大家分享使用vue-cli創(chuàng)建項目基于webpack模板打包的配置方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-07-07
  • Vue表單提交點(diǎn)擊事件只允許點(diǎn)擊一次的實例

    Vue表單提交點(diǎn)擊事件只允許點(diǎn)擊一次的實例

    這篇文章主要介紹了Vue表單提交點(diǎn)擊事件只允許點(diǎn)擊一次的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 講解vue-router之命名路由和命名視圖

    講解vue-router之命名路由和命名視圖

    這篇文章主要介紹了講解vue-router之命名路由和命名視圖,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • vue實現(xiàn)播放后端flask發(fā)送的mp3文件

    vue實現(xiàn)播放后端flask發(fā)送的mp3文件

    這篇文章主要為大家詳細(xì)介紹了vue如何實現(xiàn)播放后端flask發(fā)送的mp3文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • 在vue上使用cesium開發(fā)三維地圖的詳細(xì)過程

    在vue上使用cesium開發(fā)三維地圖的詳細(xì)過程

    這篇文章主要給大家介紹了關(guān)于在vue上使用cesium開發(fā)三維地圖的詳細(xì)過程,Cesium是一個強(qiáng)大的JavaScript庫,支持三維地理信息展示,并提供了豐富的地理空間數(shù)據(jù)可視化功能,需要的朋友可以參考下
    2023-12-12
  • vite結(jié)合electron構(gòu)建前端桌面應(yīng)用程序

    vite結(jié)合electron構(gòu)建前端桌面應(yīng)用程序

    本文主要介紹了vite結(jié)合electron構(gòu)建前端桌面應(yīng)用程序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 詳解Element 指令clickoutside源碼分析

    詳解Element 指令clickoutside源碼分析

    這篇文章主要介紹了詳解Element 指令clickoutside源碼分析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • VUE利用vuex模擬實現(xiàn)新聞點(diǎn)贊功能實例

    VUE利用vuex模擬實現(xiàn)新聞點(diǎn)贊功能實例

    本篇文章主要介紹了VUE利用vuex模擬實現(xiàn)新聞點(diǎn)贊功能實例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06

最新評論