How to connect a form component object with a parent object in Vue3 using v-model and the Options API?

My inquiry is quite straightforward. I am exploring the official Vue documentation that delves into v-model arguments in relation to forms within a child component. Here is the code snippet I am referring to:

(App.Vue)
<script>
import UserName from './UserName.vue'

export default {
  components: { UserName },
  data() {
    return {
      firstLast: {
        first: 'John',
        last: 'Doe'
      }
    }
  }
}
</script>

<template>
  <h1>{{ firstLast.first }} {{ firstLast.last }}</h1>
  <UserName
    v-model:first-name="firstLast.first"
    v-model:last-name="firstLast.last"
  />
</template>
(UserName.vue)
<script>
export default {
  props: {
      firstName: String,
    lastName: String
    },
  emits: ['update:firstName', 'update:lastName']
}
</script>

<template>
  <input
    type="text"
    :value="firstName"
    @input="$emit('update:firstName', $event.target.value)"
  />
  <input
    type="text"
    :value="lastName"
    @input="$emit('update:lastName', $event.target.value)"
  />
</template>

The aforementioned files are functional! The name "John Doe" is displayed on screen, and any changes made in the inputs will reflect on the name value.

However, my concern lies in the fact that in UserName.vue, I am referencing individual variables, "first" and "last", whereas I would prefer to reference an object containing both properties together.

How can I accomplish this task?

Answer №1

When the modelValue is changed to an object, it is necessary for the inputs to emit an updated object.

App.vue

<template>
  <h1>{{ firstLast.first }} {{ firstLast.last }}</h1>
  <UserName v-model="firstLast" />
</template>

UserName.vue

<script>
export default {
  props: {
    modelValue: Object
  },
  emits: ['update:modelValue']
}
</script>

<template>
  <input
    type="text"
    :value="modelValue.first"
    @input="$emit('update:modelValue', { ...modelValue, first: $event.target.value })"
  />
  <input
    type="text"
    :value="modelValue.last"
    @input="$emit('update:modelValue', { ...modelValue, last: $event.target.value })"
  />
</template>

If you want a more straightforward approach, consider using the newer Composition API and <script setup>, which grants access to the defineModel macro

Using Composition API

UserName.vue

<script setup>
const firstLast = defineModel()
</script>

<template>
  <input
    type="text"
    v-model="firstLast.first"
  />
  <input
    type="text"
    v-model="firstLast.last"
  />
</template>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Uncover the mystery behind the return value of a generic function in TypeScript

I can't seem to wrap my head around why TypeScript is behaving in the way described below. Snippet 01| const dictionary: { [key: string]: unknown} = {} 02| 03| function set<T>(key: string, value: T): void { 04| dictionary[key] = value; 05| } ...

The presence of a constructor in a component disrupts the connection between React and Redux in

I am facing an issue with the connect function from 'react-redux' in my Typescript class example. The error occurs at the last line and I'm struggling to understand why it's happening. The constructor is necessary for other parts of the ...

Safari experiences occasional failures with pre-signed post uploads to S3 when using multipart/form-data for file uploads

Lately, I've encountered issues with pre-signed post uploads to S3 that seem to be unique to Mobile Safari browsers. Interestingly, the error has also shown up occasionally on Desktop Safari. Whenever this error occurs, it triggers a response from S3 ...

Troubleshooting an issue with a Typescript React component that is generating an error when using

I am in the process of implementing unit testing in a Typescript and React application. To start off, I have created a very basic component for simplicity's sake. import React from "react"; import ReactDOM from "react-dom"; type T ...

How can I globally expose my APIService.js class to Vue JS components without needing to import it in each individual component?

Most of my components rely on interactions with my apiservice.js class, which uses Axios to handle http requests based on the method called. I understand that this may not be the recommended approach, but in every component, I include the following code: ...

