I have a component called Input.vue that displays a label and an input field of some type. Here is how it looks:
<template>
<div class="form-element">
<label :for="inputId" :class="['form-element-title', { 'js-focused': focused }]">{{ label }}</label>
<input :disabled="!canEdit" :type="inputType" :id="inputId" :name="inputName" v-model="inputData" :placeholder="placeholder" @focus="focused = true" @blur="focused = false">
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class Input extends Vue {
@Prop({ default: () => {} }) inputId!: string
@Prop({ default: () => {} }) inputType!: string
@Prop({ default: () => {} }) inputName!: string
@Prop({ default: () => {} }) label!: string
@Prop({ default: () => {} }) placeholder!: string
@Prop({ default: () => {} }) data!: string
@Prop({ default: () => true }) canEdit!: boolean
private inputData = this.data;
private focused = false
}
</script>
Another component calls it like this:
<input-component inputId="formDiscountName"
inputType="text"
inputName="discountName"
:label="translations['name']"
:placeholder="translations['name']"
:data="discount.name"
/>
The issue arises when entering data in the input field - discount.name does not update because it's instantly assigned to the inputData variable inside the input-component and the data property doesn't reflect the change. Since mutating the data property directly is not recommended due to Vue warnings, I explored using computed properties but unsure of the proper implementation.
One solution could be to use a computed property and emit an update within the set function:
get inputData() {
return this.data;
}
set inputData(value: string) {
this.$root.$emit('inputUpdate', {'inputName' : this.inputName, 'inputValue' : value});
}
However, emitting events may not be the most elegant solution. Are there any better alternatives?