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

Ste*_*veO 18 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;

            }
        },

    })
Run Code Online (Sandbox Code Playgroud)

Ber*_*ert 31

我通常会将这个问题标记为重复,但是,我觉得这个具体的问题值得多一点解释,因为总体上存在整体混淆this,以及它应该如何在Vue中使用.

通常情况下,内部的方法,或在计算的Vue性质或生命周期的处理程序中,将使用this来指代该方法/运算/处理程序被安装的组件.this指的是函数当前正在执行的上下文.

使用axios.post时遇到的问题是在当前函数的上下文中声明新函数时,就像在对promise(axios.get,this)编写回调时发生的那样.考虑以下代码:

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              
      })
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,第一个注释可以替换为this.tickets用于获取数据属性或调用Vue(this)方法的代码.第二点意见,但是是内部的一个新功能上下文,function() {}将不参考的Vue公司.这是因为,在Javascript中,当您使用声明新的函数this语法,该功能有其自身的功能方面是不同的,从在声明它的功能.

有几种方法可以在Javascript中处理这个问题.这些天最常见的是要么使用闭包来捕获正确的() => {},要么使用箭头功能.考虑以下代码:

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

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

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

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
      })
}
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用bind方法创建具有特定功能的函数vm,尽管现在这种情况并不常见,但可以使用箭头函数.

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
}
Run Code Online (Sandbox Code Playgroud)

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

在任何情况下,如何使用正确的内容this都会在整个互联网上的许多帖子中详细介绍,此处也在StackOverflow上.

最后,这里是修改过的问题的代码,this 应该正确使用.

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

      this.showAdd = false;
    }
  },
})
Run Code Online (Sandbox Code Playgroud)


小智 6

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

this在Vue对象中随处使用,并在外部使用其引用标识符:

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
Run Code Online (Sandbox Code Playgroud)

切勿在引用对象本身内部使用引用名称。在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.
    })
  }
})
Run Code Online (Sandbox Code Playgroud)

如上所述,每个函数都获得自己的this对象。因此,使用“ this.something = false”,您只是在嵌套的第二级函数的“ this”对象中创建了新属性“ something”,而不是在第一级函数中更改了“ this”。换句话说,在嵌套函数中,您失去了对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
    })
  }
})
Run Code Online (Sandbox Code Playgroud)

如您所见,您可以将其保存为任何名称。但是,请遵循方便性并将其命名为self。不是vm,因为这个名字可以再次迷惑你,是否会与碰撞var vm = new Vue(),还是不行。不会,但不会混淆自己,仅将其命名为self

不尝试使用箭头功能,请勿使用绑定。只需遵循以下简单规则即可。以后,您将更有经验,可以(并且应该)使用它们,但是现在,享受编码,而不是调试:)