How to Emit values from child to an object in parent component in vuejs?

Viewed 1246

I am trying to use a child component with custom form inputs & emit those value to parent component. However, while I am trying to store the values in an object of parent component, One input value disapper when another input value is entered. Let me show some code:

Child Component

<template>
   <input
      type="text"
      @input="setField($event.target.value, 'title')"
   />
   <wysiwyg-input
      @change="(text) => setField(text, 'content')"
   />
</template>

<script>
export default {
methods: {
    setField(value, field) {
      this.$emit("input", {
        title: field === "title" && value,
        content: field === "content" && value,
      });
    },
  },
}
</script>

Parent Component

<template>
  <FormFields v-model="blogPost" />
</template>

<script>

export default {
  data() {
    return {
      blogPost: {},
    };
  },
  watch: {
    blogPost(val) {
      console.log(val);
    },
  },
};
</script>

Here, when I try to input the 'content', the 'title' field become false. So how can I set the condition on child component as I can emit both input to parent component ? Or Any other idea to accomplish the same task ?

CodeSandbox link: https://codesandbox.io/s/mystifying-benz-w8wgu?file=/src/App.vue

3 Answers

You can use ternary operator:

this.$emit("input", {
   title: field === "title" ? value : "",
   content: field === "content" ? value : "",
});

As per MDN docs

&& operator actually returns the value of one of the specified operands

expr1 && expr2

If expr1 can be converted to true, returns expr2; else, returns expr1

const a = 3;
const b = -2;

console.log(a > 0 && b > 0); // which returns false as expression `a > 0` true and b > 0 is `false` returned.

In your case

if filed = 'title', field === "title" && value will return value

if filed = 'somethingelse', field === "title" && value will return false.

As Serg mentioned, you can use ternary operator to fix your issue.

this.$emit("input", {
   title: field === "title" ? value : "",
   content: field === "content" ? value : "",
});

Awesome Question

Why don't we use this.value in child component? In your code, parent component passed v-model="blogPost" into child component, but in child component that is not used.

Try this

In Child component:

<template>
   <input
      type="text"
      @input="setField($event.target.value, 'title')"
   />
   <wysiwyg-input
      @change="(text) => setField(text, 'content')"
   />
</template>

<script>
export default {
props: {
  value: {
    type: Oject
  }
},
methods: {
    setField(value, field) {
      this.$emit("input", {
        title: field === "title" ? value : this.value.title,
        content: field === "content" ? value : this.value.content,
      });
    },
  },
}
</script>

Related