如何在 Vue 组件中保存对 "this" 的引用?
How to save reference to "this" in Vue component?
我不确定我这样做是否正确。请看看这个简单的 Vue 组件 Test.vue
:
<template>
<div>
Hi from {{name}}
</div>
</template>
<script>
let self;
export default {
created: function () {
self = this;
},
methods: {
load() {
ajax().then((obj) => self.name = obj.data);
}
},
data() {
return {
name: 'one',
}
}
}
</script>
如您所见,我将其引用保存到一个名为 self
的变量中,因为 this
的 值在 lambda 函数中发生了变化 ,例如ajax().then((obj) => self.name = obj.data);
我的问题是,当创建另一个组件实例时,它会覆盖前一个实例中 self
的值。因此,例如,如果我有两个 <test id="1"></test>
和 <test id="2"></test>
,那么后面的组件会覆盖第一个组件的 self
变量(同样发生在 v-for
中)。
所以我的问题是如何创建 self
变量,它为每个实例保存到 this
的值并且不会被覆盖?
编辑: 是的,我知道我可以在每个函数中执行 self = this
,但这只是一个只有 1 个方法的简单示例。在我的实际组件中,我有 20 多个函数,我不想在每个函数中执行 self = this
。这就是为什么我可以创建一个变量,我可以在 create
调用期间分配一次并在任何地方使用它(就像我们过去使用 that
变量一样)。
您尝试做的大部分是不必要的。
确实 this
的值在 JavaScript 中有时会令人困惑。不过,这也是一个众所周知的问题,具有众所周知的解决方案。
这些解决方案,至少在与 Vue 实例相关的问题中,是:
但不要相信我,让我们来看一个例子。拿你的源代码:
methods: {
load() {
ajax().then((obj) => self.name = obj.data);
}
},
作为 .then()
的参数,您必须传递一个函数。此类函数 中 this
的值将取决于 如何 你传递它 .
在第一种情况下(上述两个解决方案中的第一个解决方案),应该使用箭头函数(你这样做了)。因此,在您的代码中,self
是不必要的,因为箭头函数内的 this
仍将指向 Vue 实例。
methods: {
load() {
console.log(this.name);
ajax().then((obj) => this.name = obj.data);
}
},
在上面的示例中,this.name
都指的是 相同的 属性。请参阅下面的演示。
const ajax = () => {
return fetch('https://api.myjson.com/bins/18gqg9')
.then((response) => response.json())
};
new Vue({
el: '#app',
data: {
name: 'Alice'
},
methods: {
yoo() {
console.log('outside:', this.name);
ajax().then((obj) => { this.name = obj.name; console.log('inside arrow, after change:', this.name); });
}
}
})
<script src="https://unpkg.com/vue@latest/dist/vue.min.js"></script>
<div id="app">
<p>
name: {{ name }}
</p>
<button @click="yoo">AJAX!</button>
<p>Click the button above and check the console. The printed name variable is the same.</p>
</div>
现在,在第二种解决方案中,您将使用 常规 (non-arrow) 函数。但是要确保保留 this
,您可以 使用 .bind(this)
,如下所示:
methods: {
load() {
console.log(this.name);
ajax().then(function (obj) { this.name = obj.data }.bind(this));
}
},
和前面的情况类似,在两个地方this.name
指的是同一个属性。请参阅下面的演示。
const ajax = () => {
return fetch('https://api.myjson.com/bins/18gqg9')
.then((response) => response.json())
};
new Vue({
el: '#app',
data: {
name: 'Alice'
},
methods: {
yoo() {
console.log('outside:', this.name);
ajax().then(function(obj) { this.name = obj.name; console.log('inside arrow, after change:', this.name); }.bind(this));
}
}
})
<script src="https://unpkg.com/vue@latest/dist/vue.min.js"></script>
<div id="app">
<p>
name: {{ name }}
</p>
<button @click="yoo">AJAX!</button>
<p>Click the button above and check the console. The printed name variable is the same.</p>
</div>
因此,如您所见,在 Vue 实例中,不需要声明这样的 self
变量。
我不确定我这样做是否正确。请看看这个简单的 Vue 组件 Test.vue
:
<template>
<div>
Hi from {{name}}
</div>
</template>
<script>
let self;
export default {
created: function () {
self = this;
},
methods: {
load() {
ajax().then((obj) => self.name = obj.data);
}
},
data() {
return {
name: 'one',
}
}
}
</script>
如您所见,我将其引用保存到一个名为 self
的变量中,因为 this
的 值在 lambda 函数中发生了变化 ,例如ajax().then((obj) => self.name = obj.data);
我的问题是,当创建另一个组件实例时,它会覆盖前一个实例中 self
的值。因此,例如,如果我有两个 <test id="1"></test>
和 <test id="2"></test>
,那么后面的组件会覆盖第一个组件的 self
变量(同样发生在 v-for
中)。
所以我的问题是如何创建 self
变量,它为每个实例保存到 this
的值并且不会被覆盖?
编辑: 是的,我知道我可以在每个函数中执行 self = this
,但这只是一个只有 1 个方法的简单示例。在我的实际组件中,我有 20 多个函数,我不想在每个函数中执行 self = this
。这就是为什么我可以创建一个变量,我可以在 create
调用期间分配一次并在任何地方使用它(就像我们过去使用 that
变量一样)。
您尝试做的大部分是不必要的。
确实 this
的值在 JavaScript 中有时会令人困惑。不过,这也是一个众所周知的问题,具有众所周知的解决方案。
这些解决方案,至少在与 Vue 实例相关的问题中,是:
但不要相信我,让我们来看一个例子。拿你的源代码:
methods: {
load() {
ajax().then((obj) => self.name = obj.data);
}
},
作为 .then()
的参数,您必须传递一个函数。此类函数 中 this
的值将取决于 如何 你传递它 .
在第一种情况下(上述两个解决方案中的第一个解决方案),应该使用箭头函数(你这样做了)。因此,在您的代码中,self
是不必要的,因为箭头函数内的 this
仍将指向 Vue 实例。
methods: {
load() {
console.log(this.name);
ajax().then((obj) => this.name = obj.data);
}
},
在上面的示例中,this.name
都指的是 相同的 属性。请参阅下面的演示。
const ajax = () => {
return fetch('https://api.myjson.com/bins/18gqg9')
.then((response) => response.json())
};
new Vue({
el: '#app',
data: {
name: 'Alice'
},
methods: {
yoo() {
console.log('outside:', this.name);
ajax().then((obj) => { this.name = obj.name; console.log('inside arrow, after change:', this.name); });
}
}
})
<script src="https://unpkg.com/vue@latest/dist/vue.min.js"></script>
<div id="app">
<p>
name: {{ name }}
</p>
<button @click="yoo">AJAX!</button>
<p>Click the button above and check the console. The printed name variable is the same.</p>
</div>
现在,在第二种解决方案中,您将使用 常规 (non-arrow) 函数。但是要确保保留 this
,您可以 使用 .bind(this)
,如下所示:
methods: {
load() {
console.log(this.name);
ajax().then(function (obj) { this.name = obj.data }.bind(this));
}
},
和前面的情况类似,在两个地方this.name
指的是同一个属性。请参阅下面的演示。
const ajax = () => {
return fetch('https://api.myjson.com/bins/18gqg9')
.then((response) => response.json())
};
new Vue({
el: '#app',
data: {
name: 'Alice'
},
methods: {
yoo() {
console.log('outside:', this.name);
ajax().then(function(obj) { this.name = obj.name; console.log('inside arrow, after change:', this.name); }.bind(this));
}
}
})
<script src="https://unpkg.com/vue@latest/dist/vue.min.js"></script>
<div id="app">
<p>
name: {{ name }}
</p>
<button @click="yoo">AJAX!</button>
<p>Click the button above and check the console. The printed name variable is the same.</p>
</div>
因此,如您所见,在 Vue 实例中,不需要声明这样的 self
变量。