In the docs for vue's v-model
modifiers, they give this example and there is a playground link as well.
<script setup>
const [model, modifiers] = defineModel({
set(value) {
if (modifiers.capitalize) {
return value.charAt(0).toUpperCase() + value.slice(1)
}
return value
}
})
</script>
<template>
<input type="text" v-model="model" />
</template>
This code can be edited so that the modifiers
variable is now foo
. What kind of pattern is this and how is this achievable (with pseudocode) since the value of const [model, foo] = ...
is in a different scope than foo.capitalize
?
<script setup>
const [model, foo] = defineModel({
// ^^^
set(value) {
if (foo.capitalize) {
// ^^^
return value.charAt(0).toUpperCase() + value.slice(1)
}
return value
}
})
</script>
<template>
<input type="text" v-model="model" />
</template>
As stated in comments, the fact that you can change the variable name and achieve the same results, is expected: there is nothing special to the name model
-- it is just a name.
What can be confusing is that the set
method reads from a variable that is only defined and assigned a value in the same expression that set
method occurs in.
But realise that this set
method is not yet called when defineModel
is called. The foo
(or model
) variable will be initialised by this overall expression, but the set
method is not called by this expression. This whole expression has already been evaluated and assigned to foo
before the set
method is ever called.
NB: It would have been a problem if the defineModel
function would itself call the set
method of the given object. If that were the case, foo
would be undefined, and an error would be triggered when evaluating foo.capitalize
.
As to the parsing of this code: the foo
variable is declared, and its name is known for the set
function, and can be parsed without issue.
This principle is not specific for Vue. It is how things work in plain JavaScript.
Here is a simple JavaScript example, where foo
is assigned without destructuring (which was an irrelevant aspect), and set
is called explicitly with some format
function that is made available to foo
:
function create(obj) {
console.log("executing: create()");
return {
capitalize: true,
format(value) { return obj.set(value); }
};
}
const foo = create({
set(value) {
console.log("executing: set()");
if (foo.capitalize) value = value.toUpperCase();
return value;
}
});
console.log("foo was assigned");
// Only now `set` will be called
const value = foo.format("hello world");
console.log(value);
So, notice the order of the output that this snippet generates.