Achieving Bi-Directional Data Binding with Vue.js using the vue-property-decorator Library

Currently, I am working with Vue.js and TypeScript while also utilizing the vue-property-decorator. My goal is to establish two-way data binding between a parent and child component. Below is an example of what I have in mind:

Parent Component

<template>
  <progress :is-loaded.sync="isLoaded"/>
</template>

@Component
export default class ParentComponent extends Vue {
  get isLoaded() { return Store.getters["isLoaded"]; }
  set isLoaded(value: boolean) { Store.commit("isLoaded", value); }
}

Child Component

<template>
 <progress :value="_value" min="0" max="100"></progress>
 {{_isLoaded}}
</template>

@Component
export default class ChildComponent extends Vue {
  @Prop()
  public isLoaded: boolean;

  public _isLoaded: boolean;
  public _value: number;

  public mounted() {
    this._isLoaded = this.isLoaded;
    this._value = this.value;
  }

  @Watch("isLoaded")
  public onIsLoadedChanged() {
    if (!isLoaded) {
      // Animate _value from 0 to 100.
      this._isLoaded = true;
      this.$emit("update:isLoaded", this._isLoaded);
    }
  }
}

Is there a more concise way to achieve the desired result without having to use both isLoaded and _isLoaded, along with this.$emit using a magic string like update:isLoaded? It all feels quite verbose – perhaps there's a simpler approach or some encapsulation that can be implemented?

Answer №1

When does the value of isLoaded change within your application? If it only changes in the parent component, you can simply use the prop without the need for emitting events or using the @Watch decorator and the _isLoaded variable. If the change in isLoaded happens in the child component, there is no requirement for the prop and the redundant variable. Instead, you can emit a loaded event and listen for it in the parent component.

This scenario illustrates how the style of the child component changes based on the parent's isLoaded state.

Parent Component:

<template>
  <progress :is-loaded="isLoaded"/>
</template>

@Component
export default class ParentComponent extends Vue {
  public isLoaded: boolean = false
  created(){
    setInterval(()=>this.updateStatus(), 500)
  }
  this.updateStatus(){
    this.isLoaded = true
  }
}

Child Component:

<template>
 <div :class="{ full: isLoaded }">Loaded is {{ isLoaded }}</div>
</template>

@Component
export default class ChildComponent extends Vue {
  @Prop()
  isLoaded: boolean;
}

<css>
   .full {width:100%}
</css>

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

Auth0 encountering issues retrieving ID token and user metadata

Currently in the process of integrating Auth0 into a Vue.js/Node.js application, I have successfully enabled user registration and login functionality (to /callback). Although the manual addition of data to the user metadata section is functional at this s ...

The function within the Context Hook has not been invoked

My attempt to implement a signin method using the context hook is not working as expected inside the AuthContext file. When calling the signin method from the Home Page, neither the console.log nor the setUser functions are being executed inside the AuthC ...

click event on ion card

Attempting to handle a click event within an ion-card using Ionic 5.0.2 version has presented some challenges. Despite my efforts, I have not been successful in handling the event with the expected function. Here is a snippet of my code: Dynamic card list ...

Images not showing in Vue.js

I have been working on setting up a carousel using bootstrap-vue. It is being generated dynamically through an array containing three objects with keys such as id, caption, text, and image path. The issue I am facing now is that while the caption and text ...

Executing a Root Hook Plugin Prior to Running All Mocha and Playwright Tests

I've recently incorporated automated tests into my Vue.js project by installing this useful plugin. The Vue.js application was initially set up using vue-cli. Everything is running smoothly, and I must say Playwright is proving to be a remarkably ro ...

Is there something lacking in my project.json while building with nuxtjs?

Issue detected in ./services/emailService.js Unable to locate module: Error: Unable to find '@/apis/adl/instance/EmailsApi' in I encountered this error while executing the nuxt build within a docker container or on certain CI/CD servers such a ...

Assigning default value to radio button based on the state

I am encountering an issue with my vuejs application where the default value of a setting called defaultView is not being properly retrieved from the vuex state during login. The defaultView setting can be either 1 or 2 based on the user's selection, ...

Combining Bootstrap Vue: utilizing class names alongside HTML tags

(Bootstrap-Vue 2.0, Vue.js 2.5) Is it possible to combine traditional CSS Bootstrap 4 classes with Bootstrap-Vue? For example, can I use the following code snippet: <section id="introduction"> <b-container class="h-100"> & ...

Encountering build issues in my next.js application post updating to version 12.#.# and implementing Typescript

In my next.js application, I recently upgraded to version 10 and added TypeScript to the mix. Despite ironing out all issues during development, I encountered errors when running yarn next build due to my use of the keyword interface. ./src/components/ ...

Mastering the art of passing props in VueJS

My setup in the App is quite straightforward, with two main components: The HelloWorld component and a dialog component. The dialog component receives props from the HelloWorld component. The data in the HelloWorld component is rendered by looping over an ...

When instance data is altered during an ajax submission, the input data is reset

Within my Vue instance, I have implemented the following method: ajaxSubmit: function(event) { this.loader = true; var form = event.target; var action = form.getAttribute('action'); var data = new FormData(f ...

Angular Material Datatables - Issue with Paginating Data from Firestore

Data has been retrieved from Firestore and transformed into an Observable array with the InvoiceItem type. The data loads correctly onto the datatable, but there seems to be an issue initializing the paginator with the array's length. This could poss ...

Do I need to add /public directory to the gitignore file when working with Vue.js

In my Laravel/Vue.js project, I noticed that whenever I make a commit, three additional files are also included: - public/main.js - public/manifest.js - public/vendor.js As a result, I am wondering whether or not I should include the /public folder in the ...

Transferring properties from the main layout to a specific component

Recently delving into the world of Vue, I find myself in need of passing props from a layout to a global component. Although my search skills may not be up to par, I have been tinkering with a default layout setup as follows: layouts/default.vue <templ ...

Incorporating dynamic form elements using Vue.js within a targeted div

Here is the HTML and Vue.js code that I have: <table class="table"> <thead> <tr> <td><strong>Title</strong></td> <td><strong>Description< ...

Tips for binding to a single input box within an ngFor loop

Can anyone lend a hand with some code? I'm working on a straightforward table using ngFor, but I'm facing an issue with input binding. The problem is that all the input fields generated by ngFor display the same value when typing. How can I preve ...

RxJS: Transforming an Observable array prior to subscribing

I am retrieving data (students through getStudents()) from an API that returns an Observable. Within this result, I need to obtain data from two different tables and merge the information. Below are my simplified interfaces: export interface student Stude ...

Using Angular 5 to access a variable within a component while iterating through a loop

I am currently in the process of transferring code from an AngularJS component to an Angular 5 component. Within my code, I have stored an array of objects in a variable called productlist. In my previous controller, I initialized another empty array nam ...

Creating a custom pipe that converts seconds to hours and minutes retrieved from an API can be achieved by implementing a transformation function

Can someone please provide guidance on creating a custom pipe in Angular 8 that converts seconds to hours and minutes? Thank you. <div class="col-2" *ngFor="let movie of moviesList"> <div class="movie"> {{ movie.attributes.title }} ...

Acquiring the download link for Firebase Storage in Angular 2+ technology

reference: AngularFireStorageReference; task: AngularFireUploadTask; uploadState: Observable<string>; uploadProgress: Observable<number>; downloadLink: Observable<string>; beginUpload(event) { const id = Math.floor(Math.random() * 1000 ...