#title Weekly Vue News #91 - Declare and Mutate v-model Props as Normal Variable Using defineModel #preview Ready for your weekly Vue & Nuxt dose?
Declare and Mutate v-model Props as Normal Variable Using defineModel
Hi π
Last week I focused on enhancing the code coverage of E2E tests for
In this week's issue, I provide a valuable tip for improving your development workflow. We'll explore how to declare and mutate v-model props as normal variables using defineModel
.
But that's not all! I've curated a collection of exceptional content related to Vue.js, Nuxt.js and web development in general.
So, get ready to level up your Vue.js and Nuxt.js skills and stay at the forefront of web development. Let's embark on this exciting journey together!
Have a lovely week βοΈ
To support me:
- π Recommend the newsletter to your friends: it really helps!
- πΈ Sponsor the newsletter
- π§΅ Retweet the latest Twitter thread
- π¨ Reply to this email: feedback is welcome
This experimental feature will be
defineModel
is a compiler macro that allows you to declare and mutate v-model
props as the same as a normal variable.
Example without defineModel
Let's take a look at a simple example that uses v-model
. We have a Parent.vue
component that passes a counter ref to a Child.vue
component:
1 <script setup lang="ts">
2 import { ref } from 'vue'
3 import Child from './components/Child.vue'
4
5 const state = ref({ count: 0 })
6 </script>
7
8 <template>
9 <div>
10 <span>Parent state: {{ state }}</span>
11 <Child v-model="state.count" />
12 </div>
13 </template>
Let's take a look at the implementation of the child component:
1 <script setup lang="ts">
2 import { ref } from 'vue'
3
4 const props = defineProps<{ modelValue: number }>()
5
6 const emit = defineEmits<{
7 (e: 'update:modelValue', value: number): void
8 }>()
9
10 const onClick = () => {
11 props.modelValue += 1
12 emit('update:modelValue', props.modelValue)
13 }
14 </script>
15
16 <template>
17 <div>
18 <span>Child state: {{ modelValue }}</span>
19 <button @click="onClick">Increment child state</button>
20 </div>
21 </template>
As Child.vue
receives the v-model
you need to declare a prop called modelValue
which receives the v-model
value. Additionally, you need to declare an emit called update:modelValue
that is used to update the parent that the modelValue
has been updated.
As props are readonly and you should not mutate them, you cannot update modelValue
and will receive the following warning:
Set operation on key "modelValue" failed: target is readonly.
I defineModel
provides a nice solution to this problem, so let's take a look at it.
Example with defineModel
In the following example, I'm using defineModel
available since Vue 3.3.0-alpha.9
We can simplify our child component by using defineModels
:
1 <script setup lang="ts">
2 const { modelValue, count } = defineModels<{
3 modelValue: number
4 }>()
5
6 const onClick = () => {
7 modelValue.value += 1
8 }
9 </script>
10
11 <template>
12 <div class="container">
13 <span>Child with defineModels state: {{ modelValue }}</span>
14 <button @click="onClick">Increment child state</button>
15 </div>
16 </template>
The defineModels
compiler macro will declare a prop with the same name and a corresponding update:propName
event when it is compiled.
By updating the modelValue
ref, the corresponding update:propName
event is automatically emitted.
Try it yourself in the following StackBlitz project:
ππ» The official certification of competence for the Vue.js Framework is now available.
certification.vuejs.orgππ» An amazing All-In-One SEO layer for Nuxt 3 by @harlan_zw |
ππ» Supports robots.txt, HTTP header, meta tags, sitemap.xml, Schema.org and much more |
When refreshing async data, when should you use refresh vs watch source? |
ππ» Use refresh() when you know server side data has changed |
ππ» Use a watch source when the data loaded is dependent upon client side data |
ππ» Nuxt 3 gives us two great options for managing all of our assets in our web app. |
ππ» But whatβs the difference, and how do you know which to use? |
ππ» A minor release of the popular frontend toolchain, but one that focuses on performance.
vitejs.devππ» Verifiably link npm packages to their source repository and build instructions. |
ππ» Developers building npm projects on GitHub Actions can now publish provenance alongside their packages. |
ππ» This post explains how passwordless can be implemented using modern technologies such as WebAuthn |
ππ» Passwordless provides a better user experience and security than the traditional password-based approach. |
ππ» This is a very handy list of places for you to code online without having to install anything on your machine.
jvns.caππ» Chrome 113 will allow you to override network response headers, including CORS headers. |
ππ» It also offers Nuxt, Vite, and Rollup debugging improvements. |
Until next week,
Holzapfelkreuther Str. 19, 81375 Munich, Germany