VueJS vee-validate issue when passed validation as props to input component - vue.js

I'm building an input component to work with vee-validate.
for more convenience, I want to use validation rules as a props for this.
Every thing is ok when I use v-model directive on parent. but, with value property; after writing in the field and validating, input value reset to it's parent.
This is logical? if not, how can I solve this problem without v-model?
Note that:
1) - Validations events are 'input' and 'blur'
2) - I never want to set v-on:input event on parent
See This Fiddle

This is logical.
#input="$emit('input', $event.target.value)" is useless here because you don't listen to the input event.
When your input is invalid, component is re-render again. value of input component has never change changed when you input. When it re-render, it will display correct value which is passed from parent.
https://jsfiddle.net/787g7q0e/

Related

Vue: Event does not emit several values. Is there something wrong with v-model?

I'm Vue beginner and have tried setting up a simple app that takes in some user input to display a result on an extra page / component.
Component A has 2 sliders. I'd like to pass both values to Component C. Currently only one value is passed.
I spent hours on this and have already received super valuable support on another question by #RoboKozo, but this keeps me from progressing any further.
Please find my current code here.
Bind both props, and emits
<component
:is="selectedComponent"
:modelValue="value"
:modelValue2="value2"
#update:modelValue="value = $event"
#update2:modelValue2="value2 = $event"
>
</component>
The event name for updating the model value of modelValue2 should be update:modelValue2 (not update2:modelValue2):
// ComponentC.vue
this.$emit('update:modelValue2', this.local2)
Then to bind component.modelValue2 to App.value2, specify modelValue2 as the v-model binding argument:
<component v-model="value" v-model:modelValue2="value2">
Note you don't need to specify the binding argument for modelValue because that's the default.
demo

Why some Vue custom component can do `<Radio v-model="today" value="monday" />`?

I was confused by this boostrap-vue's <Radio /> component:
It can do this
<b-form-radio v-model="selected" value="A">Option A</b-form-radio>
Why is this happening?
v-model is using value prop already, why can it still specify value prop?
Radio buttons differs a little bit from some other input elements such as text. Radio button values are static (not changing after set) while values on some other field types such as text are dynamic (able to change.
So without a value on a radio button the v-model would not know what data to set.
Read more on: https://v2.vuejs.org/v2/guide/forms.html#Value-Bindings

Using inner component in a loop in Shopware 6 does not persist the values uniquely for each looped component

I am using a v-for over a custom component and passing the item as a prop. But the issue is that each component instance in the loop takes the same item prop. For e.g in the 1st loop a component field has text "abc", then the second looped component also will have the same "abc" text. If I change the text in the 2nd one, it changes in the 1st component too. Is there a way to make the prop unique for each loop ?
For e.g this is the code which calls the inner component:
<template v-for="(businesscase, index) in businessCase.fields">
<custom-case-freetext-field #field-changed="updateFields"
:key="index"
#field-removed="removeFields"
:fields="businessCase.fields"
:index="index">
</custom-case-freetext-field>
</template>
and inside this component I have a basic form
<sw-field :label="$tc('rma.modules.case.freetext.nameLabel')"
:placeholder="$tc('rma.modules.case.freetext.nameLabel')"
required
v-model="fields[index].name">
</sw-field>
<sw-single-select
labelValue="label"
valueProperty="label"
:options="fieldTypes"
:label="$tc('rma.modules.case.freetext.fieldType')"
:placeholder="$tc('rma.modules.case.freetext.fieldType')"
v-model="fields[index].type"
#input="changeType"
required>
</sw-single-select>
If I do :value instead of v-model, the entered value disappears as soon as the element loses focus.
If I use v-model, the data stays there, but then both (or as many are there in the loop) component instances, have data binding between them, so it defeats the purpose of having a loop for multiple components. As seen in the screenshot, I am typing in the 2nd component, but it changes the text for the first one too.
In the above example I am sending the whole array as prop, but I have also tried with individual field element instead of fields
Your are not using the businesscase variable inside your components. And since every component always works on the upper scope property, they will all change the same. Use the innerscope property. If you have problems with reactivity, because you try to mutate props directly work with events emitting the key and the changed value to the upperscope component.

Why input is broken when value is the same?

I want to have a controlled input, and set keep its value unchanged on any input. The problem is: it works only when I type in for the first time (i.e. it's set to 1). But then it stops working and you can type in any value. Why?
<input :value="message" #input="message = 1" />
Sandbox: https://codesandbox.io/s/unruffled-fire-in9yn?file=/index.html:162-209
If all you want to do is prevent the user from changing the <input> value, you can do that with simple HTML. You don't need Vue at all.
<input value="1" readonly>
I don't recommend doing this, but this would achieve your expected behavior:
<input v-model="message" #input="message = 1" />
This works because it is a "2-way binding" using v-model, which means changes to the input's value are propagated automatically, so a state change is triggered, because the new value of input is propagated (in the state) and then message = 1 get triggered afterwards and triggers a state change which updates the input element.
The original using :value=message is one-way, so changes in value to the input box are not automatically propagated to your component's state, and so Vue just sees a component with the same value bound to the message prop and does not update.

Vue.js - 2 way binding not working. Data is not updating when changed in a component

I have a 'Builder' component and I am passing a variable named 'formula' to that component, but the changes made in this variable in 'Builder' component do not get updated in current component.
<builder :formula="formula"
:columns="columns"
:result_type="result_type">
</builder>
When I submit form the value for the 'formula' variable is same.
try this
<builder :formula.sync="formula"
:columns="columns"
:result_type="result_type">
</builder>
As in VueJS 2 .sync - 2 way binding has been deprecated, you have to handle it differently. https://v2.vuejs.org/v2/guide/migration.html#once-and-sync-Modifiers-on-v-bind-removed
You have to emit events like this.$emit('formulaChange', formula) etc. and listen to them in parent component with #formulaChange=yourHandler(formula)