如何在 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 变量。