Home  >  Q&A  >  body text

Why is "this" defined as undefined in Vue 3 function

Please see the following simple component example in Vue 3:

<script>
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'Test',
  setup(){
    return{
      one,
      two
    }
  }
})

function one(){
  console.log(this) //<-- Proxy{}
  two()
}

function two(){
  console.log(this) //<-- undefined
}
</script>
  
<template>
  <a href="#" @click.prevent="one()">开始</a>
</template>

I'm trying to understand why when calling the two() function from the one() function, this happens in the two() function The middle is undefined. Both functions return in setup(), so I would expect both of them to have access to this.

Having said that, how do you get a reference to the component instance this in the two() function?

P粉057869348P粉057869348318 days ago704

reply all(1)I'll reply

  • P粉776412597

    P粉7764125972023-11-07 00:01:40

    I think Vue still needs to abide by the rules of JavaScript. When an event handler is called, it is usually in the context of the object receiving the event. In this case, one() is bound to the Proxy of the <a> element, and this is bound to Proxy.

    However, two() is called specifically without context (i.e.: two() instead of someobject.foo()). This means this will be undefined.

    I'm not very familiar with Vue, but I imagine it doesn't automatically bind methods so you don't have to pay for something you don't use.

    Since this in one() is properly bound, you can actually use two() as a method of this Called, rather than as a bare function:

    <script>
    import { defineComponent } from 'vue'
    
    export default defineComponent({
      name: 'Test',
      setup(){
        return{
          one,
          two
        }
      }
    })
    
    function one(){
      console.log(this) //<-- Proxy{}
      this.two()
    }
    
    function two(){
      console.log(this) //<-- Proxy{}
    }
    </script>
      
    <template>
      <a href="#" @click.prevent="one()">开始</a>
    </template>

    reply
    0
  • Cancelreply