Synchronizing data between parent and child components using two-way binding with emit in Vue 3 using TypeScript

Within my code, there is a child component:

<template>
  <label :class="className + ' ctrl'">
    <span><LocCtrl :page="pageName" :locKey="labelLoc" /></span>
    <input
      type="text"
      :placeholder="getLoc(placeHolderLoc)"
      :value="text"
    />
  </label>
</template>

<script lang="ts">
import { ref, defineComponent} from "vue";
import { useModelWrapper } from '../utils/modelWrapper';
import LocCtrl from "../components/LocCtrl.vue";
import Locale from "@/services/Locale";

export default defineComponent({
  name: "Claims3View",
  components: {
    LocCtrl
  },
  setup(props, {emit}) {
    
    const data = ref({
      textValue: ""
    });

    return {
      text: useModelWrapper(props, emit, "modelValue")
    };
  },
  methods: {
    getLoc(locKey: string): string {
      return Locale.getItem(this.pageName, locKey);
    }
  },
  props: {
    labelLoc: {
      type: String,
      required: true,
    },
    modelValue: {
      type: String,
      required: true,
    },
    placeHolderLoc: {
      type: String,
      required: true,
    },
    pageName: {
      type: String,
      required: true,
    },
    className: {
      type: String,
      required: true,
    },
  },
});
</script>

Additionally, there is a parent control in the code:

<template>
   <textBox
      labelLoc="Symptoms"
      className="w4"
      data="claim.petCondition"
      :modelValue="claim.petCondition.symptoms"
      placeHolderLoc="saDC"
      pageName="claims3View"
   />
  </div>
</template>

<script lang="ts">
import { ref, defineComponent, inject } from "vue";
import type { Claim } from "../types/types";
import TextBox from "../components/TextBox.vue";

export default defineComponent({
  name: "Claims3View",
  components: {
    TextBox,
  },
  setup() {
    const claim = inject("ClaimData") as Claim;

    return {
      claim,
    };
  },
});
</script>

