[Vuejs]-Parentheses while calling a method in Vue change the value of this

2👍

When v-on directive is provided with @sayHi="me.sayHi()" inline expression, it’s wrapped with a function and compiled to something like:

el.addEventListener('sayHi', $event => { vm.me.sayHi() })

When a value is a function value like @sayHi="me.sayHi", event handler is a function itself:

el.addEventListener('sayHi', vm.me.sayHi)

As explained in this question, this context is not parent object when its method is used as a callback, and this happens when it’s passed as event handler. A function should be explicitly bound to the desired context to receive it as this.

The difference with this question is that sayHi is not component method. Component methods in Vue options API are internally bound to component instance, this doesn’t apply to composition API.

sayHi should refer reactive value explicitly instead of using this:

const me = reactive({
  name: "foo",
  sayHi: () => {
    console.log("Hi I am : ", me.name);
  },
});

There’s no benefit from using sayHi function as a method of reactive object, it’s ignored by Vue reactivity API. Unless there are reasons for me to be an object, e.g. it’s passed to other components, a state and function could be separated:

const me = ref("foo")
const sayHi = () => {
    console.log("Hi I am : ", me.value);
};

1👍

Event call compiles differently

// <Comp :name="me.name" @sayHi="me.sayHi"/>
let fn = me.sayHi
fn($event) // `this` is undefined us you just calling a function

and

// <Comp :name="me.name" @sayHi="me.sayHi()"/>
// or
// <Comp :name="me.name" @sayHi="() => me.sayHi()"/>
let fn = () => me.sayHi()
fn($event) // `this` is `me` as you are calling an object method
👤Dimava

Leave a comment