66

this在vue和小程序中的使用

 5 years ago
source link: https://www.qdtalk.com/2019/01/27/this在vue和小程序中的使用/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

javascript作用域系列文章第五篇,感兴趣的同学请保持关注

之前用了两篇文章介绍了this的基本使用方法,

今天我们看看this在vue中的使用情况

vue中的this使用

目录

匿名函数下的this

方便本地demo,没有使用webpack

引入两个文件,vue和axios

axios返回一个promise对象,我们通过axios进行ajax请求

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<body>
    <div id="app">
        {{ message }}
    </div>
</body>

看下js部分

var message = '我是全局message!';
var app = new Vue({
  el: '#app',
  data() {
    return {
      message: '我是vue下的message!'
    }
  },
  created() {
    this.getData()
  },
  methods: {
    getData() {
      axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1')
        .then(function () {
          console.log(this.message);//=>我是全局message!
        })
    }
  }
})

不必关心axios请求的接口返回的数据

那么在axios下,输出的是=>我是全局message!,为什么呢?我们是想输出=>”我是vue下的message!”

在这里有那么一些人就蒙了,为什么axios下会这样呢?

axios有话说:

VJNnQzI.jpg!web

出现这种情况,不是axios的锅,

不信你往下看

//其他代码省略
  getData() {
    setTimeout(function () {
      console.log(this.message);//=>我是全局message!
    }, 1000);
  }
}

我们将getData方法下的axios请求换掉,用一个定时器替代,其他部分保持不变

输出依然是=>我是全局message!

为什么?

因为

匿名函数下this指向window

至于原因, 这里解释的很清楚https://www.zhihu.com/question/21958425

你只需要记住一点,默认情况下,匿名函数this指向window

如何处理匿名函数下this指向的问题呢?

通过bind来处理

结合之前所学,我们可以同bind来进行处理

//部分代码省略
created() {
    this.getData()
},
    methods: {
        getData() {
            setTimeout(function () {
                console.log(this.message);//=>我是vue下的message!
            }.bind(this), 1000);
        }
    }

通过bind可以改变this的指向,这是一中解决方式

还有一种比较常用

this赋值暂存

created() {
  this.getData()
},
methods: {
  getData() {
    const that = this
    setTimeout(function () {
      console.log(that.message);//=>我是vue下的message!
    }, 1000);
  }
}

在匿名函数之前,我们先将this赋值给that,在匿名函数中使用that来替代原来的this,同样可以实现我们所希望的效果

如果你的项目支持ES6标准,那么

箭头函数是你最佳选择

getData() {
  axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1')
    .then(() => {
      console.log(this.message);
    })
}

我们在之前的文章中总结过一个结论

this的指向是在函数执行的时候定义的,而不是在函数创建时定义的,this指向的是最后调用它的对象

我们接下来本篇文章的另一个知识点

箭头函数中的this

看一个栗子

var heroName = '黄蓉';
var heroObj = {
  heroName: '郭靖',
  callName: function () {
    console.log(this.heroName)//=>郭靖
  }
}
heroObj.callName();

this指向最后调用它的对象,所以输出=>郭靖

再看下箭头函数的栗子

var heroName = '黄蓉';
var heroObj = {
  heroName: '郭靖',
  callName: () => {
    console.log(this.heroName)//=>黄蓉
  }
}
heroObj.callName();

对这个输出结果感到意外吗?

不管懵没懵,我们再看一个栗子

var heroName = '黄蓉';
function getHeroName() {
  this.heroName = '郭靖'
  const foo = () => {
    console.log(this.heroName)//=>郭靖
  }
  foo();
}
getHeroName();

放在一起做一下比较:

普通函数:this的指向是在函数 执行 的时候绑定的,而不是在函数 创建 时绑定的

箭头函数:this的指向是在函数 创建 的时候绑定的,而不是在函数 执行 时绑定的。

不管在什么情况下,箭头函数的this跟外层function的this一致,外层function的this指向谁,箭头函数的this就指向谁,如果外层不是function则指向window。

ES6中定义的时候绑定的this是继承的父执行上下文里面的this

小程序中的this

如果项目中的小程序也支持ES6标准,无疑,使用箭头函数是一个不错的选择

//省略。。。
  getLocation() {
    wx.chooseLocation({
      success: res => {
        if (res.address && res.name) {
          this.setData({
            shopAddress: `${res.address}(${res.name})`
          })
        } else if (res.address) {
          this.setData({
            shopAddress: `${res.address}`
          })
        }
      }
    })
  }

很多场景就不需要缓存中转this

var that = this//使用箭头函数替代此方案

合理的使用this会使我们事半功倍


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK