How Vue's event
can change const
variable is possible?
The 'state' is the primitive const
variable. Of course, it is impossible to change the value.
error: state ++
However, there is no error when increasing the state through the inline event.
Why is that?
https://codepen.io/quietjun/pen/gOvEjvq?editors=1111
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>모두의 코딩</title>
</head>
<body>
<div id="app">
<span>{{state}}</span><br />
<button @click="state++">inline</button><br />
<button @click="increase">function</button><br />
</div>
</body>
</html>
<script src="https://unpkg.com/vue@3"></script>
<script>
const { createApp } = Vue;
createApp({
setup() {
const state = 1;
// of course below line is error
//state++;
const increase = () => {
state++;
};
return {
state,
increase,
};
},
}).mount("#app");
</script>
Of course state is not reactive. However, using the developer tool, you can see that the value has changed.
return {
state,
increase,
}
is short for
return {
state: state,
increase: increase
}
In other words, inside <template>
you don't interact with the const state
from <script>
.
You interact with the template context's properties. Think of it as an object created by merging everything that needs to be exposed to the <template>
(e.g: spread return of data
, all computed
, all methods
, spread return of setup
, all props
, etc...)
And you can safely write to an object's property, unless it has been defined as writeable: false
, which is clearly not the case.
Simple example:
const a = 1;
// a++; => Error: "Uncaught TypeError: Assignment to constant variable"
const b = {
a,
increment() {
this.a++ // 👈 similar to what you're doing in your handler
}
};
b.a++;
console.log(b.a); // 2! no error.
b.increment();
console.log(b.a); // 3! no error.
Additionally, @click="expression"
is wrapped in an anonymous function by Vue if expression
is not callable (akin to @click="() => { expression; }"
).
Side note: In your example, if you want state
to be reactive you have to declare it as const state = ref(1)
. Otherwise, even though state++
will change state
's value, it won't trigger a re-render, so it will look like it didn't update, until something else triggers a component re-render and the template value gets updated (overridden).