Vue中关于this指向的重要原则
1.所被Vue管理的函数,最好写成普通函数。这样的this指向实例对象;2.所有不被Vue所管理的函数(定时器,ajax,回调)最好写成箭头函数,这样this依旧指向Vue或者组件的实例对象。
前言
在学习js的时候,偶尔会涉及到this的指向问题。大部分情况下,在一个函数中,谁调用这个函数,this就指向谁。
在Vue中,this的指向却显得尤为重要。本节博客将为大家解释Vue中this的指向问题,同时告诉读者,为什么this的指向在Vue中非常重要,以及我们在平时写Vue代码时需要注意的相关内容。
一,Vue底层的相关原理
1.1 MVVM模型的复习
Vue的设计收到了MVVM模型的影响,在看this指向问题前,我想带读者们复习一下MVVM模型的相关知识。
M:Model模型,对应的是data中的数据;
V:View视图,对应的是模板,也就是页面结构;
VM:视图模型,对应的是Vue实例对象。
这里用一个html文件给大家划分一下具体结构:
1.2 通过差值语法看vm的属性
所有vm中的属性,利用差值语法都可以看到。为了测试,我们先看看vm是什么。此处,我们先打印一下this,可以看到此时的this是Vue。准确来说使我们创建的Vue实例。这里面的所有属性都可以通过插值语法看到。
为了验证上面说的话,现在我利用差值语法随意看Vue实例对象中的一些东西:
1.3 为什么差值语法可以看到vm的内部属性
==因为在Vue中,this指向的是vm实例对象Vue。==所以可以利用this看到vm的所有属性。希望读者朋友们可以牢记这一点。
记住这一点在时时刻刻的应用中:我们不要轻易的改变this的指向,如若改变,this不再是vm,页面上的元素将无法正常被渲染。
这里给大家看一个例子:这段代码的需求是,在 页面中写出姓和名,让Vue帮我们合成姓名。并且在我们修改姓或者名后停顿1s后再帮我们合成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="lastName"><br>
全名:<span>{{ fullName }}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三',
fullName: ''
},
watch: {
firstName(newValue, oldValue) {
setTimeout(() => {
this.fullName = newValue + this.lastName
console.log(this)
}, 1000)
},
lastName(newValue, oldValue) {
setTimeout(() => {
this.fullName = this.firstName + newValue
console.log(this)
}, 1000)
}
}
})
</script>
</body>
</html>
上述代码是没有什么问题的。并且在定时器中,使用箭头函数,打印出来的this都是vue实例
原因:箭头函数中的this指向它的外层调用者。
现在看一个反例:我们把箭头函数改成普通函数,则会出现问题:
<body>
<div id="root">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="lastName"><br>
全名:<span>{{ fullName }}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三',
fullName: ''
},
watch: {
firstName(newValue, oldValue) {
setTimeout(() => {
this.fullName = newValue + this.lastName
console.log(this)
}, 1000)
},
// lastName(newValue, oldValue) {
// setTimeout(() => {
// this.fullName = this.firstName + newValue
// console.log(this)
// }, 1000)
// }
// 这是一个错误写法,因为它改变了this的指向。它的this是window。那么就没办法读到vue中的数据了
lastName(newValue, oldValue) {
setTimeout(function() {
this.fullName = this.firstName + newValue
console.log(this)
}, 1000)
}
}
})
</script>
没办法正常运行并且,this打印出来的是window:
==原因:普通函数中的this指向它的直接调用者。==由于定时器的this指向的是window。此时此刻,改变了this的指向,所以会报错。
二,总结部分
1.所被Vue管理的函数,最好写成普通函数。这样的this指向实例对象;
2.所有不被Vue所管理的函数(定时器,ajax,回调)最好写成箭头函数,这样this依旧指向Vue或者组件的实例对象。
更多推荐
所有评论(0)