Running `ng serve` in Angular works perfectly fine, but for some reason `ng serve --

Recently diving into Angular, I am still getting the hang of things as a newcomer. Nodejs and Typescript are all set up and good to go. Navigating to my project directory in the command prompt, running 'ng serve' compiles the project successfully ...

Refreshing events in FullCalendar 5 using Vue.js's refetchEvents

I am currently integrating FullCalendar with Vue.js. My goal is to reload the events when the refreshCal() function is triggered, thereby rendering the calendar on the screen using refetchEvents. I have two main components: The Calendar: here is the code ...

The index type 'X' is not allowed for use in this scenario

I encountered an issue in my TypeScript code: error message: 'Type 'TransitionStyles' cannot be used as an index type.' I'm wondering if there's a way to modify my interface so that it can be used as an index type as well: ...

Can you suggest a simpler approach to implementing this function?

Greetings to all who are perusing this message. I have devised a technique for retrieving today's date along with the current time. If the deadline value in the database is null, it will fetch the current datetime and format it correctly. Otherwise, ...

Is it possible for me to activate a function on a different component using my header?

Hi there, I'm curious about how Vue routing and the tree structure work together. In my setup, I have a parent router that contains both my router-view and header at the same level. I want to be able to trigger some functions from my header component ...

Issue encountered: Trying to deploy firebase functions and hosting with vue-cli v3 and node.js leads to an error "No npm package found in functions source directory

My plan is to utilize Vue.js for the Frontend and Firebase Functions (Express.js) + Firestore for the Backend. Step 0: I initiated a new project on Google Firebase, then created a new Service Account with Owner's permissions to be used with Admin SDK ...

Vue warning: You are trying to access a property or method that is not defined on the instance but is being referenced during

The code snippet above was created to manage an event triggered by a button click var MainTable = Vue.extend({ template: "<ul>" + "<li v-for='(set,index) in settings'>" + "{{index}}) " + &qu ...

Disabling ion-select in Ionic 2 with Typescript

To disable an ion-select element in Angular, you can use the disabled attribute like this: <ion-item> <ion-label stacked>Property Type</ion-label> <ion-select [(ngModel)]="propType" (ionChange)="ionChanger()" di ...

Discovering the Secrets of Laravel 5: Harnessing the Power of Vue.js to Access Data Attribute Values

I'm a beginner in vue js. Within our app, we have implemented validation to check if a value already exists in the database. I would like to enhance this feature by making it dynamic. To achieve this, I have added a data attribute to my field which is ...

Exploring the power of Vue.js with the versatile v-for

I'm new to vue.js and I'm looking to retrieve data from app.js using v-for in HTML to display it in separate divs. I want each todo item to have its own background and text. var example = new Vue({ el:"#example", data: { todos ...

Querying subdocuments within an array using MongoDB's aggregation framework

Currently, I'm facing a challenge while developing a statistics dashboard for a meditation app. I'm struggling with creating a MongoDB query to fetch the most popular meditations based on user progress. The key collections involved are users and ...

Angular 7 router navigate encountering a matching issue

I created a router module with the following configuration: RouterModule.forRoot([ {path: 'general', component: MapComponent}, {path: 'general/:id', component: MapComponent}, {path: '', component: LoginComponent} ]) Sub ...

The Vue component that was added dynamically is failing to render

When I have a section of HTML with Vue components inside it, coming from a server, and then insert it on the page by clicking a button, the components are not rendering or showing up. Here is the HTML that gets inserted when the button is clicked: <sec ...

Getting js.map Files to Function Properly with UMD Modules

I am experiencing an issue with debugging TypeScript files in Chrome and Firefox. Specifically, when trying to debug the MapModuleTest.ts file, the debugger seems to be out of sync with the actual JavaScript code by two lines. This discrepancy makes settin ...

Managing multiple asynchronous requests through Observables in web development

I am working on an Angular2 website that sends multiple ajax requests using Json Web Tokens for authorization when it is initialized Here are two examples: public getUser(): Observable<User> { // Code block to get user data } public getFriends ...