本文介绍了如何保存对“this"的引用在 Vue 组件中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定我这样做是否正确.请看一下这个简单的 Vue 组件 Test.vue:

<div>来自{{name}}的你好

</模板><脚本>让自己;导出默认{创建:函数(){自我=这个;},方法: {加载() {ajax().then((obj) => self.name = obj.data);}},数据() {返回 {name: '一个',}}}

如您所见,我将 this 的引用保存到一个名为 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 实例相关的问题中,是:

但是现在不要相信我,让我们来看一个例子.获取您的源代码:

 方法:{加载() {ajax().then((obj) => self.name = obj.data);}},

作为 .then() 的参数,您必须传递一个函数.此类函数中this的值将取决于如何传递它.

在第一种情况下(上述两个解决方案中的第一个解决方案),应该使用箭头函数(您这样做了).因此,在代码的那个点, self 是不必要的,因为箭头函数中的 this 仍然会指向 Vue 实例.

 方法:{加载() {console.log(this.name);ajax().then((obj) => this.name = obj.data);}},

在上面的例子中,this.name 都引用了 same 属性.请参阅下面的演示.

const ajax = () =>{返回获取('https://api.myjson.com/bins/18gqg9').then((响应) => response.json())};新的 Vue({el: '#app',数据: {名称:'爱丽丝'},方法: {哟(){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"><;/脚本><div id="应用程序"><p>姓名:{{姓名}}</p><button @click="yoo">AJAX!</button><p>单击上面的按钮并检查控制台.打印的名称变量是相同的.</p>

现在,在第二种解决方案中,您将使用常规(非箭头)函数.但是要确保保留 this,您可以使用 .bind(this),如下所示:

 方法:{加载() {console.log(this.name);ajax().then(function (obj) { this.name = obj.data }.bind(this));}},

与前一种情况类似,在两个地方 this.name 指的是同一个属性.请参阅下面的演示.

const ajax = () =>{返回获取('https://api.myjson.com/bins/18gqg9').then((响应) => response.json())};新的 Vue({el: '#app',数据: {名称:'爱丽丝'},方法: {哟(){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"><;/脚本><div id="应用程序"><p>姓名:{{姓名}}</p><button @click="yoo">AJAX!</button><p>单击上面的按钮并检查控制台.打印的名称变量是相同的.</p>

所以,如你所见,在 Vue 实例中,这样的 self 变量的声明是不必要的.

I'm not sure if I'm doing this properly. Please have a look at this simple Vue component 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>

As you can see I'm saving the reference of this into a variable called self because the value of this changes in lambda functions, e.g. ajax().then((obj) => self.name = obj.data);

My problem is when this another instance of component is created, it overwrites the value of self in previous instance. So for example if I have two <test id="1"></test> and <test id="2"></test> then the later component overwrites the self variable of the first one (same happens in v-for too).

So my question is how can I create the self variable which saves to the value of this for every instance and doesn't get overwritten?

Edit: Yes I know I can do self = this inside every function but this is just a bare-bones example with 1 method. In my actual component I have 20+ functions I don't want to do self = this in every function. Which is why I can to create a variable that I can just assign once during the create call and use it everywhere (like we used to use that variable).

解决方案

What you are attempting to do is mostly unnecessary.

It is true that the value of this can be confusing at times in JavaScript. It is also true, though, that this is a well known problem, with well known solutions.

And these solutions, at least in problems related to the Vue instance, are:

But don't trust me just yet, let's go through an example. Take your source code:

    methods: {
        load() {
            ajax().then((obj) => self.name = obj.data);
        }
    },

As argument for the .then() you must pass a function. The value of this inside such function will depend on how you pass it.

In the first case (first solution from the two solutions above), one should use arrow functions (which you did). So, in that point of your code, the self is unnecessary because the this inside the arrow function still will point to the Vue instance.

    methods: {
        load() {
            console.log(this.name);
            ajax().then((obj) => this.name = obj.data);
        }
    },

In the example above, both this.name refer to the same property. See demo below.

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>

Now, in the second solution, you would use a regular (non-arrow) function. But to make sure the this is kept, you would use .bind(this), as follows:

    methods: {
        load() {
            console.log(this.name);
            ajax().then(function (obj) { this.name = obj.data }.bind(this));
        }
    },

Similar to the previous case, in both places this.name refers to the same property. See demo below.

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>

So, as you can see, within the Vue instance, the declaration of such self variable is unnecessary.

这篇关于如何保存对“this"的引用在 Vue 组件中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 02:07