如何在Vue组件中保存对“this”的引用?

时间:2018-03-21 22:14:46

标签: javascript vue.js vuejs2 vue-component umd

我不确定我是否正确地做到了这一点。请看一下这个简单的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变量一样)。

1 个答案:

答案 0 :(得分:1)

您尝试做的主要是不必要的

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都引用了相同的属性。见下面的演示。

&#13;
&#13;
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); });
    }
  }
})
&#13;
<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>
&#13;
&#13;
&#13;

现在,在第二个解决方案中,您将使用常规(非箭头)功能。但为了确保保留this,您使用.bind(this) ,如下所示:

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

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

&#13;
&#13;
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));
    }
  }
})
&#13;
<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>
&#13;
&#13;
&#13;

因此,正如您所看到的,在Vue实例中,不需要声明此类self变量。