Why is v-model not used?

Hi, I’m just curious about it.

@nolimits4web said v-model is too buggy. But as what is mentioned in Vue guide, v-model is just syntax sugar of :value and @input. So, why and how buggy is it? Any jsfiddle examples?

1 Like

It is buggy on custom components. Try to create component that can be any input type and try to implement working v-model on it :wink:

1 Like

HI @nolimits4web,

From this https://jsfiddle.net/qdechochen/prz2xb0L/63/, I see the problem. v-model on f7-input will get a value { “isTrusted”: true }. But why my component ‘my-input’ works fine with v-model and f7-input not?

In many other frameworks(eg. element-ui), v-model works very well.

I just found something, which I think is the cause.

In Vue’s guide (see https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components), it says:

When used on a component, v-model instead does this:

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>

When we use v-model on a component, v-model will get $event, rather than $event.target.value.

So in a custom component, should $emit(‘input’, $event.target.value), not $emit(‘input, $event’).

Then I read your F7 Vue doc about Input Events, and the code of f7-input, the arguments of f7-input events are all “event”, not value.

I then understand that maybe it’s you who made the choice of whether to emit event or value.

I really suggest getting v-model back. Maybe for input/change event should emit $event.target.value, and another input:native/change:native should emit $event? Actually I don’t know why we need $event rather than just value.

I also understand that even my option is correct and good (or maybe it’s a bad idea though), it’s nearly impossible to change because many versions has been released. (Maybe a global switch for it?)

2 Likes

When one component can render input, select, textarea, radio, checkbox etc

Hi @nolimits4web,

yes, I understand how to recreate the “bug”, but actually it’s not a bug of Vue, it is how Vue designs. Please have a look at my last post, and especially the link I posted in it ( https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components). In f7-input, the ‘input’ event should be emitted as $emit(‘input’, $event.target.value) not $emit(‘input’, $event).

Once again, yes, but in case of same component can render different types of inputs, then it should emit same for change event too, which won’t just bring more problems if you need to get native event object with event.target. So instead of making it hack, just use it as :value + @input combination instead of v-model.

1 Like

As a matter of fact, I would suggest a more radical approach: ditch <f7-input all together.

When we need to apply a mask or any directive/custom component that are , we must not use vue and them emulate what F7 vanilla does.

Perhaps, if the input component were sloted, we could have a <f7-input that does all the magic, but still be able to render custom components, directives and use v-model (since the final html is ours to control).

This makes sense?

@Echo_Chen: It would be alot helpful if you could fork, check if your theory works, then do a pull-request. I would be the first to welcome v-model =)

Just change framework7-vue.js, (or other file you use), and change the following code for f7-input:

onInput: function onInput(event) {
    // this.$emit('input', event);
    this.$emit('input', event.target.value);
},

This may cause problems on other f7 components. (I didn’t do any test)

1 Like

@nolimits4web For me (or for a vue user?), I don’t care about “native” target, value is the only thing I need. If someone needs it, input:native/change:native maybe the option.

Anyway, this is just my personal superficial opinion. Thanks for your explanation and awesome F7.

I am a vue user too. First time I also was needed only the value. But afterwards I realised that current solution is appropriate to me. I use some transformation before emitting. For example: event.target.value.trim(), parseInt(event.target.value), event.target.checked for f7-checkbox or more complex:

updateValue($Event) {
 let selectedOptions = $Event.target.selectedOptions;
 let newValue = [];
 for (let Index in selectedOptions) {
   if (selectedOptions.hasOwnProperty(Index)) {
      newValue.push(selectedOptions[Index]['_value'])
   }
 }
 this.$emit('input', newValue);
}

Please leave it as it is.

3 Likes

Hi @almazk,

Modifiers (trim, number) can be used together with v-model https://vuejs.org/v2/guide/forms.html#number. And v-model for a checkbox should emit a boolean value or the value of true-value or false-value. https://vuejs.org/v2/guide/forms.html#Checkbox-1. or for a group of checkboxes, v-model should return an array.