何时使用vm。或这个。在Vue.js

时间:2017-11-07 01:06:47

标签: javascript vue.js vuejs2

我对何时在vue.js中使用“this”这个词感到有点困惑。例如,在下面的代码中,我使用“vm”而不是“this”代码不起作用。

我也看过一些使用“self”的例子,但我不是一个javascript大师,这真的很混乱。

var vm = new Vue({
        el: '#app',
        data: {
            tickets: [],
            top: 100,
            search: '',
            showAdd: false,
         },
        mounted: function () {
            this.$nextTick(function () {
                console.log('mounted');
                this.GetTickets(100);
            })
        },
        methods: {
            GetTickets: function (top) {
                axios.get('/api/Tickets', {
                    params: {
                        Top: top
                    }
                })
                    .then(function (response) {
                        vm.tickets = response.data;
                    })
                    .catch(function (error) {
                        console.log(error);
                    });
            },
            ClearTicket: function () {
                var t = {
                    "ticketSubject": '',
                    "contactName": '',
                    "createdAt": moment()
                }
                vm.ticket = t;
                vm.showAdd = !vm.showAdd;
            },
            AddTicket: function () {
                //vm.tickets.unshift(vm.ticket);
                axios.post('/api/Tickets', vm.ticket)
                    .then(function (response) {
                        console.log(response);
                        vm.GetTickets(100);
                    })
                    .catch(function (error) {
                        console.log(error);
                    });
                vm.showAdd = false;

            }
        },

    })

2 个答案:

答案 0 :(得分:22)

我通常会将此问题标记为重复,但是,我觉得这个具体问题需要更多解释,因为总体上对SELECT COALESCE(@maybe_col, null) AS norm_col FROM database;的总体困惑,以及如何在Vue中特别使用它。 / p>

通常,Vue中的内部方法或计算属性或生命周期处理程序,您将使用this来引用方法/计算/处理程序所附加的组件。 this指的是函数当前正在执行的上下文。

使用this遇到麻烦的地方是在当前函数的上下文中声明一个新函数时,就像在回写一个promise(this,{{1}时发生的那样})。请考虑以下代码:

axios.post

在上面的代码中,第一个注释可以替换为使用axios.get来获取数据属性或调用Vue(AddTicket: function () { // "this", on this line, refers to the Vue // and you can safely use "this" to get any of the // data properties of the Vue axios.post('/api/Tickets', ...) .then(function (response) { // "this" HERE, does NOT refer to the Vue!! // The reason why explained below }) } )方法的代码。然而,第二条评论是里面一个新的函数上下文,this不会引用Vue。这是因为在Javascript中使用this.tickets语法声明一个新函数时,该函数有自己的函数上下文,它与声明它的函数不同

有几种方法可以在Javascript中处理这个问题。这些天最常见的是使用闭包来捕获正确的this,或者使用箭头函数。请考虑以下代码:

function() {}

请注意,在此示例中,使用箭头函数(this)定义回调。箭头函数不会创建自己的函数上下文并使用声明它们的上下文。这也被称为具有词汇范围。

另一个最常见的解决方法是使用闭包。

AddTicket: function () {
  // As before, "this" here is the Vue
    axios.post('/api/Tickets', ...)
      .then((response) => {
        // "this" HERE is ALSO the Vue
      })
}

最后,您可以使用bind method创建一个具有特定() => {}的函数,但现在这种情况并不常见,因为箭头函数可用。

AddTicket: function () {
  const self = this // Here we save a reference to the "this" we want
    axios.post('/api/Tickets', ...)
      .then(function(response){
        // and HERE, even though the context has changed, and we can't use
        // "this", we can use the reference we declared (self) which *is*
        // pointing to the Vue
        self.tickets = response
      })
}

在几乎所有情况下,你真的应该在你的问题中做你做的事情,这是在变量this中保存对Vue的引用,并在Vue中使用该变量对象本身。这是一种不好的做法。

在任何情况下,许多帖子throughout the internethere on StackOverflow都会详细介绍如何使用正确的AddTicket: function () { axios.post('/api/Tickets', ...) .then(function(response){ this.tickets = response }.bind(this)) // NOTE the ".bind(this)" added to the end of the function here }

最后,以下是修订过的问题中的代码,以便正确使用vm

this

答案 1 :(得分:4)

最后,很简单。在您不完全了解其工作原理之前,请遵循以下简单规则:

在Vue对象中的任何地方使用this,并在外部使用其引用标识符:

var vm = new Vue({
  // Use "this" inside
  el: '#app',
  data: {
    something: true
  },
  created: function () {
    this.something = false // like here
  }
})

// Here, outside, use reference iditentifier,
// as you have no other choice
vm.something = null

永远不要在引用的对象本身内使用引用名称。在Vue对象之外,您别无选择,只需使用引用名称。

在Vue内部,this内容可能会有所不同。还会。它只是在每个函数/对象中自动创建的另一个对象。因此,您需要第二条规则:在深入了解嵌套的二级函数之前,将this保存到引用/变量。原因:

var vm = new Vue({
  el: '#app',
  data: {
    something: true
  },
  created: function () {
    // You are in first level function,
    // you can use "this"
    axios.get('/uri').then(function () {
      // Here you are in nested, second level
      // function. It will have own "this" object
      this.something = false // no error here but...
      // You did not changed "something" value in data object,
      // you just created new property also called "something",
      // but in this nested "this" object.
    })
  }
})

如上所述,每个函数都获得它自己的this对象。因此,使用' this.something = false'你刚刚创造了新的物业'在'这个'嵌套的二级函数中的对象,而不是改变这个'在第一级功能。换句话说,在嵌套函数中,您从第一级函数中丢失了对先前this的引用,因为它的内容在嵌套函数创建过程中被新创建的内容覆盖。因此,如果您需要在嵌套函数中使用this对象形式的第一级函数,只需将其保存在另一个名称中,该名称不会被覆盖:

var vm = new Vue({
  el: '#app',
  data: {
    something: true
  },
  created: function () {
    var anyName = this // Save reference to this under another name
    axios.get('/uri').then(function () {
      this.something = false // no error here, but you are still creating new property
      anyName.something = false // NOW you are really changing "something" value in data
    })
  }
})

如您所见,您可以使用任何名称保存它。但请按照便利性将其命名为self。不是vm,因为此名称可能会再次让您感到困惑,是否会与var vm = new Vue()发生冲突。它不会,但不会让自己感到困惑,只需将其命名为self

不试用箭头功能,不要使用bind。只需按照这个简单的规则。稍后,您将更有经验,您可以(并且应该)使用它们,但是现在,享受编码,而不是调试:)