The functionality of the code successfully populates the value from Claim into the input field of the control. However, it does not update the data in the opposite direction when the user enters text into the textbox. This needs to be addressed to enable validation methods and other functionalities. One of the difficulties stems from the usage of code from a resource that I am still trying to fully comprehend (https://developpaper.com/vue-3-with-the-development-of-data-events-are-more-and-more-outstanding/).

Another challenge is that many Vue3 examples are not in TypeScript and do not function correctly when the JavaScript code is directly copied.

Additionally, I neglected to include the helper class:

import { computed } from "vue";
export function useModelWrapper(
  props: { [x: string]: any },
  emit: (arg0: string, arg1: any) => void,
  name = "modelValue"
) {
  return computed({
    get: () => props[name],
    set: (value) => emit("update:${name}", value),
  });
}

Answer №1

Give this a shot?

<inputField
  labelLocation="Symptoms"
  classType="w4"
  dataValue="claim.petCondition"
  valueModel="claim.petCondition.symptoms"
  placeholderLocation="saDC"
  pageReference="claims3View" />

Answer №2

gengsong's answer was somewhat accurate.

To implement v-model on the child control, make sure to include it.

Additionally, the conversion of the helper function to TypeScript was not done correctly. The initial example was in JavaScript, so I needed to adjust it to TypeScript. Here is the updated code that works:

import { computed } from "vue";
export function useModelWrapper(
  props: { [x: string]: any },
  emit: (arg0: string, arg1: any) => void,
  name = "modelValue"
) {
  return computed({
    get: () => {
      return props[name];
    },
    set: (value: string) => {
      return emit("update:" + name, value)
    }
  });
}

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

Confidently set up a proxy that is recursively nested and strongly typed

I have a collection of objects where I store various content for a user interface. Here is an example: const copy = { header: { content: 'Page Header' }, main: { header: { content: 'Content Subheader' }, body ...

Tips for navigating to a specific row within a designated page using the Angular Material table

Utilizing angular material, I have set up a table with pagination for displaying data. When a user clicks on a row, they are redirected to another page. To return to the table page, they must click on a button. The issue arises when the user needs to retu ...

Two unnamed objects cannot be combined using the AsyncPipe

Currently, I am looking to implement an autocomplete feature using Angular Material in Angular 8. Below is a snippet of the code used in the TypeScript file: @Input() admins: User[]; userGroupOptions: Observable<User[]>; filterFormFG: FormGrou ...

Appending an item to an array in TypeScript

I'm feeling lost. I'm attempting to insert new objects into an array in TypeScript, but I encountered an error. My interface includes a function, and I'm puzzled. Can anyone offer guidance? interface Videos{ title: string; descriptio ...

Creating TypeScript models from a JSON response in React components

My Angular 2 application retrieves a JSON string, and I am looking to map its values to a model. According to my understanding, a TypeScript model file is used to assist in mapping an HTTP Get response to an object - in this case, a class named 'Custo ...

Is there a way to omit type arguments in TypeScript when they are not needed?

Here is a function I am currently working with: function progress<T>(data: JsonApiQueryData<T>): number { const { links, meta } = data.getMeta(); if (!links.next) { return 1; } const url = new URL(links.next); return parseInt(url ...

Problem with custom anchor component in React that needs to perform an action before being clicked

React Component (Custom Anchor) import React from 'react'; class Anchor extends React.Component { onClick = (event) => { // ----------------------------- // send Google Analytics request ...

Prevent special characters in input fields using Angular and TypeScript

I am currently working on an Angular project using Ant Design ng Zorro. I've encountered an issue with validation when trying to restrict special characters in an input field. Despite setting up the validation rules, it seems that the key press event ...

Tips for creating a carousel with Angular 9 to showcase numerous items

I've got this code snippet that I'm working on. I want to incorporate a Carousel feature using Angular 9 without relying on any external libraries. Currently, all the data items are appearing in a single row (they are exceeding the specified bor ...

What could be the reason for the 'tsc' command not functioning in the Git Bash terminal but working perfectly in the command prompt?

I recently installed TypeScript globally on my machine, but I am facing an issue while trying to use it in the git bash terminal. Whenever I run tsc -v, I encounter the following error: C:\Users\itupe\AppData\Roaming\npm/node: l ...

Encountering a surprise token < while processing JSON with ASP.NET MVC alongside Angular

I encountered an issue when attempting to return the Index page. The data is successfully sent from the client to the server, but upon trying to display the Index page, an error occurs. Could someone review my code and identify where the mistake lies? acc ...

cookies cannot be obtained from ExecutionContext

I've been trying to obtain a cookie while working with the nestjs and graphql technologies. However, I encountered an issue when it came to validating the cookies by implementing graphql on the module and creating a UseGuard. It was suggested that I ...

Creating a tsconfig.json file that aligns perfectly with your package.json and tsc command: a step-by-step

I've chosen to use TodoMvc Typescript-Angular as the starting point for my AngularJS project. Everything is working smoothly so far. Here's a breakdown of what I can do: To manage all dependencies, I simply run npm install or npm update based o ...

What sets apart v-model from :model-value?

I'm curious because I have trouble grasping the distinction between v-model and :model-value. According to the information in the documentation: v-model is used on a native element: <input v-model="searchText"/> However, when used on ...

Extending momentjs functionality with a custom method in Typescript

I am attempting to extend the momentjs prototype with a new function. In JavaScript, I achieved this with the following code: Object.getPrototypeOf(moment()).isWeekend = function() { return this.isoWeekday() >= 6; }; How can I accomplish this in T ...

having difficulties with angular subscribing to an observable

I am currently working on a service that retrieves a post from a JSON file containing an array of posts. I already have a service in place that uses HttpClient to return the contents of a JSON file. The main objective is to display the full content of the ...

Issue with MUI 5 Button component not receiving all necessary props

Currently, I am attempting to create a customized MUI5-based button in a separate component with the following code: import {Button, buttonClasses, ButtonProps, styled} from '@mui/material'; interface MxFlatButtonProps extends Omit<ButtonProp ...

retrieve data types from an array of object values

I am looking to extract types from an array of objects. const names = [ { name: 'Bob' }, { name: 'Jane' }, { name: 'John' }, { name: 'Mike' }, ] The desired result should resemble thi ...

What are the best ways to troubleshoot my Angular 2 project?

I've been searching for my TypeScript files in the console, but they're not showing up. I've tried everything to debug my Angular 2 project, but no luck. I can't move forward without debugging, can anyone lend a hand? ...

Locate and retrieve the item that appears most often in a given array

In order to determine the mode of an array consisting of integer numbers only, I must create a function named findMode. If the array is empty, the function should return 0. Otherwise, it should return the element that occurs most frequently in the array. I ...