I have a component called Input.vue, which basically prints label and and input of some type. It looks like this:
<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>
It's being called from another component like this:
<input-component inputId="formDiscountName"
inputType="text"
inputName="discountName"
:label="translations['name']"
:placeholder="translations['name']"
:data="discount.name"
/>
Now the problem is that if I enter any data in this input, discount.name doesn't get any value set, because inside input-component it's instantly assigned to inputData variable and data property doesn't get any update. Now I can't mutate data property itself because of the Vue warning.
What should I do? I tried to use computed properties but I am not sure what get and set functions should look like.
One thing I can think of is to use computed property and emit an update on set function:
get inputData() {
return this.data;
}
set inputData(value: string) {
this.$root.$emit('inputUpdate', {'inputName' : this.inputName, 'inputValue' : value});
}
But emit doesn't look very clean method. Is there anything better?