Vue实例里this的使用

时间:2021-12-16 16:08:49

要理解Vue实例里this的使用,首先要理解this在JavaScript里的用法,可以参考理解JavaScript普通函数以及箭头函数里使用的this

这是vue文档里的原话:

All lifecycle hooks are called with their 'this' context pointing to the Vue instance invoking it.

意思是:在Vue所有的生命周期钩子方法(如created,mounted, updated以及destroyed)里使用this,this指向调用它的Vue实例。

示例分析

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
    <script src="https://unpkg.com/vue@2.5.9/dist/vue.js"></script>
</head>
<div  style="width: 100%;height: auto;font-size:20px;">
    <p ></p>
    <p ></p>
</div>
<script type="text/javascript">
    var message = "Hello!";
    var app = new Vue({
        el:"#app",
        data:{
            message: "你好!"
        },
        created: function() {
          this.showMessage1();    //this 1
          this.showMessage2();   //this 2
        },
        methods:{
            showMessage1:function(){
                setTimeout(function() {
                   document.getElementById("id1").innerText = this.message;  //this 3
                }, 10)
            },
            showMessage2:function() {
                setTimeout(() => {
                   document.getElementById("id2").innerText = this.message;  //this 4
                }, 10)
            }
        }
    });
</script>
</html>

示例定义了两个message。一个是全局变量,即window.message,它的值为英文“Hello!”。另外一个是vue实例的数据message,它的值为中文的“你好!”。

运行示例,在浏览器得到:
Vue实例里this的使用
第一个输出英文"Hello!”,第二个输出中文“你好!”。这说明了showMessage1()里的this指的是window,而showMessage2()里的this指的是vue实例。

created

created: function() {
  this.showMessage1();    //this 1
  this.showMessage2();   //this 2
}

created函数为vue实例的钩子方法,它里面使用的this指的是vue实例。

showMessage1()

showMessage1:function(){
    setTimeout(function() {
       document.getElementById("id1").innerText = this.message;  //this 3
    }, 10)
}

对于普通函数(包括匿名函数),this指的是直接的调用者,在非严格模式下,如果没有直接调用者,this指的是window。showMessage1()里setTimeout使用了匿名函数,this指向window。

showMessage2()

showMessage2:function() {
    setTimeout(() => {
       document.getElementById("id2").innerText = this.message;  //this 4
    }, 10)
}

箭头函数是没有自己的this,在它内部使用的this是由它定义的宿主对象决定。showMessage2()里定义的箭头函数宿主对象为vue实例,所以它里面使用的this指向vue实例。

绑定vue实例到this的方法

为了避免this指向出现歧义,有两种方法绑定this。

使用bind

showMessage1()可以改为:

showMessage1:function(){
    setTimeout(function() {
       document.getElementById("id1").innerText = this.message;  //this 3
    }.bind(this), 10)
}

对setTimeout()里的匿名函数使用bind()绑定到vue实例的this。这样在匿名函数内的this也为vue实例。

把vue实例的this赋值给另一个变量再使用

showMessage1()也可以改为

showMessage1:function(){
    var self = this;
    setTimeout(function() {
       document.getElementById("id1").innerText = self.message;  //改为self
    }.bind(this), 10)
}

这里吧表示vue实例的this赋值给变量self。在使用到this的地方改用self引用。